| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- #pragma once
- #include <compare>
- #include <cstdint>
- #include <ostream>
- #include <string>
- #include <string_view>
- #include <variant>
- #include <vector>
- namespace std {
- template <typename T> std::strong_ordering operator<=>(T const & lhs, T const & rhs) {
- if (lhs < rhs) {
- return std::strong_ordering::less;
- }
- if (lhs > rhs) {
- return std::strong_ordering::greater;
- }
- return std::strong_ordering::equal;
- }
- }
- namespace jvalidate::detail {
- class Pointer {
- public:
- Pointer() = default;
- Pointer(std::vector<std::variant<std::string, size_t>> const & tokens) : tokens_(tokens) {}
- Pointer(std::string_view path) {
- for (size_t p = path.find('/'); p != std::string::npos;
- path.remove_prefix(p + 1), p = path.find('/')) {
- std::string token(path.substr(0, p));
- if (token.find_first_not_of("0123456789") == std::string::npos) {
- tokens_.emplace_back(std::stoull(token));
- } else {
- tokens_.emplace_back(token);
- }
- }
- }
- Pointer parent() const { return Pointer({tokens_.begin(), tokens_.end() - 1}); }
- Pointer & operator/=(Pointer const & relative) {
- tokens_.insert(tokens_.end(), relative.tokens_.begin(), relative.tokens_.end());
- return *this;
- }
- Pointer operator/(Pointer const & relative) const { return Pointer(*this) /= relative; }
- Pointer & operator/=(std::string_view key) {
- tokens_.emplace_back(std::string(key));
- return *this;
- }
- Pointer operator/(std::string_view key) const { return Pointer(*this) /= key; }
- Pointer & operator/=(size_t index) {
- tokens_.emplace_back(index);
- return *this;
- }
- Pointer operator/(size_t index) const { return Pointer(*this) /= index; }
- friend std::ostream & operator<<(std::ostream & os, Pointer const & self) {
- for (auto const & elem : self.tokens_) {
- std::visit([&os](auto const & v) { os << '/' << v; }, elem);
- }
- return os;
- }
- auto operator<=>(Pointer const &) const = default;
- private:
- std::vector<std::variant<std::string, size_t>> tokens_{};
- };
- }
|