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