// Boost.Range library // // Copyright Neil Groves 2009. // Copyright Thorsten Ottosen 2003-2004. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // For more information, see http://www.boost.org/libs/range/ // #ifndef BOOST_RANGE_SUB_RANGE_HPP #define BOOST_RANGE_SUB_RANGE_HPP #include #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) #pragma warning( push ) #pragma warning( disable : 4996 ) #endif #include #include #include #include #include #include #include #include #include #include namespace boost { namespace range_detail { template class sub_range_base : public iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > { typedef iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > base; protected: typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_; public: typedef BOOST_DEDUCED_TYPENAME range_value::type value_type; typedef BOOST_DEDUCED_TYPENAME range_iterator::type iterator; typedef BOOST_DEDUCED_TYPENAME range_iterator::type const_iterator; typedef BOOST_DEDUCED_TYPENAME range_difference::type difference_type; typedef BOOST_DEDUCED_TYPENAME range_size::type size_type; typedef BOOST_DEDUCED_TYPENAME range_reference::type reference; typedef BOOST_DEDUCED_TYPENAME range_reference::type const_reference; sub_range_base() { } template sub_range_base(Iterator first, Iterator last) : base(first, last) { } reference front() { return base::front(); } const_reference front() const { return base::front(); } }; template class sub_range_base : public sub_range_base { typedef sub_range_base base; public: sub_range_base() { } template sub_range_base(Iterator first, Iterator last) : base(first, last) { } BOOST_DEDUCED_TYPENAME base::reference back() { return base::back(); } BOOST_DEDUCED_TYPENAME base::const_reference back() const { return base::back(); } }; template class sub_range_base : public sub_range_base { typedef sub_range_base base; public: sub_range_base() { } template sub_range_base(Iterator first, Iterator last) : base(first, last) { } BOOST_DEDUCED_TYPENAME base::reference operator[](BOOST_DEDUCED_TYPENAME base::difference_type n) { return this->begin()[n]; } BOOST_DEDUCED_TYPENAME base::const_reference operator[](BOOST_DEDUCED_TYPENAME base::difference_type n) const { return this->begin()[n]; } }; } // namespace range_detail template class sub_range : public range_detail::sub_range_base< ForwardRange, BOOST_DEDUCED_TYPENAME iterator_traversal< BOOST_DEDUCED_TYPENAME range_iterator::type >::type > { typedef BOOST_DEDUCED_TYPENAME range_iterator< ForwardRange >::type iterator_t; typedef range_detail::sub_range_base< ForwardRange, BOOST_DEDUCED_TYPENAME iterator_traversal< BOOST_DEDUCED_TYPENAME range_iterator::type >::type > base; typedef BOOST_DEDUCED_TYPENAME base::impl impl; protected: typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_; private: template struct is_compatible_range : is_convertible< BOOST_DEDUCED_TYPENAME mpl::eval_if< has_range_iterator, range_iterator, mpl::identity >::type, BOOST_DEDUCED_TYPENAME base::iterator > { }; public: sub_range() { } #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) ) sub_range(const sub_range& r) : base(impl::adl_begin(static_cast(r)), impl::adl_end(static_cast(r))) { } #endif template< class ForwardRange2 > sub_range( ForwardRange2& r, BOOST_DEDUCED_TYPENAME ::boost::enable_if< is_compatible_range >::type* = 0 ) : base(impl::adl_begin(r), impl::adl_end(r)) { } template< class ForwardRange2 > sub_range( const ForwardRange2& r, BOOST_DEDUCED_TYPENAME ::boost::enable_if< is_compatible_range >::type* = 0 ) : base(impl::adl_begin(r), impl::adl_end(r)) { } BOOST_DEDUCED_TYPENAME base::const_iterator begin() const { return base::begin(); } BOOST_DEDUCED_TYPENAME base::iterator begin() { return base::begin(); } BOOST_DEDUCED_TYPENAME base::const_iterator end() const { return base::end(); } BOOST_DEDUCED_TYPENAME base::iterator end() { return base::end(); } template< class Iter > sub_range( Iter first, Iter last ) : base( first, last ) { } template BOOST_DEDUCED_TYPENAME ::boost::enable_if< is_compatible_range, sub_range& >::type operator=(ForwardRange2& r) { iterator_range_::operator=( r ); return *this; } template BOOST_DEDUCED_TYPENAME ::boost::enable_if< is_compatible_range, sub_range& >::type operator=( const ForwardRange2& r ) { iterator_range_::operator=( r ); return *this; } sub_range& operator=( const sub_range& r ) { iterator_range_::operator=( static_cast(r) ); return *this; } sub_range& advance_begin( BOOST_DEDUCED_TYPENAME base::difference_type n) { std::advance(this->m_Begin, n); return *this; } sub_range& advance_end( BOOST_DEDUCED_TYPENAME base::difference_type n) { std::advance(this->m_End, n); return *this; } }; } // namespace 'boost' #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) #pragma warning( pop ) #endif #endif