3 #include "fly/concepts/concepts.hpp"
4 #include "fly/types/json/concepts.hpp"
5 #include "fly/types/json/json_exception.hpp"
6 #include "fly/types/string/string.hpp"
11 #include <type_traits>
18 namespace fly::detail {
20 template <
typename JsonIterator>
21 class JsonReverseIterator;
56 template <fly::SameAs<Json> JsonType>
59 static constexpr
bool is_const_iterator = std::is_const_v<JsonType>;
64 using object_iterator_type = std::conditional_t<
66 json_object_type::const_iterator,
67 json_object_type::iterator>;
72 using array_iterator_type = std::conditional_t<
74 json_array_type::const_iterator,
75 json_array_type::iterator>;
80 using iterator_type = std::variant<object_iterator_type, array_iterator_type>;
97 using value_type = JsonType;
98 using difference_type =
typename JsonType::difference_type;
99 using reference = std::conditional_t<
101 typename JsonType::const_reference,
102 typename JsonType::reference>;
103 using pointer = std::conditional_t<
105 typename JsonType::const_pointer,
106 typename JsonType::pointer>;
183 reference
operator[](difference_type offset)
const;
367 template <
typename J>
409 const typename json_object_type::key_type &
key()
const;
418 reference
value()
const;
421 friend std::conditional_t<is_const_iterator, NonConstJsonIterator, ConstJsonIterator>;
428 template <
typename... Ts>
429 static constexpr
inline bool is_object_iterator = fly::SameAsAll<object_iterator_type, Ts...>;
434 template <
typename... Ts>
435 static constexpr
inline bool is_array_iterator = fly::SameAsAll<array_iterator_type, Ts...>;
442 void validate_iterator()
const;
452 void validate_iterator(
const JsonIterator &iterator)
const;
466 template <
typename T>
467 void validate_offset(
const T &it, difference_type offset)
const;
478 template <
typename T>
479 void validate_dereference(
const T &it)
const;
481 pointer m_json {
nullptr};
482 iterator_type m_iterator;
486 template <fly::SameAs<Json> JsonType>
489 auto visitor = [
this, &position](
auto &value) noexcept(JsonIterable<decltype(value)>) {
490 if constexpr (JsonIterable<decltype(value)>)
494 case Position::Begin:
495 m_iterator = value.begin();
498 m_iterator = value.end();
508 if (m_json !=
nullptr)
510 std::visit(std::move(visitor), m_json->m_value);
515 template <fly::SameAs<Json> JsonType>
517 m_json(iterator.m_json)
519 auto visitor = [
this](
const auto &it) noexcept {
523 std::visit(std::move(visitor), iterator.m_iterator);
527 template <fly::SameAs<Json> JsonType>
531 m_json = iterator.m_json;
533 auto visitor = [
this](
const auto &it) noexcept {
537 std::visit(std::move(visitor), iterator.m_iterator);
542 template <fly::SameAs<Json> JsonType>
547 auto visitor = [
this](
const auto &it) -> reference {
548 this->validate_dereference(it);
550 if constexpr (is_object_iterator<decltype(it)>)
554 else if constexpr (is_array_iterator<decltype(it)>)
560 return std::visit(std::move(visitor), m_iterator);
564 template <fly::SameAs<Json> JsonType>
569 auto visitor = [
this](
const auto &it) -> pointer {
570 this->validate_dereference(it);
572 if constexpr (is_object_iterator<decltype(it)>)
574 return &(it->second);
576 else if constexpr (is_array_iterator<decltype(it)>)
582 return std::visit(std::move(visitor), m_iterator);
586 template <fly::SameAs<Json> JsonType>
591 auto visitor = [&](
const auto &it) -> reference {
592 if constexpr (is_array_iterator<decltype(it)>)
594 validate_offset(it, offset);
596 auto next = std::next(it, offset);
597 validate_dereference(next);
607 return std::visit(std::move(visitor), m_iterator);
611 template <fly::SameAs<Json> JsonType>
614 validate_iterator(iterator);
615 return m_iterator == iterator.m_iterator;
619 template <fly::SameAs<Json> JsonType>
622 return !(*
this == iterator);
626 template <fly::SameAs<Json> JsonType>
629 validate_iterator(iterator);
631 auto visitor = [
this](
const auto &it1,
const auto &it2) ->
bool {
632 if constexpr (is_array_iterator<decltype(it1), decltype(it2)>)
642 return std::visit(std::move(visitor), m_iterator, iterator.m_iterator);
646 template <fly::SameAs<Json> JsonType>
649 return !(iterator < *
this);
653 template <fly::SameAs<Json> JsonType>
656 return !(*
this <= iterator);
660 template <fly::SameAs<Json> JsonType>
663 return !(*
this < iterator);
667 template <fly::SameAs<Json> JsonType>
677 template <fly::SameAs<Json> JsonType>
683 validate_offset(it, 1);
689 return std::visit(std::move(visitor), m_iterator);
693 template <fly::SameAs<Json> JsonType>
703 template <fly::SameAs<Json> JsonType>
709 validate_offset(it, -1);
710 std::advance(it, -1);
715 return std::visit(std::move(visitor), m_iterator);
719 template <fly::SameAs<Json> JsonType>
724 auto visitor = [
this, &offset](
auto &it) {
725 if constexpr (is_array_iterator<decltype(it)>)
727 validate_offset(it, offset);
728 std::advance(it, offset);
736 std::visit(std::move(visitor), m_iterator);
741 template <fly::SameAs<Json> JsonType>
744 return *
this += -offset;
748 template <fly::SameAs<Json> JsonType>
758 template <fly::SameAs<Json> JsonType>
760 typename JsonIterator<JsonType>::difference_type offset,
763 auto result = iterator;
770 template <fly::SameAs<Json> JsonType>
780 template <fly::SameAs<Json> JsonType>
783 validate_iterator(iterator);
785 auto visitor = [
this](
const auto &it1,
const auto &it2) -> difference_type {
786 if constexpr (is_array_iterator<decltype(it1), decltype(it2)>)
788 return std::distance(it2, it1);
796 return std::visit(std::move(visitor), m_iterator, iterator.m_iterator);
800 template <fly::SameAs<Json> JsonType>
805 auto visitor = [
this](
const auto &it) ->
const typename json_object_type::key_type & {
806 if constexpr (is_object_iterator<decltype(it)>)
808 validate_dereference(it);
817 return std::visit(std::move(visitor), m_iterator);
821 template <fly::SameAs<Json> JsonType>
828 template <fly::SameAs<Json> JsonType>
831 if (m_json ==
nullptr)
838 template <fly::SameAs<Json> JsonType>
839 void JsonIterator<JsonType>::validate_iterator(
const JsonIterator &iterator)
const
842 iterator.validate_iterator();
844 if (m_json != iterator.m_json)
846 throw BadJsonComparisonException(*m_json, *iterator.m_json);
851 template <fly::SameAs<Json> JsonType>
852 template <
typename T>
853 void JsonIterator<JsonType>::validate_offset(
const T &it, difference_type offset)
const
856 difference_type distance = 0;
860 const JsonIterator end = m_json->end();
861 distance = std::distance(it, std::get<T>(end.m_iterator));
865 const JsonIterator begin = m_json->begin();
866 distance = std::distance(std::get<T>(begin.m_iterator), it);
869 if (std::abs(offset) > distance)
871 throw OutOfRangeJsonException(*m_json, offset);
876 template <fly::SameAs<Json> JsonType>
877 template <
typename T>
878 void JsonIterator<JsonType>::validate_dereference(
const T &it)
const
880 const JsonIterator end = m_json->end();
882 if (it == std::get<T>(end.m_iterator))
884 throw NullJsonException(*m_json);
Definition: json_exception.hpp:58
Definition: json_exception.hpp:88
Definition: json_iterator.hpp:58
bool operator==(const JsonIterator &iterator) const
Definition: json_iterator.hpp:612
const json_object_type::key_type & key() const
Definition: json_iterator.hpp:801
std::bidirectional_iterator_tag iterator_category
Definition: json_iterator.hpp:96
bool operator<=(const JsonIterator &iterator) const
Definition: json_iterator.hpp:647
bool operator>=(const JsonIterator &iterator) const
Definition: json_iterator.hpp:661
reference operator[](difference_type offset) const
Definition: json_iterator.hpp:587
bool operator!=(const JsonIterator &iterator) const
Definition: json_iterator.hpp:620
bool operator>(const JsonIterator &iterator) const
Definition: json_iterator.hpp:654
JsonIterator & operator+=(difference_type offset)
Definition: json_iterator.hpp:720
reference operator*() const
Definition: json_iterator.hpp:543
reference value() const
Definition: json_iterator.hpp:822
JsonIterator & operator++()
Definition: json_iterator.hpp:678
JsonIterator operator+(difference_type offset) const
Definition: json_iterator.hpp:749
JsonIterator & operator--()
Definition: json_iterator.hpp:704
Position
Definition: json_iterator.hpp:112
JsonIterator operator-(difference_type offset) const
Definition: json_iterator.hpp:771
bool operator<(const JsonIterator &iterator) const
Definition: json_iterator.hpp:627
JsonIterator & operator-=(difference_type offset)
Definition: json_iterator.hpp:742
pointer operator->() const
Definition: json_iterator.hpp:565
JsonIterator & operator=(const NonConstJsonIterator &iterator) noexcept
Definition: json_iterator.hpp:529
friend JsonIterator< J > operator+(typename JsonIterator< J >::difference_type offset, const JsonIterator< J > &iterator)
Definition: json_reverse_iterator.hpp:22