sub_range.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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/mpl/eval_if.hpp>
  27. #include <boost/mpl/identity.hpp>
  28. #include <boost/type_traits/is_reference.hpp>
  29. #include <boost/type_traits/remove_reference.hpp>
  30. namespace boost
  31. {
  32. namespace range_detail
  33. {
  34. template<class ForwardRange, class TraversalTag>
  35. class sub_range_base
  36. : public iterator_range<
  37. BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
  38. >
  39. {
  40. typedef iterator_range<
  41. BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
  42. > base;
  43. protected:
  44. typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
  45. public:
  46. typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type;
  47. typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator;
  48. typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type const_iterator;
  49. typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type difference_type;
  50. typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type size_type;
  51. typedef BOOST_DEDUCED_TYPENAME range_reference<ForwardRange>::type reference;
  52. typedef BOOST_DEDUCED_TYPENAME range_reference<const ForwardRange>::type const_reference;
  53. sub_range_base()
  54. {
  55. }
  56. template<class Iterator>
  57. sub_range_base(Iterator first, Iterator last)
  58. : base(first, last)
  59. {
  60. }
  61. reference front()
  62. {
  63. return base::front();
  64. }
  65. const_reference front() const
  66. {
  67. return base::front();
  68. }
  69. };
  70. template<class ForwardRange>
  71. class sub_range_base<ForwardRange, bidirectional_traversal_tag>
  72. : public sub_range_base<ForwardRange, forward_traversal_tag>
  73. {
  74. typedef sub_range_base<ForwardRange, forward_traversal_tag> base;
  75. public:
  76. sub_range_base()
  77. {
  78. }
  79. template<class Iterator>
  80. sub_range_base(Iterator first, Iterator last)
  81. : base(first, last)
  82. {
  83. }
  84. BOOST_DEDUCED_TYPENAME base::reference back()
  85. {
  86. return base::back();
  87. }
  88. BOOST_DEDUCED_TYPENAME base::const_reference back() const
  89. {
  90. return base::back();
  91. }
  92. };
  93. template<class ForwardRange>
  94. class sub_range_base<ForwardRange, random_access_traversal_tag>
  95. : public sub_range_base<ForwardRange, bidirectional_traversal_tag>
  96. {
  97. typedef sub_range_base<ForwardRange, bidirectional_traversal_tag> base;
  98. public:
  99. sub_range_base()
  100. {
  101. }
  102. template<class Iterator>
  103. sub_range_base(Iterator first, Iterator last)
  104. : base(first, last)
  105. {
  106. }
  107. BOOST_DEDUCED_TYPENAME base::reference
  108. operator[](BOOST_DEDUCED_TYPENAME base::difference_type n)
  109. {
  110. return this->begin()[n];
  111. }
  112. BOOST_DEDUCED_TYPENAME base::const_reference
  113. operator[](BOOST_DEDUCED_TYPENAME base::difference_type n) const
  114. {
  115. return this->begin()[n];
  116. }
  117. };
  118. } // namespace range_detail
  119. template<class ForwardRange>
  120. class sub_range
  121. : public range_detail::sub_range_base<
  122. ForwardRange,
  123. BOOST_DEDUCED_TYPENAME iterator_traversal<
  124. BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
  125. >::type
  126. >
  127. {
  128. typedef BOOST_DEDUCED_TYPENAME range_iterator<
  129. ForwardRange
  130. >::type iterator_t;
  131. typedef range_detail::sub_range_base<
  132. ForwardRange,
  133. BOOST_DEDUCED_TYPENAME iterator_traversal<
  134. BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
  135. >::type
  136. > base;
  137. typedef BOOST_DEDUCED_TYPENAME base::impl impl;
  138. protected:
  139. typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
  140. private:
  141. template<class Source>
  142. struct is_compatible_range
  143. : is_convertible<
  144. BOOST_DEDUCED_TYPENAME mpl::eval_if<
  145. has_range_iterator<Source>,
  146. range_iterator<Source>,
  147. mpl::identity<void>
  148. >::type,
  149. BOOST_DEDUCED_TYPENAME base::iterator
  150. >
  151. {
  152. };
  153. public:
  154. sub_range()
  155. { }
  156. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
  157. sub_range(const sub_range& r)
  158. : base(impl::adl_begin(const_cast<base&>(static_cast<const base&>(r))),
  159. impl::adl_end(const_cast<base&>(static_cast<const base&>(r))))
  160. { }
  161. #endif
  162. template< class ForwardRange2 >
  163. sub_range(
  164. ForwardRange2& r,
  165. BOOST_DEDUCED_TYPENAME ::boost::enable_if<
  166. is_compatible_range<ForwardRange2>
  167. >::type* = 0
  168. )
  169. : base(impl::adl_begin(r), impl::adl_end(r))
  170. {
  171. }
  172. template< class ForwardRange2 >
  173. sub_range(
  174. const ForwardRange2& r,
  175. BOOST_DEDUCED_TYPENAME ::boost::enable_if<
  176. is_compatible_range<const ForwardRange2>
  177. >::type* = 0
  178. )
  179. : base(impl::adl_begin(r), impl::adl_end(r))
  180. {
  181. }
  182. BOOST_DEDUCED_TYPENAME base::const_iterator begin() const
  183. {
  184. return base::begin();
  185. }
  186. BOOST_DEDUCED_TYPENAME base::iterator begin()
  187. {
  188. return base::begin();
  189. }
  190. BOOST_DEDUCED_TYPENAME base::const_iterator end() const
  191. {
  192. return base::end();
  193. }
  194. BOOST_DEDUCED_TYPENAME base::iterator end()
  195. {
  196. return base::end();
  197. }
  198. template< class Iter >
  199. sub_range( Iter first, Iter last ) :
  200. base( first, last )
  201. { }
  202. template<class ForwardRange2>
  203. BOOST_DEDUCED_TYPENAME ::boost::enable_if<
  204. is_compatible_range<ForwardRange2>,
  205. sub_range&
  206. >::type
  207. operator=(ForwardRange2& r)
  208. {
  209. iterator_range_::operator=( r );
  210. return *this;
  211. }
  212. template<class ForwardRange2>
  213. BOOST_DEDUCED_TYPENAME ::boost::enable_if<
  214. is_compatible_range<const ForwardRange2>,
  215. sub_range&
  216. >::type
  217. operator=( const ForwardRange2& r )
  218. {
  219. iterator_range_::operator=( r );
  220. return *this;
  221. }
  222. sub_range& operator=( const sub_range& r )
  223. {
  224. iterator_range_::operator=( static_cast<const iterator_range_&>(r) );
  225. return *this;
  226. }
  227. sub_range& advance_begin(
  228. BOOST_DEDUCED_TYPENAME base::difference_type n)
  229. {
  230. std::advance(this->m_Begin, n);
  231. return *this;
  232. }
  233. sub_range& advance_end(
  234. BOOST_DEDUCED_TYPENAME base::difference_type n)
  235. {
  236. std::advance(this->m_End, n);
  237. return *this;
  238. }
  239. };
  240. } // namespace 'boost'
  241. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
  242. #pragma warning( pop )
  243. #endif
  244. #endif