• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma once
2 
3 #include <cstddef> // ptrdiff_t
4 #include <iterator> // reverse_iterator
5 #include <utility> // declval
6 
7 namespace nlohmann
8 {
9 namespace detail
10 {
11 //////////////////////
12 // reverse_iterator //
13 //////////////////////
14 
15 /*!
16 @brief a template for a reverse iterator class
17 
18 @tparam Base the base iterator type to reverse. Valid types are @ref
19 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
20 create @ref const_reverse_iterator).
21 
22 @requirement The class satisfies the following concept requirements:
23 -
24 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
25   The iterator that can be moved can be moved in both directions (i.e.
26   incremented and decremented).
27 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
28   It is possible to write to the pointed-to element (only if @a Base is
29   @ref iterator).
30 
31 @since version 1.0.0
32 */
33 template<typename Base>
34 class json_reverse_iterator : public std::reverse_iterator<Base>
35 {
36   public:
37     using difference_type = std::ptrdiff_t;
38     /// shortcut to the reverse iterator adapter
39     using base_iterator = std::reverse_iterator<Base>;
40     /// the reference type for the pointed-to element
41     using reference = typename Base::reference;
42 
43     /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)44     explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
45         : base_iterator(it) {}
46 
47     /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)48     explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
49 
50     /// post-increment (it++)
operator ++(int)51     json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
52     {
53         return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
54     }
55 
56     /// pre-increment (++it)
operator ++()57     json_reverse_iterator& operator++()
58     {
59         return static_cast<json_reverse_iterator&>(base_iterator::operator++());
60     }
61 
62     /// post-decrement (it--)
operator --(int)63     json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
64     {
65         return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
66     }
67 
68     /// pre-decrement (--it)
operator --()69     json_reverse_iterator& operator--()
70     {
71         return static_cast<json_reverse_iterator&>(base_iterator::operator--());
72     }
73 
74     /// add to iterator
operator +=(difference_type i)75     json_reverse_iterator& operator+=(difference_type i)
76     {
77         return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
78     }
79 
80     /// add to iterator
operator +(difference_type i) const81     json_reverse_iterator operator+(difference_type i) const
82     {
83         return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
84     }
85 
86     /// subtract from iterator
operator -(difference_type i) const87     json_reverse_iterator operator-(difference_type i) const
88     {
89         return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
90     }
91 
92     /// return difference
operator -(const json_reverse_iterator & other) const93     difference_type operator-(const json_reverse_iterator& other) const
94     {
95         return base_iterator(*this) - base_iterator(other);
96     }
97 
98     /// access to successor
operator [](difference_type n) const99     reference operator[](difference_type n) const
100     {
101         return *(this->operator+(n));
102     }
103 
104     /// return the key of an object iterator
key() const105     auto key() const -> decltype(std::declval<Base>().key())
106     {
107         auto it = --this->base();
108         return it.key();
109     }
110 
111     /// return the value of an iterator
value() const112     reference value() const
113     {
114         auto it = --this->base();
115         return it.operator * ();
116     }
117 };
118 }  // namespace detail
119 }  // namespace nlohmann
120