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