pointer.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #pragma once
  2. #include <compare>
  3. #include <cstdint>
  4. #include <ostream>
  5. #include <string>
  6. #include <string_view>
  7. #include <variant>
  8. #include <vector>
  9. namespace std {
  10. template <typename T> std::strong_ordering operator<=>(T const & lhs, T const & rhs) {
  11. if (lhs < rhs) {
  12. return std::strong_ordering::less;
  13. }
  14. if (lhs > rhs) {
  15. return std::strong_ordering::greater;
  16. }
  17. return std::strong_ordering::equal;
  18. }
  19. }
  20. namespace jvalidate::detail {
  21. class Pointer {
  22. public:
  23. Pointer() = default;
  24. Pointer(std::vector<std::variant<std::string, size_t>> const & tokens) : tokens_(tokens) {}
  25. Pointer(std::string_view path) {
  26. for (size_t p = path.find('/'); p != std::string::npos;
  27. path.remove_prefix(p + 1), p = path.find('/')) {
  28. std::string token(path.substr(0, p));
  29. if (token.find_first_not_of("0123456789") == std::string::npos) {
  30. tokens_.emplace_back(std::stoull(token));
  31. } else {
  32. tokens_.emplace_back(token);
  33. }
  34. }
  35. }
  36. Pointer parent() const { return Pointer({tokens_.begin(), tokens_.end() - 1}); }
  37. Pointer & operator/=(Pointer const & relative) {
  38. tokens_.insert(tokens_.end(), relative.tokens_.begin(), relative.tokens_.end());
  39. return *this;
  40. }
  41. Pointer operator/(Pointer const & relative) const { return Pointer(*this) /= relative; }
  42. Pointer & operator/=(std::string_view key) {
  43. tokens_.emplace_back(std::string(key));
  44. return *this;
  45. }
  46. Pointer operator/(std::string_view key) const { return Pointer(*this) /= key; }
  47. Pointer & operator/=(size_t index) {
  48. tokens_.emplace_back(index);
  49. return *this;
  50. }
  51. Pointer operator/(size_t index) const { return Pointer(*this) /= index; }
  52. friend std::ostream & operator<<(std::ostream & os, Pointer const & self) {
  53. for (auto const & elem : self.tokens_) {
  54. std::visit([&os](auto const & v) { os << '/' << v; }, elem);
  55. }
  56. return os;
  57. }
  58. auto operator<=>(Pointer const &) const = default;
  59. private:
  60. std::vector<std::variant<std::string, size_t>> tokens_{};
  61. };
  62. }