pointer.h 1.8 KB

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