File indexing completed on 2025-10-30 08:34:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_RANGE_SUB_RANGE_HPP
0013 #define BOOST_RANGE_SUB_RANGE_HPP
0014
0015 #include <boost/detail/workaround.hpp>
0016
0017 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
0018 #pragma warning( push )
0019 #pragma warning( disable : 4996 )
0020 #endif
0021
0022 #include <boost/range/config.hpp>
0023 #include <boost/range/iterator_range.hpp>
0024 #include <boost/range/value_type.hpp>
0025 #include <boost/range/size_type.hpp>
0026 #include <boost/range/difference_type.hpp>
0027 #include <boost/range/reference.hpp>
0028 #include <boost/range/algorithm/equal.hpp>
0029 #include <boost/assert.hpp>
0030 #include <boost/mpl/eval_if.hpp>
0031 #include <boost/mpl/identity.hpp>
0032 #include <boost/type_traits/is_reference.hpp>
0033 #include <boost/type_traits/remove_reference.hpp>
0034
0035 namespace boost
0036 {
0037 namespace range_detail
0038 {
0039
0040 template<class ForwardRange, class TraversalTag>
0041 class sub_range_base
0042 : public iterator_range<
0043 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
0044 >
0045 {
0046 typedef iterator_range<
0047 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
0048 > base;
0049
0050 protected:
0051 typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
0052
0053 public:
0054 typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type;
0055 typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator;
0056 typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type const_iterator;
0057 typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type difference_type;
0058 typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type size_type;
0059 typedef BOOST_DEDUCED_TYPENAME range_reference<ForwardRange>::type reference;
0060 typedef BOOST_DEDUCED_TYPENAME range_reference<const ForwardRange>::type const_reference;
0061
0062 sub_range_base()
0063 {
0064 }
0065
0066 template<class Iterator>
0067 sub_range_base(Iterator first, Iterator last)
0068 : base(first, last)
0069 {
0070 }
0071
0072 reference front()
0073 {
0074 return base::front();
0075 }
0076
0077 const_reference front() const
0078 {
0079 return base::front();
0080 }
0081 };
0082
0083 template<class ForwardRange>
0084 class sub_range_base<ForwardRange, bidirectional_traversal_tag>
0085 : public sub_range_base<ForwardRange, forward_traversal_tag>
0086 {
0087 typedef sub_range_base<ForwardRange, forward_traversal_tag> base;
0088 public:
0089 sub_range_base()
0090 {
0091 }
0092
0093 template<class Iterator>
0094 sub_range_base(Iterator first, Iterator last)
0095 : base(first, last)
0096 {
0097 }
0098
0099 BOOST_DEDUCED_TYPENAME base::reference back()
0100 {
0101 return base::back();
0102 }
0103
0104 BOOST_DEDUCED_TYPENAME base::const_reference back() const
0105 {
0106 return base::back();
0107 }
0108 };
0109
0110 template<class ForwardRange>
0111 class sub_range_base<ForwardRange, random_access_traversal_tag>
0112 : public sub_range_base<ForwardRange, bidirectional_traversal_tag>
0113 {
0114 typedef sub_range_base<ForwardRange, bidirectional_traversal_tag> base;
0115
0116 public:
0117 sub_range_base()
0118 {
0119 }
0120
0121 template<class Iterator>
0122 sub_range_base(Iterator first, Iterator last)
0123 : base(first, last)
0124 {
0125 }
0126
0127 BOOST_DEDUCED_TYPENAME base::reference
0128 operator[](BOOST_DEDUCED_TYPENAME base::difference_type n)
0129 {
0130 return this->begin()[n];
0131 }
0132
0133 BOOST_DEDUCED_TYPENAME base::const_reference
0134 operator[](BOOST_DEDUCED_TYPENAME base::difference_type n) const
0135 {
0136 return this->begin()[n];
0137 }
0138 };
0139
0140 }
0141
0142 template<class ForwardRange>
0143 class sub_range
0144 : public range_detail::sub_range_base<
0145 ForwardRange,
0146 BOOST_DEDUCED_TYPENAME iterator_traversal<
0147 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
0148 >::type
0149 >
0150 {
0151 typedef BOOST_DEDUCED_TYPENAME range_iterator<
0152 ForwardRange
0153 >::type iterator_t;
0154
0155 typedef range_detail::sub_range_base<
0156 ForwardRange,
0157 BOOST_DEDUCED_TYPENAME iterator_traversal<
0158 BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
0159 >::type
0160 > base;
0161
0162 typedef BOOST_DEDUCED_TYPENAME base::impl impl;
0163
0164 protected:
0165 typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
0166
0167 private:
0168 template<class Source>
0169 struct is_compatible_range
0170 : is_convertible<
0171 BOOST_DEDUCED_TYPENAME mpl::eval_if<
0172 has_range_iterator<Source>,
0173 range_iterator<Source>,
0174 mpl::identity<void>
0175 >::type,
0176 BOOST_DEDUCED_TYPENAME base::iterator
0177 >
0178 {
0179 };
0180
0181 public:
0182 sub_range()
0183 { }
0184
0185 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
0186 sub_range(const sub_range& r)
0187 : base(impl::adl_begin(const_cast<base&>(static_cast<const base&>(r))),
0188 impl::adl_end(const_cast<base&>(static_cast<const base&>(r))))
0189 { }
0190 #endif
0191
0192 template< class ForwardRange2 >
0193 sub_range(
0194 ForwardRange2& r,
0195 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
0196 is_compatible_range<ForwardRange2>
0197 >::type* = 0
0198 )
0199 : base(impl::adl_begin(r), impl::adl_end(r))
0200 {
0201 }
0202
0203 template< class ForwardRange2 >
0204 sub_range(
0205 const ForwardRange2& r,
0206 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
0207 is_compatible_range<const ForwardRange2>
0208 >::type* = 0
0209 )
0210 : base(impl::adl_begin(r), impl::adl_end(r))
0211 {
0212 }
0213
0214 BOOST_DEDUCED_TYPENAME base::const_iterator begin() const
0215 {
0216 return base::begin();
0217 }
0218
0219 BOOST_DEDUCED_TYPENAME base::iterator begin()
0220 {
0221 return base::begin();
0222 }
0223
0224 BOOST_DEDUCED_TYPENAME base::const_iterator end() const
0225 {
0226 return base::end();
0227 }
0228
0229 BOOST_DEDUCED_TYPENAME base::iterator end()
0230 {
0231 return base::end();
0232 }
0233
0234 template< class Iter >
0235 sub_range( Iter first, Iter last ) :
0236 base( first, last )
0237 { }
0238
0239 template<class ForwardRange2>
0240 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
0241 is_compatible_range<ForwardRange2>,
0242 sub_range&
0243 >::type
0244 operator=(ForwardRange2& r)
0245 {
0246 iterator_range_::operator=( r );
0247 return *this;
0248 }
0249
0250 template<class ForwardRange2>
0251 BOOST_DEDUCED_TYPENAME ::boost::enable_if<
0252 is_compatible_range<const ForwardRange2>,
0253 sub_range&
0254 >::type
0255 operator=( const ForwardRange2& r )
0256 {
0257 iterator_range_::operator=( r );
0258 return *this;
0259 }
0260
0261 sub_range& operator=( const sub_range& r )
0262 {
0263 iterator_range_::operator=( static_cast<const iterator_range_&>(r) );
0264 return *this;
0265 }
0266
0267 sub_range& advance_begin(
0268 BOOST_DEDUCED_TYPENAME base::difference_type n)
0269 {
0270 std::advance(this->m_Begin, n);
0271 return *this;
0272 }
0273
0274 sub_range& advance_end(
0275 BOOST_DEDUCED_TYPENAME base::difference_type n)
0276 {
0277 std::advance(this->m_End, n);
0278 return *this;
0279 }
0280 };
0281
0282 }
0283
0284 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
0285 #pragma warning( pop )
0286 #endif
0287
0288 #endif
0289