// 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 <boost/detail/workaround.hpp> #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) #pragma warning( push ) #pragma warning( disable : 4996 ) #endif #include <boost/range/config.hpp> #include <boost/range/iterator_range.hpp> #include <boost/range/value_type.hpp> #include <boost/range/size_type.hpp> #include <boost/range/difference_type.hpp> #include <boost/range/reference.hpp> #include <boost/range/algorithm/equal.hpp> #include <boost/assert.hpp> #include <boost/type_traits/is_reference.hpp> #include <boost/type_traits/remove_reference.hpp> namespace boost { namespace range_detail { template<class ForwardRange, class TraversalTag> class sub_range_base : public iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type > { typedef iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type > base; protected: typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_; public: typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type; typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator; typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type const_iterator; typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type difference_type; typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type size_type; typedef BOOST_DEDUCED_TYPENAME range_reference<ForwardRange>::type reference; typedef BOOST_DEDUCED_TYPENAME range_reference<const ForwardRange>::type const_reference; sub_range_base() { } template<class Iterator> sub_range_base(Iterator first, Iterator last) : base(first, last) { } reference front() { return base::front(); } const_reference front() const { return base::front(); } }; template<class ForwardRange> class sub_range_base<ForwardRange, bidirectional_traversal_tag> : public sub_range_base<ForwardRange, forward_traversal_tag> { typedef sub_range_base<ForwardRange, forward_traversal_tag> base; public: sub_range_base() { } template<class Iterator> 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 ForwardRange> class sub_range_base<ForwardRange, random_access_traversal_tag> : public sub_range_base<ForwardRange, bidirectional_traversal_tag> { typedef sub_range_base<ForwardRange, bidirectional_traversal_tag> base; public: sub_range_base() { } template<class Iterator> 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 ForwardRange> class sub_range : public range_detail::sub_range_base< ForwardRange, BOOST_DEDUCED_TYPENAME iterator_traversal< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::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<ForwardRange>::type >::type > base; typedef BOOST_DEDUCED_TYPENAME base::impl impl; protected: typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_; private: template<class Source> struct is_compatible_range : is_convertible< BOOST_DEDUCED_TYPENAME mpl::eval_if< has_range_iterator<Source>, range_iterator<Source>, mpl::identity<void> >::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(const_cast<base&>(static_cast<const base&>(r))), impl::adl_end(const_cast<base&>(static_cast<const base&>(r)))) { } #endif template< class ForwardRange2 > sub_range( ForwardRange2& r, BOOST_DEDUCED_TYPENAME ::boost::enable_if< is_compatible_range<ForwardRange2> >::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<const ForwardRange2> >::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<class ForwardRange2> BOOST_DEDUCED_TYPENAME ::boost::enable_if< is_compatible_range<ForwardRange2>, sub_range& >::type operator=(ForwardRange2& r) { iterator_range_::operator=( r ); return *this; } template<class ForwardRange2> BOOST_DEDUCED_TYPENAME ::boost::enable_if< is_compatible_range<const ForwardRange2>, 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<const iterator_range_&>(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