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)
9 // For more information, see http://www.boost.org/libs/range/
12 #ifndef BOOST_RANGE_SUB_RANGE_HPP
13 #define BOOST_RANGE_SUB_RANGE_HPP
15 #include <boost/detail/workaround.hpp>
17 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
18 #pragma warning( push )
19 #pragma warning( disable : 4996 )
22 #include <boost/range/config.hpp>
23 #include <boost/range/iterator_range.hpp>
24 #include <boost/range/value_type.hpp>
25 #include <boost/range/size_type.hpp>
26 #include <boost/range/difference_type.hpp>
27 #include <boost/range/reference.hpp>
28 #include <boost/range/algorithm/equal.hpp>
29 #include <boost/assert.hpp>
30 #include <boost/type_traits/is_reference.hpp>
31 #include <boost/type_traits/remove_reference.hpp>
35 namespace range_detail
38 template<class ForwardRange, class TraversalTag>
40 : public iterator_range<
41 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
44 typedef iterator_range<
45 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
49 typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
52 typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type;
53 typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator;
54 typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type const_iterator;
55 typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type difference_type;
56 typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type size_type;
57 typedef BOOST_DEDUCED_TYPENAME range_reference<ForwardRange>::type reference;
58 typedef BOOST_DEDUCED_TYPENAME range_reference<const ForwardRange>::type const_reference;
64 template<class Iterator>
65 sub_range_base(Iterator first, Iterator last)
75 const_reference front() const
81 template<class ForwardRange>
82 class sub_range_base<ForwardRange, bidirectional_traversal_tag>
83 : public sub_range_base<ForwardRange, forward_traversal_tag>
85 typedef sub_range_base<ForwardRange, forward_traversal_tag> base;
91 template<class Iterator>
92 sub_range_base(Iterator first, Iterator last)
97 BOOST_DEDUCED_TYPENAME base::reference back()
102 BOOST_DEDUCED_TYPENAME base::const_reference back() const
108 template<class ForwardRange>
109 class sub_range_base<ForwardRange, random_access_traversal_tag>
110 : public sub_range_base<ForwardRange, bidirectional_traversal_tag>
112 typedef sub_range_base<ForwardRange, bidirectional_traversal_tag> base;
119 template<class Iterator>
120 sub_range_base(Iterator first, Iterator last)
125 BOOST_DEDUCED_TYPENAME base::reference
126 operator[](BOOST_DEDUCED_TYPENAME base::difference_type n)
128 return this->begin()[n];
131 BOOST_DEDUCED_TYPENAME base::const_reference
132 operator[](BOOST_DEDUCED_TYPENAME base::difference_type n) const
134 return this->begin()[n];
138 } // namespace range_detail
140 template<class ForwardRange>
142 : public range_detail::sub_range_base<
144 BOOST_DEDUCED_TYPENAME iterator_traversal<
145 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
149 typedef BOOST_DEDUCED_TYPENAME range_iterator<
153 typedef range_detail::sub_range_base<
155 BOOST_DEDUCED_TYPENAME iterator_traversal<
156 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
160 typedef BOOST_DEDUCED_TYPENAME base::impl impl;
163 typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
166 template<class Source>
167 struct is_compatible_range
169 BOOST_DEDUCED_TYPENAME mpl::eval_if<
170 has_range_iterator<Source>,
171 range_iterator<Source>,
174 BOOST_DEDUCED_TYPENAME base::iterator
183 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
184 sub_range(const sub_range& r)
185 : base(impl::adl_begin(const_cast<base&>(static_cast<const base&>(r))),
186 impl::adl_end(const_cast<base&>(static_cast<const base&>(r))))
190 template< class ForwardRange2 >
193 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
194 is_compatible_range<ForwardRange2>
197 : base(impl::adl_begin(r), impl::adl_end(r))
201 template< class ForwardRange2 >
203 const ForwardRange2& r,
204 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
205 is_compatible_range<const ForwardRange2>
208 : base(impl::adl_begin(r), impl::adl_end(r))
212 BOOST_DEDUCED_TYPENAME base::const_iterator begin() const
214 return base::begin();
217 BOOST_DEDUCED_TYPENAME base::iterator begin()
219 return base::begin();
222 BOOST_DEDUCED_TYPENAME base::const_iterator end() const
227 BOOST_DEDUCED_TYPENAME base::iterator end()
232 template< class Iter >
233 sub_range( Iter first, Iter last ) :
237 template<class ForwardRange2>
238 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
239 is_compatible_range<ForwardRange2>,
242 operator=(ForwardRange2& r)
244 iterator_range_::operator=( r );
248 template<class ForwardRange2>
249 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
250 is_compatible_range<const ForwardRange2>,
253 operator=( const ForwardRange2& r )
255 iterator_range_::operator=( r );
259 sub_range& operator=( const sub_range& r )
261 iterator_range_::operator=( static_cast<const iterator_range_&>(r) );
265 sub_range& advance_begin(
266 BOOST_DEDUCED_TYPENAME base::difference_type n)
268 std::advance(this->m_Begin, n);
272 sub_range& advance_end(
273 BOOST_DEDUCED_TYPENAME base::difference_type n)
275 std::advance(this->m_End, n);
280 } // namespace 'boost'
282 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
283 #pragma warning( pop )