indexed.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Boost.Range library
  2. //
  3. // Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // For more information, see http://www.boost.org/libs/range/
  9. //
  10. #ifndef BOOST_RANGE_ADAPTOR_INDEXED_IMPL_HPP
  11. #define BOOST_RANGE_ADAPTOR_INDEXED_IMPL_HPP
  12. #include <boost/config.hpp>
  13. #ifdef BOOST_MSVC
  14. #pragma warning( push )
  15. #pragma warning( disable : 4355 )
  16. #endif
  17. #include <boost/range/adaptor/argument_fwd.hpp>
  18. #include <boost/range/iterator_range.hpp>
  19. #include <boost/range/begin.hpp>
  20. #include <boost/range/end.hpp>
  21. #include <boost/iterator/iterator_adaptor.hpp>
  22. namespace boost
  23. {
  24. namespace adaptors
  25. {
  26. // This structure exists to carry the parameters from the '|' operator
  27. // to the index adapter. The expression rng | indexed(1) instantiates
  28. // this structure and passes it as the right-hand operand to the
  29. // '|' operator.
  30. struct indexed
  31. {
  32. explicit indexed(std::size_t x) : val(x) {}
  33. std::size_t val;
  34. };
  35. }
  36. namespace range_detail
  37. {
  38. template< class Iter >
  39. class indexed_iterator
  40. : public boost::iterator_adaptor< indexed_iterator<Iter>, Iter >
  41. {
  42. private:
  43. typedef boost::iterator_adaptor< indexed_iterator<Iter>, Iter >
  44. base;
  45. typedef BOOST_DEDUCED_TYPENAME base::difference_type index_type;
  46. index_type m_index;
  47. public:
  48. indexed_iterator()
  49. : m_index(index_type()) {}
  50. explicit indexed_iterator( Iter i, index_type index )
  51. : base(i), m_index(index)
  52. {
  53. BOOST_ASSERT( m_index >= 0 && "Indexed Iterator out of bounds" );
  54. }
  55. index_type index() const
  56. {
  57. return m_index;
  58. }
  59. private:
  60. friend class boost::iterator_core_access;
  61. void increment()
  62. {
  63. ++m_index;
  64. ++(this->base_reference());
  65. }
  66. void decrement()
  67. {
  68. BOOST_ASSERT( m_index > 0 && "Indexed Iterator out of bounds" );
  69. --m_index;
  70. --(this->base_reference());
  71. }
  72. void advance( index_type n )
  73. {
  74. m_index += n;
  75. BOOST_ASSERT( m_index >= 0 && "Indexed Iterator out of bounds" );
  76. this->base_reference() += n;
  77. }
  78. };
  79. template< class Rng >
  80. struct indexed_range :
  81. iterator_range< indexed_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type> >
  82. {
  83. private:
  84. typedef indexed_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type>
  85. iter_type;
  86. typedef iterator_range<iter_type>
  87. base;
  88. public:
  89. template< class Index >
  90. indexed_range( Index i, Rng& r )
  91. : base( iter_type(boost::begin(r), i), iter_type(boost::end(r),i) )
  92. { }
  93. };
  94. } // 'range_detail'
  95. // Make this available to users of this library. It will sometimes be
  96. // required since it is the return type of operator '|' and
  97. // index().
  98. using range_detail::indexed_range;
  99. namespace adaptors
  100. {
  101. template< class SinglePassRange >
  102. inline indexed_range<SinglePassRange>
  103. operator|( SinglePassRange& r,
  104. const indexed& f )
  105. {
  106. return indexed_range<SinglePassRange>( f.val, r );
  107. }
  108. template< class SinglePassRange >
  109. inline indexed_range<const SinglePassRange>
  110. operator|( const SinglePassRange& r,
  111. const indexed& f )
  112. {
  113. return indexed_range<const SinglePassRange>( f.val, r );
  114. }
  115. template<class SinglePassRange, class Index>
  116. inline indexed_range<SinglePassRange>
  117. index(SinglePassRange& rng, Index index_value)
  118. {
  119. return indexed_range<SinglePassRange>(index_value, rng);
  120. }
  121. template<class SinglePassRange, class Index>
  122. inline indexed_range<const SinglePassRange>
  123. index(const SinglePassRange& rng, Index index_value)
  124. {
  125. return indexed_range<const SinglePassRange>(index_value, rng);
  126. }
  127. } // 'adaptors'
  128. }
  129. #ifdef BOOST_MSVC
  130. #pragma warning( pop )
  131. #endif
  132. #endif