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