1 #pragma once
2 
3 #include <cstddef> // ptrdiff_t
4 #include <limits>  // numeric_limits
5 
6 namespace nlohmann
7 {
8 namespace detail
9 {
10 /*
11 @brief an iterator for primitive JSON types
12 
13 This class models an iterator for primitive JSON types (boolean, number,
14 string). It's only purpose is to allow the iterator/const_iterator classes
15 to "iterate" over primitive values. Internally, the iterator is modeled by
16 a `difference_type` variable. Value begin_value (`0`) models the begin,
17 end_value (`1`) models past the end.
18 */
19 class primitive_iterator_t
20 {
21   private:
22     using difference_type = std::ptrdiff_t;
23     static constexpr difference_type begin_value = 0;
24     static constexpr difference_type end_value = begin_value + 1;
25 
26     /// iterator as signed integer type
27     difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
28 
29   public:
get_value() const30     constexpr difference_type get_value() const noexcept
31     {
32         return m_it;
33     }
34 
35     /// set iterator to a defined beginning
set_begin()36     void set_begin() noexcept
37     {
38         m_it = begin_value;
39     }
40 
41     /// set iterator to a defined past the end
set_end()42     void set_end() noexcept
43     {
44         m_it = end_value;
45     }
46 
47     /// return whether the iterator can be dereferenced
is_begin() const48     constexpr bool is_begin() const noexcept
49     {
50         return m_it == begin_value;
51     }
52 
53     /// return whether the iterator is at end
is_end() const54     constexpr bool is_end() const noexcept
55     {
56         return m_it == end_value;
57     }
58 
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)59     friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
60     {
61         return lhs.m_it == rhs.m_it;
62     }
63 
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)64     friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
65     {
66         return lhs.m_it < rhs.m_it;
67     }
68 
operator +(difference_type n)69     primitive_iterator_t operator+(difference_type n) noexcept
70     {
71         auto result = *this;
72         result += n;
73         return result;
74     }
75 
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)76     friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
77     {
78         return lhs.m_it - rhs.m_it;
79     }
80 
operator ++()81     primitive_iterator_t& operator++() noexcept
82     {
83         ++m_it;
84         return *this;
85     }
86 
operator ++(int)87     primitive_iterator_t const operator++(int) noexcept
88     {
89         auto result = *this;
90         ++m_it;
91         return result;
92     }
93 
operator --()94     primitive_iterator_t& operator--() noexcept
95     {
96         --m_it;
97         return *this;
98     }
99 
operator --(int)100     primitive_iterator_t const operator--(int) noexcept
101     {
102         auto result = *this;
103         --m_it;
104         return result;
105     }
106 
operator +=(difference_type n)107     primitive_iterator_t& operator+=(difference_type n) noexcept
108     {
109         m_it += n;
110         return *this;
111     }
112 
operator -=(difference_type n)113     primitive_iterator_t& operator-=(difference_type n) noexcept
114     {
115         m_it -= n;
116         return *this;
117     }
118 };
119 }  // namespace detail
120 }  // namespace nlohmann
121