summaryrefslogtreecommitdiff
path: root/boost/range/sub_range.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/range/sub_range.hpp')
-rw-r--r--boost/range/sub_range.hpp311
1 files changed, 208 insertions, 103 deletions
diff --git a/boost/range/sub_range.hpp b/boost/range/sub_range.hpp
index 0b000861a3..8d5d168ce9 100644
--- a/boost/range/sub_range.hpp
+++ b/boost/range/sub_range.hpp
@@ -24,6 +24,7 @@
#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>
@@ -31,147 +32,251 @@
namespace boost
{
-
- template< class ForwardRange >
- class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
+ namespace range_detail
{
- typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t;
- typedef iterator_range< iterator_t > base;
+
+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;
- 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 base::reference reference;
-
- public: // for return value of front/back
- typedef BOOST_DEDUCED_TYPENAME
- boost::mpl::if_< boost::is_reference<reference>,
- const BOOST_DEDUCED_TYPENAME boost::remove_reference<reference>::type&,
- reference >::type const_reference;
+
+ 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() : base()
+ sub_range()
{ }
-
+
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
- sub_range( const sub_range& r )
- : base( static_cast<const base&>( r ) )
+ sub_range(const sub_range& r)
+ : base(impl::adl_begin(static_cast<const base&>(r)),
+ impl::adl_end(static_cast<const base&>(r)))
{ }
#endif
template< class ForwardRange2 >
- sub_range( ForwardRange2& r ) :
-
-#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
- base( impl::adl_begin( r ), impl::adl_end( r ) )
-#else
- base( r )
-#endif
- { }
-
- template< class ForwardRange2 >
- sub_range( const ForwardRange2& r ) :
-
-#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
- base( impl::adl_begin( r ), impl::adl_end( r ) )
-#else
- base( r )
-#endif
- { }
-
- template< class Iter >
- sub_range( Iter first, Iter last ) :
- base( first, last )
- { }
-
- template< class ForwardRange2 >
- sub_range& operator=( ForwardRange2& r )
+ 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))
{
- base::operator=( r );
- return *this;
}
template< class ForwardRange2 >
- sub_range& operator=( const ForwardRange2& r )
+ 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))
{
- base::operator=( r );
- return *this;
- }
+ }
- sub_range& operator=( const sub_range& r )
+ BOOST_DEDUCED_TYPENAME base::const_iterator begin() const
{
- base::operator=( static_cast<const base&>(r) );
- return *this;
+ return base::begin();
}
-
- public:
-
- iterator begin() { return base::begin(); }
- const_iterator begin() const { return base::begin(); }
- iterator end() { return base::end(); }
- const_iterator end() const { return base::end(); }
- difference_type size() const { return base::size(); }
-
- public: // convenience
- reference front()
+ BOOST_DEDUCED_TYPENAME base::iterator begin()
{
- return base::front();
+ return base::begin();
}
- const_reference front() const
+ BOOST_DEDUCED_TYPENAME base::const_iterator end() const
{
- return base::front();
+ return base::end();
}
- reference back()
+ BOOST_DEDUCED_TYPENAME base::iterator end()
{
- return base::back();
+ return base::end();
}
- const_reference back() const
+ 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)
{
- return base::back();
+ iterator_range_::operator=( r );
+ return *this;
}
- reference operator[]( difference_type sz )
+ template<class ForwardRange2>
+ BOOST_DEDUCED_TYPENAME ::boost::enable_if<
+ is_compatible_range<const ForwardRange2>,
+ sub_range&
+ >::type
+ operator=( const ForwardRange2& r )
{
- return base::operator[](sz);
- }
+ iterator_range_::operator=( r );
+ return *this;
+ }
- const_reference operator[]( difference_type sz ) const
+ sub_range& operator=( const sub_range& r )
{
- return base::operator[](sz);
+ 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;
}
-
};
- template< class ForwardRange, class ForwardRange2 >
- inline bool operator==( const sub_range<ForwardRange>& l,
- const sub_range<ForwardRange2>& r )
- {
- return boost::equal( l, r );
- }
-
- template< class ForwardRange, class ForwardRange2 >
- inline bool operator!=( const sub_range<ForwardRange>& l,
- const sub_range<ForwardRange2>& r )
- {
- return !boost::equal( l, r );
- }
-
- template< class ForwardRange, class ForwardRange2 >
- inline bool operator<( const sub_range<ForwardRange>& l,
- const sub_range<ForwardRange2>& r )
- {
- return iterator_range_detail::less_than( l, r );
- }
-
-
} // namespace 'boost'
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))