json_reverse_iterator.hpp 3.3 KB

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