sub_range.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. // Boost.Range library
  2. //
  3. // Copyright Neil Groves 2009.
  4. // Copyright Thorsten Ottosen 2003-2004. Use, modification and
  5. // distribution is subject to the Boost Software License, Version
  6. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // For more information, see http://www.boost.org/libs/range/
  10. //
  11. #ifndef BOOST_RANGE_SUB_RANGE_HPP
  12. #define BOOST_RANGE_SUB_RANGE_HPP
  13. #include <boost/detail/workaround.hpp>
  14. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
  15. #pragma warning( push )
  16. #pragma warning( disable : 4996 )
  17. #endif
  18. #include <boost/range/config.hpp>
  19. #include <boost/range/iterator_range.hpp>
  20. #include <boost/range/value_type.hpp>
  21. #include <boost/range/size_type.hpp>
  22. #include <boost/range/difference_type.hpp>
  23. #include <boost/range/reference.hpp>
  24. #include <boost/range/algorithm/equal.hpp>
  25. #include <boost/assert.hpp>
  26. #include <boost/type_traits/is_reference.hpp>
  27. #include <boost/type_traits/remove_reference.hpp>
  28. namespace boost
  29. {
  30. namespace range_detail
  31. {
  32. template<class ForwardRange, class TraversalTag>
  33. class sub_range_base
  34. : public iterator_range<
  35. BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
  36. >
  37. {
  38. typedef iterator_range<
  39. BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
  40. > base;
  41. protected:
  42. typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
  43. public:
  44. typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type;
  45. typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator;
  46. typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type const_iterator;
  47. typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type difference_type;
  48. typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type size_type;
  49. typedef BOOST_DEDUCED_TYPENAME range_reference<ForwardRange>::type reference;
  50. typedef BOOST_DEDUCED_TYPENAME range_reference<const ForwardRange>::type const_reference;
  51. sub_range_base()
  52. {
  53. }
  54. template<class Iterator>
  55. sub_range_base(Iterator first, Iterator last)
  56. : base(first, last)
  57. {
  58. }
  59. reference front()
  60. {
  61. return base::front();
  62. }
  63. const_reference front() const
  64. {
  65. return base::front();
  66. }
  67. };
  68. template<class ForwardRange>
  69. class sub_range_base<ForwardRange, bidirectional_traversal_tag>
  70. : public sub_range_base<ForwardRange, forward_traversal_tag>
  71. {
  72. typedef sub_range_base<ForwardRange, forward_traversal_tag> base;
  73. public:
  74. sub_range_base()
  75. {
  76. }
  77. template<class Iterator>
  78. sub_range_base(Iterator first, Iterator last)
  79. : base(first, last)
  80. {
  81. }
  82. BOOST_DEDUCED_TYPENAME base::reference back()
  83. {
  84. return base::back();
  85. }
  86. BOOST_DEDUCED_TYPENAME base::const_reference back() const
  87. {
  88. return base::back();
  89. }
  90. };
  91. template<class ForwardRange>
  92. class sub_range_base<ForwardRange, random_access_traversal_tag>
  93. : public sub_range_base<ForwardRange, bidirectional_traversal_tag>
  94. {
  95. typedef sub_range_base<ForwardRange, bidirectional_traversal_tag> base;
  96. public:
  97. sub_range_base()
  98. {
  99. }
  100. template<class Iterator>
  101. sub_range_base(Iterator first, Iterator last)
  102. : base(first, last)
  103. {
  104. }
  105. BOOST_DEDUCED_TYPENAME base::reference
  106. operator[](BOOST_DEDUCED_TYPENAME base::difference_type n)
  107. {
  108. return this->begin()[n];
  109. }
  110. BOOST_DEDUCED_TYPENAME base::const_reference
  111. operator[](BOOST_DEDUCED_TYPENAME base::difference_type n) const
  112. {
  113. return this->begin()[n];
  114. }
  115. };
  116. } // namespace range_detail
  117. template<class ForwardRange>
  118. class sub_range
  119. : public range_detail::sub_range_base<
  120. ForwardRange,
  121. BOOST_DEDUCED_TYPENAME iterator_traversal<
  122. BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
  123. >::type
  124. >
  125. {
  126. typedef BOOST_DEDUCED_TYPENAME range_iterator<
  127. ForwardRange
  128. >::type iterator_t;
  129. typedef range_detail::sub_range_base<
  130. ForwardRange,
  131. BOOST_DEDUCED_TYPENAME iterator_traversal<
  132. BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
  133. >::type
  134. > base;
  135. typedef BOOST_DEDUCED_TYPENAME base::impl impl;
  136. protected:
  137. typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
  138. private:
  139. template<class Source>
  140. struct is_compatible_range
  141. : is_convertible<
  142. BOOST_DEDUCED_TYPENAME mpl::eval_if<
  143. has_range_iterator<Source>,
  144. range_iterator<Source>,
  145. mpl::identity<void>
  146. >::type,
  147. BOOST_DEDUCED_TYPENAME base::iterator
  148. >
  149. {
  150. };
  151. public:
  152. sub_range()
  153. { }
  154. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
  155. sub_range(const sub_range& r)
  156. : base(impl::adl_begin(const_cast<base&>(static_cast<const base&>(r))),
  157. impl::adl_end(const_cast<base&>(static_cast<const base&>(r))))
  158. { }
  159. #endif
  160. template< class ForwardRange2 >
  161. sub_range(
  162. ForwardRange2& r,
  163. BOOST_DEDUCED_TYPENAME ::boost::enable_if<
  164. is_compatible_range<ForwardRange2>
  165. >::type* = 0
  166. )
  167. : base(impl::adl_begin(r), impl::adl_end(r))
  168. {
  169. }
  170. template< class ForwardRange2 >
  171. sub_range(
  172. const ForwardRange2& r,
  173. BOOST_DEDUCED_TYPENAME ::boost::enable_if<
  174. is_compatible_range<const ForwardRange2>
  175. >::type* = 0
  176. )
  177. : base(impl::adl_begin(r), impl::adl_end(r))
  178. {
  179. }
  180. BOOST_DEDUCED_TYPENAME base::const_iterator begin() const
  181. {
  182. return base::begin();
  183. }
  184. BOOST_DEDUCED_TYPENAME base::iterator begin()
  185. {
  186. return base::begin();
  187. }
  188. BOOST_DEDUCED_TYPENAME base::const_iterator end() const
  189. {
  190. return base::end();
  191. }
  192. BOOST_DEDUCED_TYPENAME base::iterator end()
  193. {
  194. return base::end();
  195. }
  196. template< class Iter >
  197. sub_range( Iter first, Iter last ) :
  198. base( first, last )
  199. { }
  200. template<class ForwardRange2>
  201. BOOST_DEDUCED_TYPENAME ::boost::enable_if<
  202. is_compatible_range<ForwardRange2>,
  203. sub_range&
  204. >::type
  205. operator=(ForwardRange2& r)
  206. {
  207. iterator_range_::operator=( r );
  208. return *this;
  209. }
  210. template<class ForwardRange2>
  211. BOOST_DEDUCED_TYPENAME ::boost::enable_if<
  212. is_compatible_range<const ForwardRange2>,
  213. sub_range&
  214. >::type
  215. operator=( const ForwardRange2& r )
  216. {
  217. iterator_range_::operator=( r );
  218. return *this;
  219. }
  220. sub_range& operator=( const sub_range& r )
  221. {
  222. iterator_range_::operator=( static_cast<const iterator_range_&>(r) );
  223. return *this;
  224. }
  225. sub_range& advance_begin(
  226. BOOST_DEDUCED_TYPENAME base::difference_type n)
  227. {
  228. std::advance(this->m_Begin, n);
  229. return *this;
  230. }
  231. sub_range& advance_end(
  232. BOOST_DEDUCED_TYPENAME base::difference_type n)
  233. {
  234. std::advance(this->m_End, n);
  235. return *this;
  236. }
  237. };
  238. } // namespace 'boost'
  239. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
  240. #pragma warning( pop )
  241. #endif
  242. #endif