libfly  6.2.2
C++20 utility library for Linux, macOS, and Windows
json_reverse_iterator.hpp
1 #pragma once
2 
3 #include "fly/types/json/concepts.hpp"
4 #include "fly/types/json/json_exception.hpp"
5 
6 #include <cstddef>
7 #include <iterator>
8 
9 namespace fly::detail {
10 
20 template <typename JsonIterator>
21 class JsonReverseIterator : public std::reverse_iterator<JsonIterator>
22 {
23  using reverse_iterator = std::reverse_iterator<JsonIterator>;
24 
25 public:
29  using value_type = typename JsonIterator::value_type;
30  using difference_type = typename JsonIterator::difference_type;
31  using reference = typename JsonIterator::reference;
32  using const_reference = const reference;
33  using pointer = typename JsonIterator::pointer;
34 
38  JsonReverseIterator() noexcept;
39 
45  explicit JsonReverseIterator(const JsonIterator &it) noexcept;
46 
52  explicit JsonReverseIterator(const reverse_iterator &it) noexcept;
53 
61  reference operator*() const;
62 
70  pointer operator->() const;
71 
86  reference operator[](difference_type offset) const;
87 
97  JsonReverseIterator operator++(int);
98 
108  JsonReverseIterator &operator++();
109 
120  JsonReverseIterator operator--(int);
121 
132  JsonReverseIterator &operator--();
133 
147  JsonReverseIterator &operator+=(difference_type offset);
148 
162  JsonReverseIterator &operator-=(difference_type offset);
163 
177  JsonReverseIterator operator+(difference_type offset) const;
178 
192  JsonReverseIterator operator-(difference_type offset) const;
193 
205  difference_type operator-(const JsonReverseIterator &other) const;
206 
216  const typename json_object_type::key_type &key() const;
217 
225  reference value() const;
226 
227 private:
233  const_reference json() const;
234 };
235 
236 //==================================================================================================
237 template <typename JsonIterator>
238 JsonReverseIterator<JsonIterator>::JsonReverseIterator() noexcept : reverse_iterator()
239 {
240 }
241 
242 //==================================================================================================
243 template <typename JsonIterator>
245  reverse_iterator(it)
246 {
247 }
248 
249 //==================================================================================================
250 template <typename JsonIterator>
251 JsonReverseIterator<JsonIterator>::JsonReverseIterator(const reverse_iterator &it) noexcept :
252  reverse_iterator(it)
253 {
254 }
255 
256 //==================================================================================================
257 template <typename JsonIterator>
259 {
260  try
261  {
262  return reverse_iterator::operator*();
263  }
264  catch (const fly::OutOfRangeJsonException &)
265  {
266  throw fly::NullJsonException(json());
267  }
268 }
269 
270 //==================================================================================================
271 template <typename JsonIterator>
273 {
274  try
275  {
276  return reverse_iterator::operator->();
277  }
278  catch (const fly::OutOfRangeJsonException &)
279  {
280  throw fly::NullJsonException(json());
281  }
282 }
283 
284 //==================================================================================================
285 template <typename JsonIterator>
286 auto JsonReverseIterator<JsonIterator>::operator[](difference_type offset) const -> reference
287 {
288  return *(operator+(offset));
289 }
290 
291 //==================================================================================================
292 template <typename JsonIterator>
294 {
295  return static_cast<JsonReverseIterator>(reverse_iterator::operator++(dummy));
296 }
297 
298 //==================================================================================================
299 template <typename JsonIterator>
301 {
302  return static_cast<JsonReverseIterator &>(reverse_iterator::operator++());
303 }
304 
305 //==================================================================================================
306 template <typename JsonIterator>
308 {
309  return static_cast<JsonReverseIterator>(reverse_iterator::operator--(dummy));
310 }
311 
312 //==================================================================================================
313 template <typename JsonIterator>
315 {
316  return static_cast<JsonReverseIterator &>(reverse_iterator::operator--());
317 }
318 
319 //==================================================================================================
320 template <typename JsonIterator>
322 {
323  return static_cast<JsonReverseIterator &>(reverse_iterator::operator+=(offset));
324 }
325 
326 //==================================================================================================
327 template <typename JsonIterator>
329 {
330  return static_cast<JsonReverseIterator &>(reverse_iterator::operator-=(offset));
331 }
332 
333 //==================================================================================================
334 template <typename JsonIterator>
335 auto JsonReverseIterator<JsonIterator>::operator+(difference_type offset) const
337 {
338  return static_cast<JsonReverseIterator>(reverse_iterator::operator+(offset));
339 }
340 
341 //==================================================================================================
342 template <typename JsonIterator>
343 auto JsonReverseIterator<JsonIterator>::operator-(difference_type offset) const
345 {
346  return static_cast<JsonReverseIterator>(reverse_iterator::operator-(offset));
347 }
348 
349 //==================================================================================================
350 template <typename JsonIterator>
352  -> difference_type
353 {
354  return reverse_iterator(*this) - reverse_iterator(other);
355 }
356 
357 //==================================================================================================
358 template <typename JsonIterator>
359 const typename json_object_type::key_type &JsonReverseIterator<JsonIterator>::key() const
360 {
361  try
362  {
363  auto it = --(reverse_iterator::base());
364  return it.key();
365  }
366  catch (const fly::OutOfRangeJsonException &)
367  {
368  throw fly::NullJsonException(json());
369  }
370 }
371 
372 //==================================================================================================
373 template <typename JsonIterator>
375 {
376  try
377  {
378  auto it = --(reverse_iterator::base());
379  return it.value();
380  }
381  catch (const fly::OutOfRangeJsonException &)
382  {
383  throw fly::NullJsonException(json());
384  }
385 }
386 
387 //==================================================================================================
388 template <typename JsonIterator>
389 auto JsonReverseIterator<JsonIterator>::json() const -> const_reference
390 {
391  return *(reverse_iterator::base().m_json);
392 }
393 
394 } // namespace fly::detail
Definition: json_exception.hpp:88
Definition: json_exception.hpp:108
Definition: json_iterator.hpp:58
Definition: json_reverse_iterator.hpp:22
JsonReverseIterator operator-(difference_type offset) const
Definition: json_reverse_iterator.hpp:343
JsonReverseIterator & operator++()
Definition: json_reverse_iterator.hpp:300
const json_object_type::key_type & key() const
Definition: json_reverse_iterator.hpp:359
JsonReverseIterator & operator+=(difference_type offset)
Definition: json_reverse_iterator.hpp:321
JsonReverseIterator operator+(difference_type offset) const
Definition: json_reverse_iterator.hpp:335
reference operator*() const
Definition: json_reverse_iterator.hpp:258
reference operator[](difference_type offset) const
Definition: json_reverse_iterator.hpp:286
JsonReverseIterator & operator-=(difference_type offset)
Definition: json_reverse_iterator.hpp:328
reference value() const
Definition: json_reverse_iterator.hpp:374
JsonReverseIterator() noexcept
Definition: json_reverse_iterator.hpp:238
JsonReverseIterator & operator--()
Definition: json_reverse_iterator.hpp:314
typename JsonIterator::value_type value_type
Definition: json_reverse_iterator.hpp:29
pointer operator->() const
Definition: json_reverse_iterator.hpp:272