pointer.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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. for (size_t p = path.find('/'); p != std::string::npos;
  16. path.remove_prefix(p + 1), p = path.find('/')) {
  17. std::string token(path.substr(0, p));
  18. if (token.find_first_not_of("0123456789") == std::string::npos) {
  19. tokens_.emplace_back(std::stoull(token));
  20. } else {
  21. tokens_.emplace_back(token);
  22. }
  23. }
  24. }
  25. Pointer parent() const { return Pointer({tokens_.begin(), tokens_.end() - 1}); }
  26. Pointer & operator/=(Pointer const & relative) {
  27. tokens_.insert(tokens_.end(), relative.tokens_.begin(), relative.tokens_.end());
  28. return *this;
  29. }
  30. Pointer operator/(Pointer const & relative) const { return Pointer(*this) /= relative; }
  31. Pointer & operator/=(std::string_view key) {
  32. tokens_.emplace_back(std::string(key));
  33. return *this;
  34. }
  35. Pointer operator/(std::string_view key) const { return Pointer(*this) /= key; }
  36. Pointer & operator/=(size_t index) {
  37. tokens_.emplace_back(index);
  38. return *this;
  39. }
  40. Pointer operator/(size_t index) const { return Pointer(*this) /= index; }
  41. friend std::ostream & operator<<(std::ostream & os, Pointer const & self) {
  42. for (auto const & elem : self.tokens_) {
  43. std::visit([&os](auto const & v) { os << '/' << v; }, elem);
  44. }
  45. return os;
  46. }
  47. auto operator<=>(Pointer const &) const = default;
  48. private:
  49. std::vector<std::variant<std::string, size_t>> tokens_{};
  50. };
  51. }