iterator.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2023 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_DETAIL_ITERATOR_HPP_INCLUDED
5 #define LEXY_DETAIL_ITERATOR_HPP_INCLUDED
6 
10 #include <lexy/_detail/std.hpp>
11 
12 //=== iterator algorithms ===//
13 namespace lexy::_detail
14 {
15 // Can't use std::is_base_of_v<std::random_access_iterator_tag, ...> without including <iterator>.
16 template <typename Iterator>
17 using _detect_random_access = decltype(LEXY_DECLVAL(Iterator) - LEXY_DECLVAL(Iterator));
18 template <typename Iterator>
19 constexpr auto is_random_access_iterator = is_detected<_detect_random_access, Iterator>;
20 
21 template <typename Iterator, typename Sentinel>
22 constexpr std::size_t range_size(Iterator begin, Sentinel end)
23 {
24  if constexpr (std::is_same_v<Iterator, Sentinel> && is_random_access_iterator<Iterator>)
25  {
26  return static_cast<std::size_t>(end - begin);
27  }
28  else
29  {
30  std::size_t result = 0;
31  for (auto cur = begin; cur != end; ++cur)
32  ++result;
33  return result;
34  }
35 }
36 
37 template <typename Iterator>
38 constexpr Iterator next(Iterator iter)
39 {
40  return ++iter;
41 }
42 template <typename Iterator>
43 constexpr Iterator next(Iterator iter, std::size_t n)
44 {
45  if constexpr (is_random_access_iterator<Iterator>)
46  {
47  return iter + n;
48  }
49  else
50  {
51  for (auto i = 0u; i != n; ++i)
52  ++iter;
53  return iter;
54  }
55 }
56 
57 template <typename Iterator, typename Sentinel>
58 constexpr Iterator next_clamped(Iterator iter, std::size_t n, Sentinel end)
59 {
60  if constexpr (is_random_access_iterator<Iterator> && std::is_same_v<Iterator, Sentinel>)
61  {
62  auto remaining = std::size_t(end - iter);
63  if (remaining < n)
64  return end;
65  else
66  return iter + n;
67  }
68  else
69  {
70  for (auto i = 0u; i != n; ++i)
71  {
72  if (iter == end)
73  break;
74  ++iter;
75  }
76  return iter;
77  }
78 }
79 
80 // Used for assertions.
81 template <typename Iterator, typename Sentinel>
82 constexpr bool precedes([[maybe_unused]] Iterator first, [[maybe_unused]] Sentinel after)
83 {
84  if constexpr (is_random_access_iterator<Iterator> && std::is_same_v<Iterator, Sentinel>)
85  return first <= after;
86  else
87  return true;
88 }
89 
90 // Requires: begin <= end_a && begin <= end_b.
91 // Returns min(end_a, end_b).
92 template <typename Iterator>
93 constexpr Iterator min_range_end(Iterator begin, Iterator end_a, Iterator end_b)
94 {
95  if constexpr (is_random_access_iterator<Iterator>)
96  {
97  LEXY_PRECONDITION(begin <= end_a && begin <= end_b);
98  if (end_a <= end_b)
99  return end_a;
100  else
101  return end_b;
102  }
103  else
104  {
105  auto cur = begin;
106  while (cur != end_a && cur != end_b)
107  ++cur;
108  return cur;
109  }
110 }
111 
112 // Requires: begin <= end_a && begin <= end_b.
113 // Returns max(end_a, end_b).
114 template <typename Iterator>
115 constexpr Iterator max_range_end(Iterator begin, Iterator end_a, Iterator end_b)
116 {
117  if constexpr (is_random_access_iterator<Iterator>)
118  {
119  LEXY_PRECONDITION(begin <= end_a && begin <= end_b);
120  if (end_a <= end_b)
121  return end_b;
122  else
123  return end_a;
124  }
125  else
126  {
127  auto cur = begin;
128  while (true)
129  {
130  if (cur == end_a)
131  return end_b;
132  else if (cur == end_b)
133  return end_a;
134 
135  ++cur;
136  }
137  return begin; // unreachable
138  }
139 }
140 } // namespace lexy::_detail
141 
142 //=== facade classes ===//
143 namespace lexy::_detail
144 {
145 template <typename T>
147 {
148  T value;
149 
150  constexpr T* operator->() noexcept
151  {
152  return &value;
153  }
154 };
155 
156 template <typename Derived, typename T, typename Reference = T&, typename Pointer = const T*>
158 {
159  using value_type = std::remove_cv_t<T>;
160  using reference = Reference;
162  using difference_type = std::ptrdiff_t;
163  using iterator_category = std::forward_iterator_tag;
164 
165  constexpr reference operator*() const noexcept
166  {
167  return static_cast<const Derived&>(*this).deref();
168  }
169  constexpr pointer operator->() const noexcept
170  {
171  if constexpr (std::is_void_v<Pointer>)
172  return pointer{**this};
173  else
174  return &**this;
175  }
176 
177  constexpr Derived& operator++() noexcept
178  {
179  auto& derived = static_cast<Derived&>(*this);
180  derived.increment();
181  return derived;
182  }
183  constexpr Derived operator++(int) noexcept
184  {
185  auto& derived = static_cast<Derived&>(*this);
186  auto copy = derived;
187  derived.increment();
188  return copy;
189  }
190 
191  friend constexpr bool operator==(const Derived& lhs, const Derived& rhs)
192  {
193  return lhs.equal(rhs);
194  }
195  friend constexpr bool operator!=(const Derived& lhs, const Derived& rhs)
196  {
197  return !lhs.equal(rhs);
198  }
199 };
200 
201 template <typename Derived, typename T, typename Reference = T&, typename Pointer = const T*>
202 struct bidirectional_iterator_base : forward_iterator_base<Derived, T, Reference, Pointer>
203 {
204  using iterator_category = std::bidirectional_iterator_tag;
205 
206  constexpr Derived& operator--() noexcept
207  {
208  auto& derived = static_cast<Derived&>(*this);
209  derived.decrement();
210  return derived;
211  }
212  constexpr Derived operator--(int) noexcept
213  {
214  auto& derived = static_cast<Derived&>(*this);
215  auto copy = derived;
216  derived.decrement();
217  return copy;
218  }
219 };
220 
221 template <typename Derived, typename Iterator>
223 {
224  friend constexpr bool operator==(const Iterator& lhs, Derived) noexcept
225  {
226  return lhs.is_end();
227  }
228  friend constexpr bool operator!=(const Iterator& lhs, Derived) noexcept
229  {
230  return !(lhs == Derived{});
231  }
232  friend constexpr bool operator==(Derived, const Iterator& rhs) noexcept
233  {
234  return rhs == Derived{};
235  }
236  friend constexpr bool operator!=(Derived, const Iterator& rhs) noexcept
237  {
238  return !(rhs == Derived{});
239  }
240 };
241 } // namespace lexy::_detail
242 
243 #endif // LEXY_DETAIL_ITERATOR_HPP_INCLUDED
244 
detect.hpp
lexy::_detail::forward_iterator_base::operator++
constexpr Derived & operator++() noexcept
Definition: iterator.hpp:177
lexy::_detail::sentinel_base::operator!=
constexpr friend bool operator!=(const Iterator &lhs, Derived) noexcept
Definition: iterator.hpp:228
lexy::_detail::forward_iterator_base< iterator, node, node, void >::value_type
std::remove_cv_t< node > value_type
Definition: iterator.hpp:159
lexy::_detail::_proxy_pointer
Definition: iterator.hpp:146
lexy::_detail::precedes
constexpr bool precedes([[maybe_unused]] Iterator first, [[maybe_unused]] Sentinel after)
Definition: iterator.hpp:82
config.hpp
lexy::_detail::forward_iterator_base::operator->
constexpr pointer operator->() const noexcept
Definition: iterator.hpp:169
lexy::_detail::type_or
std::conditional_t< std::is_void_v< T >, Fallback, T > type_or
Definition: config.hpp:56
lexy::_detail::next
constexpr Iterator next(Iterator iter)
Definition: iterator.hpp:38
std.hpp
LEXY_PRECONDITION
#define LEXY_PRECONDITION(Expr)
Definition: assert.hpp:36
cx::end
constexpr auto end(const C &c) -> decltype(c.end())
Definition: wildcards.hpp:686
lexy::_detail::max_range_end
constexpr Iterator max_range_end(Iterator begin, Iterator end_a, Iterator end_b)
Definition: iterator.hpp:115
lexy::_detail::_detect_random_access
decltype(LEXY_DECLVAL(Iterator) - LEXY_DECLVAL(Iterator)) _detect_random_access
Definition: iterator.hpp:17
lexy::_detail::forward_iterator_base< iterator, node, node, void >::reference
node reference
Definition: iterator.hpp:160
lexy::_detail::next_clamped
constexpr Iterator next_clamped(Iterator iter, std::size_t n, Sentinel end)
Definition: iterator.hpp:58
lexy::_detail::forward_iterator_base< iterator, node, node, void >::pointer
lexy::_detail::type_or< void, _proxy_pointer< value_type > > pointer
Definition: iterator.hpp:161
lexy::_detail::sentinel_base::operator!=
constexpr friend bool operator!=(Derived, const Iterator &rhs) noexcept
Definition: iterator.hpp:236
lexy::_detail::forward_iterator_base::operator!=
constexpr friend bool operator!=(const Derived &lhs, const Derived &rhs)
Definition: iterator.hpp:195
lexy::_detail::forward_iterator_base< iterator, node, node, void >::difference_type
std::ptrdiff_t difference_type
Definition: iterator.hpp:162
lexy::_detail::_proxy_pointer::value
T value
Definition: iterator.hpp:148
lexy::_detail::bidirectional_iterator_base::operator--
constexpr Derived & operator--() noexcept
Definition: iterator.hpp:206
lexy::_detail::bidirectional_iterator_base::operator--
constexpr Derived operator--(int) noexcept
Definition: iterator.hpp:212
assert.hpp
lexy::_detail::range_size
constexpr std::size_t range_size(Iterator begin, Sentinel end)
Definition: iterator.hpp:22
magic_enum::detail::n
constexpr auto n() noexcept
Definition: magic_enum.hpp:417
lexy::_detail::forward_iterator_base::operator*
constexpr reference operator*() const noexcept
Definition: iterator.hpp:165
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexy::_detail::_proxy_pointer::operator->
constexpr T * operator->() noexcept
Definition: iterator.hpp:150
lexy::_detail
Definition: any_ref.hpp:12
lexy::argv_iterator::decrement
constexpr void decrement() noexcept
Definition: argv_input.hpp:47
lexy::_detail::bidirectional_iterator_base
Definition: iterator.hpp:202
lexy::_detail::forward_iterator_base
Definition: iterator.hpp:157
lexy::_detail::sentinel_base
Definition: iterator.hpp:222
lexy::_detail::sentinel_base::operator==
constexpr friend bool operator==(Derived, const Iterator &rhs) noexcept
Definition: iterator.hpp:232
lexy::_detail::min_range_end
constexpr Iterator min_range_end(Iterator begin, Iterator end_a, Iterator end_b)
Definition: iterator.hpp:93
LEXY_DECLVAL
#define LEXY_DECLVAL(...)
Definition: config.hpp:24
lexy::_detail::forward_iterator_base< iterator, node, node, void >::iterator_category
std::forward_iterator_tag iterator_category
Definition: iterator.hpp:163
lexy::_detail::sentinel_base::operator==
constexpr friend bool operator==(const Iterator &lhs, Derived) noexcept
Definition: iterator.hpp:224
lexy::_detail::forward_iterator_base::operator++
constexpr Derived operator++(int) noexcept
Definition: iterator.hpp:183
lexy::_detail::forward_iterator_base::operator==
constexpr friend bool operator==(const Derived &lhs, const Derived &rhs)
Definition: iterator.hpp:191
lexy::_detail::is_random_access_iterator
constexpr auto is_random_access_iterator
Definition: iterator.hpp:19


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:07