iterator_adaptor.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // (C) Copyright David Abrahams 2002.
  2. // (C) Copyright Jeremy Siek 2002.
  3. // (C) Copyright Thomas Witt 2002.
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
  8. #define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
  9. #include <type_traits>
  10. #include <boost/core/use_default.hpp>
  11. #include <boost/iterator/iterator_categories.hpp>
  12. #include <boost/iterator/iterator_facade.hpp>
  13. #include <boost/iterator/iterator_traits.hpp>
  14. #include <boost/iterator/enable_if_convertible.hpp> // for backward compatibility; remove once downstream users are updated
  15. #include <boost/iterator/detail/eval_if_default.hpp>
  16. #include <boost/iterator/detail/config_def.hpp>
  17. namespace boost {
  18. namespace iterators {
  19. // Used as a default template argument internally, merely to
  20. // indicate "use the default", this can also be passed by users
  21. // explicitly in order to specify that the default should be used.
  22. using boost::use_default;
  23. namespace detail {
  24. // A metafunction which computes an iterator_adaptor's base class,
  25. // a specialization of iterator_facade.
  26. template<
  27. typename Derived,
  28. typename Base,
  29. typename Value,
  30. typename Traversal,
  31. typename Reference,
  32. typename Difference
  33. >
  34. using iterator_adaptor_base_t = iterator_facade<
  35. Derived,
  36. #ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
  37. detail::eval_if_default_t<
  38. Value,
  39. detail::eval_if_default<
  40. Reference,
  41. iterator_value< Base >,
  42. std::remove_reference< Reference >
  43. >
  44. >,
  45. #else
  46. detail::eval_if_default_t<
  47. Value,
  48. iterator_value< Base >
  49. >,
  50. #endif
  51. detail::eval_if_default_t<
  52. Traversal,
  53. iterator_traversal< Base >
  54. >,
  55. detail::eval_if_default_t<
  56. Reference,
  57. detail::eval_if_default<
  58. Value,
  59. iterator_reference< Base >,
  60. std::add_lvalue_reference< Value >
  61. >
  62. >,
  63. detail::eval_if_default_t<
  64. Difference,
  65. iterator_difference< Base >
  66. >
  67. >;
  68. } // namespace detail
  69. //
  70. // Iterator Adaptor
  71. //
  72. // The parameter ordering changed slightly with respect to former
  73. // versions of iterator_adaptor The idea is that when the user needs
  74. // to fiddle with the reference type it is highly likely that the
  75. // iterator category has to be adjusted as well. Any of the
  76. // following four template arguments may be omitted or explicitly
  77. // replaced by use_default.
  78. //
  79. // Value - if supplied, the value_type of the resulting iterator, unless
  80. // const. If const, a conforming compiler strips constness for the
  81. // value_type. If not supplied, iterator_traits<Base>::value_type is used
  82. //
  83. // Category - the traversal category of the resulting iterator. If not
  84. // supplied, iterator_traversal<Base>::type is used.
  85. //
  86. // Reference - the reference type of the resulting iterator, and in
  87. // particular, the result type of operator*(). If not supplied but
  88. // Value is supplied, Value& is used. Otherwise
  89. // iterator_traits<Base>::reference is used.
  90. //
  91. // Difference - the difference_type of the resulting iterator. If not
  92. // supplied, iterator_traits<Base>::difference_type is used.
  93. //
  94. template<
  95. typename Derived,
  96. typename Base,
  97. typename Value = use_default,
  98. typename Traversal = use_default,
  99. typename Reference = use_default,
  100. typename Difference = use_default
  101. >
  102. class iterator_adaptor :
  103. public detail::iterator_adaptor_base_t<
  104. Derived, Base, Value, Traversal, Reference, Difference
  105. >
  106. {
  107. friend class iterator_core_access;
  108. protected:
  109. using super_t = detail::iterator_adaptor_base_t<
  110. Derived, Base, Value, Traversal, Reference, Difference
  111. >;
  112. public:
  113. using base_type = Base;
  114. iterator_adaptor() = default;
  115. explicit iterator_adaptor(Base const& iter) :
  116. m_iterator(iter)
  117. {
  118. }
  119. base_type const& base() const { return m_iterator; }
  120. protected:
  121. // for convenience in derived classes
  122. using iterator_adaptor_ = iterator_adaptor< Derived, Base, Value, Traversal, Reference, Difference >;
  123. //
  124. // lvalue access to the Base object for Derived
  125. //
  126. Base& base_reference() { return m_iterator; }
  127. Base const& base_reference() const { return m_iterator; }
  128. private:
  129. //
  130. // Core iterator interface for iterator_facade. This is private
  131. // to prevent temptation for Derived classes to use it, which
  132. // will often result in an error. Derived classes should use
  133. // base_reference(), above, to get direct access to m_iterator.
  134. //
  135. typename super_t::reference dereference() const { return *m_iterator; }
  136. template< typename OtherDerived, typename OtherIterator, typename V, typename C, typename R, typename D >
  137. bool equal(iterator_adaptor< OtherDerived, OtherIterator, V, C, R, D > const& x) const
  138. {
  139. // Maybe readd with same_distance
  140. // BOOST_STATIC_ASSERT(
  141. // (detail::same_category_and_difference<Derived,OtherDerived>::value)
  142. // );
  143. return m_iterator == x.base();
  144. }
  145. using my_traversal = typename iterator_category_to_traversal< typename super_t::iterator_category >::type;
  146. void advance(typename super_t::difference_type n)
  147. {
  148. static_assert(detail::is_traversal_at_least< my_traversal, random_access_traversal_tag >::value,
  149. "Iterator must support random access traversal.");
  150. m_iterator += n;
  151. }
  152. void increment() { ++m_iterator; }
  153. void decrement()
  154. {
  155. static_assert(detail::is_traversal_at_least< my_traversal, bidirectional_traversal_tag >::value,
  156. "Iterator must support bidirectional traversal.");
  157. --m_iterator;
  158. }
  159. template< typename OtherDerived, typename OtherIterator, typename V, typename C, typename R, typename D >
  160. typename super_t::difference_type distance_to(iterator_adaptor< OtherDerived, OtherIterator, V, C, R, D > const& y) const
  161. {
  162. static_assert(detail::is_traversal_at_least< my_traversal, random_access_traversal_tag >::value,
  163. "Super iterator must support random access traversal.");
  164. // Maybe readd with same_distance
  165. // BOOST_STATIC_ASSERT(
  166. // (detail::same_category_and_difference<Derived,OtherDerived>::value)
  167. // );
  168. return y.base() - m_iterator;
  169. }
  170. private: // data members
  171. Base m_iterator;
  172. };
  173. } // namespace iterators
  174. using iterators::iterator_adaptor;
  175. } // namespace boost
  176. #include <boost/iterator/detail/config_undef.hpp>
  177. #endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP