indirect_iterator.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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_INDIRECT_ITERATOR_23022003THW_HPP
  8. #define BOOST_INDIRECT_ITERATOR_23022003THW_HPP
  9. #include <iterator>
  10. #include <type_traits>
  11. #include <boost/iterator/iterator_adaptor.hpp>
  12. #include <boost/iterator/enable_if_convertible.hpp>
  13. #include <boost/iterator/detail/eval_if_default.hpp>
  14. #include <boost/pointee.hpp>
  15. #include <boost/indirect_reference.hpp>
  16. #include <boost/core/use_default.hpp>
  17. namespace boost {
  18. namespace iterators {
  19. template< typename Iter, typename Value, typename Category, typename Reference, typename Difference >
  20. class indirect_iterator;
  21. namespace detail {
  22. template< typename Iter, typename Value, typename Category, typename Reference, typename Difference >
  23. struct indirect_base
  24. {
  25. using dereferenceable = typename std::iterator_traits< Iter >::value_type;
  26. using type = iterator_adaptor<
  27. indirect_iterator< Iter, Value, Category, Reference, Difference >,
  28. Iter,
  29. detail::eval_if_default_t<
  30. Value,
  31. pointee< dereferenceable >
  32. >,
  33. Category,
  34. detail::eval_if_default_t<
  35. Reference,
  36. detail::eval_if_default<
  37. Value,
  38. indirect_reference< dereferenceable >,
  39. std::add_lvalue_reference< Value >
  40. >
  41. >,
  42. Difference
  43. >;
  44. };
  45. } // namespace detail
  46. template<
  47. typename Iterator,
  48. typename Value = use_default,
  49. typename Category = use_default,
  50. typename Reference = use_default,
  51. typename Difference = use_default
  52. >
  53. class indirect_iterator :
  54. public detail::indirect_base<
  55. Iterator, Value, Category, Reference, Difference
  56. >::type
  57. {
  58. using super_t = typename detail::indirect_base<
  59. Iterator, Value, Category, Reference, Difference
  60. >::type;
  61. friend class iterator_core_access;
  62. public:
  63. indirect_iterator() = default;
  64. indirect_iterator(Iterator iter) :
  65. super_t(iter)
  66. {}
  67. template<
  68. typename Iterator2,
  69. typename Value2,
  70. typename Category2,
  71. typename Reference2,
  72. typename Difference2,
  73. typename = enable_if_convertible_t< Iterator2, Iterator >
  74. >
  75. indirect_iterator(indirect_iterator< Iterator2, Value2, Category2, Reference2, Difference2 > const& y) :
  76. super_t(y.base())
  77. {}
  78. private:
  79. typename super_t::reference dereference() const
  80. {
  81. return **this->base();
  82. }
  83. };
  84. template< typename Iter >
  85. inline indirect_iterator< Iter > make_indirect_iterator(Iter x)
  86. {
  87. return indirect_iterator< Iter >(x);
  88. }
  89. template< typename Value, typename Iter >
  90. inline indirect_iterator< Iter, Value > make_indirect_iterator(Iter x)
  91. {
  92. return indirect_iterator< Iter, Value >(x);
  93. }
  94. } // namespace iterators
  95. using iterators::indirect_iterator;
  96. using iterators::make_indirect_iterator;
  97. } // namespace boost
  98. #endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP