simple_adapter.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #pragma once
  2. #include <unordered_map>
  3. #include <vector>
  4. #include <jvalidate/adapter.h>
  5. #include <jvalidate/detail/array_iterator.h>
  6. #include <jvalidate/detail/object_iterator.h>
  7. #include <jvalidate/forward.h>
  8. namespace jvalidate::adapter::detail {
  9. template <typename JSON, typename Adapter = AdapterFor<JSON>> class SimpleObjectAdapter {
  10. public:
  11. using underlying_iterator_t = decltype(std::declval<JSON>().begin());
  12. using const_iterator = JsonObjectIterator<underlying_iterator_t, Adapter>;
  13. SimpleObjectAdapter(JSON * value) : value_(value) {}
  14. size_t size() const { return value_ ? value_->size() : 0; }
  15. const_iterator find(std::string const & key) const {
  16. return std::find_if(begin(), end(), [key](auto const & kv) { return kv.first == key; });
  17. }
  18. bool contains(std::string const & key) const { return find(key) != end(); }
  19. Adapter operator[](std::string const & key) const {
  20. auto it = find(key);
  21. return it != end() ? it->second : Adapter();
  22. }
  23. const_iterator begin() const {
  24. return value_ ? const_iterator(value_->begin()) : const_iterator();
  25. }
  26. const_iterator end() const { return value_ ? const_iterator(value_->end()) : const_iterator(); }
  27. std::map<std::string_view, Adapter> operator*() const {
  28. using C = std::map<std::string_view, Adapter>;
  29. return value_ ? C(begin(), end()) : C();
  30. }
  31. protected:
  32. JSON * value() const { return value_; }
  33. JSON const & const_value() const { return value_ ? *value_ : AdapterTraits<JSON>::const_empty(); }
  34. private:
  35. JSON * value_;
  36. };
  37. template <typename JSON, typename Adapter = AdapterFor<JSON>> class SimpleArrayAdapter {
  38. public:
  39. using underlying_iterator_t = decltype(std::declval<JSON>().begin());
  40. using const_iterator = JsonArrayIterator<underlying_iterator_t, Adapter>;
  41. SimpleArrayAdapter(JSON * value) : value_(value) {}
  42. size_t size() const { return value_ ? value_->size() : 0; }
  43. Adapter operator[](size_t index) const {
  44. if (index > size()) {
  45. return Adapter();
  46. }
  47. auto it = begin();
  48. std::advance(it, index);
  49. return *it;
  50. }
  51. const_iterator begin() const {
  52. return value_ ? const_iterator(value_->begin()) : const_iterator();
  53. }
  54. const_iterator end() const { return value_ ? const_iterator(value_->end()) : const_iterator(); }
  55. std::vector<Adapter> operator*() const {
  56. using C = std::vector<Adapter>;
  57. return value_ ? C(begin(), end()) : C();
  58. }
  59. protected:
  60. JSON * value() const { return value_; }
  61. JSON const & const_value() const { return value_ ? *value_ : AdapterTraits<JSON>::const_empty(); }
  62. private:
  63. JSON * value_;
  64. };
  65. template <typename JSON, typename CRTP = AdapterFor<JSON>> class SimpleAdapter : public Adapter {
  66. public:
  67. using value_type = std::remove_const_t<JSON>;
  68. public:
  69. SimpleAdapter(JSON * value) : value_(value) {}
  70. SimpleAdapter(JSON & value) : value_(&value) {}
  71. size_t array_size() const { return self().as_array().size(); }
  72. CRTP operator[](size_t index) const { return self().as_array()[index]; }
  73. detail::SimpleArrayAdapter<JSON> as_array() const { return value_; }
  74. bool apply_array(AdapterCallback const & cb) const final {
  75. bool result = true;
  76. for (auto const & child : self().as_array()) {
  77. result = cb(child) && result;
  78. }
  79. return result;
  80. }
  81. size_t object_size() const { return self().as_object().size(); }
  82. bool contains(std::string const & key) const { return self().as_object().contains(key); }
  83. CRTP operator[](std::string const & key) const { return self().as_object()[key]; }
  84. detail::SimpleObjectAdapter<JSON, CRTP> as_object() const { return value_; }
  85. bool apply_object(ObjectAdapterCallback const & cb) const final {
  86. bool result = true;
  87. for (auto const & [key, child] : self().as_object()) {
  88. result = cb(key, child) && result;
  89. }
  90. return result;
  91. }
  92. std::unique_ptr<Const const> freeze() const final {
  93. return std::make_unique<GenericConst<value_type>>(const_value());
  94. }
  95. protected:
  96. JSON * value() const { return value_; }
  97. JSON const & const_value() const { return value_ ? *value_ : AdapterTraits<JSON>::const_empty(); }
  98. private:
  99. CRTP const & self() const { return static_cast<CRTP const &>(*this); }
  100. private:
  101. JSON * value_;
  102. };
  103. }