sub_range.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Boost.Range library
  2. //
  3. // Copyright Thorsten Ottosen 2003-2004. 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_SUB_RANGE_HPP
  11. #define BOOST_RANGE_SUB_RANGE_HPP
  12. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
  13. #pragma warning( push )
  14. #pragma warning( disable : 4996 )
  15. #endif
  16. #include <boost/detail/workaround.hpp>
  17. #include <boost/range/config.hpp>
  18. #include <boost/range/iterator_range.hpp>
  19. #include <boost/range/value_type.hpp>
  20. #include <boost/range/size_type.hpp>
  21. #include <boost/range/difference_type.hpp>
  22. #include <boost/assert.hpp>
  23. #include <boost/type_traits/is_reference.hpp>
  24. #include <boost/type_traits/remove_reference.hpp>
  25. namespace boost
  26. {
  27. template< class ForwardRange >
  28. class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
  29. {
  30. typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t;
  31. typedef iterator_range< iterator_t > base;
  32. typedef BOOST_DEDUCED_TYPENAME base::impl impl;
  33. public:
  34. typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type;
  35. typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator;
  36. typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type const_iterator;
  37. typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type difference_type;
  38. typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type size_type;
  39. typedef BOOST_DEDUCED_TYPENAME base::reference reference;
  40. public: // for return value of front/back
  41. typedef BOOST_DEDUCED_TYPENAME
  42. boost::mpl::if_< boost::is_reference<reference>,
  43. const BOOST_DEDUCED_TYPENAME boost::remove_reference<reference>::type&,
  44. reference >::type const_reference;
  45. public:
  46. sub_range() : base()
  47. { }
  48. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
  49. sub_range( const sub_range& r )
  50. : base( static_cast<const base&>( r ) )
  51. { }
  52. #endif
  53. template< class ForwardRange2 >
  54. sub_range( ForwardRange2& r ) :
  55. #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
  56. base( impl::adl_begin( r ), impl::adl_end( r ) )
  57. #else
  58. base( r )
  59. #endif
  60. { }
  61. template< class ForwardRange2 >
  62. sub_range( const ForwardRange2& r ) :
  63. #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
  64. base( impl::adl_begin( r ), impl::adl_end( r ) )
  65. #else
  66. base( r )
  67. #endif
  68. { }
  69. template< class Iter >
  70. sub_range( Iter first, Iter last ) :
  71. base( first, last )
  72. { }
  73. template< class ForwardRange2 >
  74. sub_range& operator=( ForwardRange2& r )
  75. {
  76. base::operator=( r );
  77. return *this;
  78. }
  79. template< class ForwardRange2 >
  80. sub_range& operator=( const ForwardRange2& r )
  81. {
  82. base::operator=( r );
  83. return *this;
  84. }
  85. sub_range& operator=( const sub_range& r )
  86. {
  87. base::operator=( static_cast<const base&>(r) );
  88. return *this;
  89. }
  90. public:
  91. iterator begin() { return base::begin(); }
  92. const_iterator begin() const { return base::begin(); }
  93. iterator end() { return base::end(); }
  94. const_iterator end() const { return base::end(); }
  95. difference_type size() const { return base::size(); }
  96. public: // convenience
  97. reference front()
  98. {
  99. return base::front();
  100. }
  101. const_reference front() const
  102. {
  103. return base::front();
  104. }
  105. reference back()
  106. {
  107. return base::back();
  108. }
  109. const_reference back() const
  110. {
  111. return base::back();
  112. }
  113. reference operator[]( difference_type sz )
  114. {
  115. return base::operator[](sz);
  116. }
  117. const_reference operator[]( difference_type sz ) const
  118. {
  119. return base::operator[](sz);
  120. }
  121. };
  122. template< class ForwardRange, class ForwardRange2 >
  123. inline bool operator==( const sub_range<ForwardRange>& l,
  124. const sub_range<ForwardRange2>& r )
  125. {
  126. return iterator_range_detail::equal( l, r );
  127. }
  128. template< class ForwardRange, class ForwardRange2 >
  129. inline bool operator!=( const sub_range<ForwardRange>& l,
  130. const sub_range<ForwardRange2>& r )
  131. {
  132. return !iterator_range_detail::equal( l, r );
  133. }
  134. template< class ForwardRange, class ForwardRange2 >
  135. inline bool operator<( const sub_range<ForwardRange>& l,
  136. const sub_range<ForwardRange2>& r )
  137. {
  138. return iterator_range_detail::less_than( l, r );
  139. }
  140. } // namespace 'boost'
  141. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
  142. #pragma warning( pop )
  143. #endif
  144. #endif