mirror of
https://github.com/boostorg/range.git
synced 2025-07-30 12:57:28 +02:00
refactored iterator_range to better handle SFINAE.
This commit is contained in:
@ -26,6 +26,7 @@
|
|||||||
#include <boost/type_traits/is_array.hpp>
|
#include <boost/type_traits/is_array.hpp>
|
||||||
#include <boost/type_traits/is_convertible.hpp>
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
#include <boost/type_traits/is_pointer.hpp>
|
#include <boost/type_traits/is_pointer.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
#include <boost/range/functions.hpp>
|
#include <boost/range/functions.hpp>
|
||||||
#include <boost/range/iterator.hpp>
|
#include <boost/range/iterator.hpp>
|
||||||
#include <boost/range/difference_type.hpp>
|
#include <boost/range/difference_type.hpp>
|
||||||
@ -101,10 +102,251 @@ namespace boost
|
|||||||
return boost::equal(l, r);
|
return boost::equal(l, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct range_tag { };
|
struct range_tag
|
||||||
struct const_range_tag { };
|
{
|
||||||
|
};
|
||||||
struct iterator_range_tag { };
|
|
||||||
|
struct const_range_tag
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iterator_range_tag
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class IteratorT, class TraversalTag>
|
||||||
|
class iterator_range_base
|
||||||
|
: public iterator_range_tag
|
||||||
|
{
|
||||||
|
typedef range_detail::safe_bool<
|
||||||
|
IteratorT iterator_range_base<IteratorT, TraversalTag>::*
|
||||||
|
> safe_bool_t;
|
||||||
|
|
||||||
|
typedef iterator_range_base<IteratorT, TraversalTag> type;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef iterator_range_impl<IteratorT> impl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME
|
||||||
|
safe_bool_t::unspecified_bool_type unspecified_bool_type;
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME
|
||||||
|
iterator_value<IteratorT>::type value_type;
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME
|
||||||
|
iterator_difference<IteratorT>::type difference_type;
|
||||||
|
|
||||||
|
typedef std::size_t size_type; // note: must be unsigned
|
||||||
|
|
||||||
|
// Needed because value-type is the same for
|
||||||
|
// const and non-const iterators
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME
|
||||||
|
iterator_reference<IteratorT>::type reference;
|
||||||
|
|
||||||
|
//! const_iterator type
|
||||||
|
/*!
|
||||||
|
There is no distinction between const_iterator and iterator.
|
||||||
|
These typedefs are provides to fulfill container interface
|
||||||
|
*/
|
||||||
|
typedef IteratorT const_iterator;
|
||||||
|
//! iterator type
|
||||||
|
typedef IteratorT iterator;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
iterator_range_base()
|
||||||
|
: m_Begin()
|
||||||
|
, m_End()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Iterator>
|
||||||
|
iterator_range_base(Iterator Begin, Iterator End)
|
||||||
|
: m_Begin(Begin)
|
||||||
|
, m_End(End)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
IteratorT begin() const
|
||||||
|
{
|
||||||
|
return m_Begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
IteratorT end() const
|
||||||
|
{
|
||||||
|
return m_End;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return m_Begin == m_End;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator unspecified_bool_type() const
|
||||||
|
{
|
||||||
|
return safe_bool_t::to_unspecified_bool(
|
||||||
|
m_Begin != m_End, &iterator_range_base::m_Begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!() const
|
||||||
|
{
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal(const iterator_range_base& r) const
|
||||||
|
{
|
||||||
|
return m_Begin == r.m_Begin && m_End == r.m_End;
|
||||||
|
}
|
||||||
|
|
||||||
|
reference front() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!empty());
|
||||||
|
return *m_Begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_front()
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!empty());
|
||||||
|
++m_Begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template<class Iterator>
|
||||||
|
void assign(Iterator first, Iterator last)
|
||||||
|
{
|
||||||
|
m_Begin = first;
|
||||||
|
m_End = last;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
void assign(const SinglePassRange& r)
|
||||||
|
{
|
||||||
|
m_Begin = impl::adl_begin(r);
|
||||||
|
m_End = impl::adl_end(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
void assign(SinglePassRange& r)
|
||||||
|
{
|
||||||
|
m_Begin = impl::adl_begin(r);
|
||||||
|
m_End = impl::adl_end(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
IteratorT m_Begin;
|
||||||
|
IteratorT m_End;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class IteratorT>
|
||||||
|
class iterator_range_base<IteratorT, bidirectional_traversal_tag>
|
||||||
|
: public iterator_range_base<IteratorT, forward_traversal_tag>
|
||||||
|
{
|
||||||
|
typedef iterator_range_base<IteratorT, forward_traversal_tag> base_type;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
iterator_range_base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Iterator>
|
||||||
|
iterator_range_base(Iterator first, Iterator last)
|
||||||
|
: iterator_range_base<IteratorT, forward_traversal_tag>(first, last)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
BOOST_DEDUCED_TYPENAME base_type::reference back() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!this->empty());
|
||||||
|
return *boost::prior(this->m_End);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_back()
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!this->empty());
|
||||||
|
--this->m_End;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class IteratorT>
|
||||||
|
class iterator_range_base<IteratorT, random_access_traversal_tag>
|
||||||
|
: public iterator_range_base<IteratorT, bidirectional_traversal_tag>
|
||||||
|
{
|
||||||
|
typedef iterator_range_base<
|
||||||
|
IteratorT, bidirectional_traversal_tag> base_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME
|
||||||
|
boost::mpl::if_<
|
||||||
|
boost::mpl::or_<
|
||||||
|
boost::is_abstract<
|
||||||
|
BOOST_DEDUCED_TYPENAME base_type::value_type
|
||||||
|
>,
|
||||||
|
boost::is_array<
|
||||||
|
BOOST_DEDUCED_TYPENAME base_type::value_type
|
||||||
|
>
|
||||||
|
>,
|
||||||
|
BOOST_DEDUCED_TYPENAME base_type::reference,
|
||||||
|
BOOST_DEDUCED_TYPENAME base_type::value_type
|
||||||
|
>::type abstract_value_type;
|
||||||
|
|
||||||
|
// Rationale:
|
||||||
|
// typedef these here to reduce verbiage in the implementation of this
|
||||||
|
// type.
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME base_type::difference_type difference_type;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME base_type::reference reference;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
iterator_range_base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Iterator>
|
||||||
|
iterator_range_base(Iterator first, Iterator last)
|
||||||
|
: iterator_range_base<IteratorT, bidirectional_traversal_tag>(
|
||||||
|
first, last)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
reference operator[](difference_type at) const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(at >= 0 && at < size());
|
||||||
|
return this->m_Begin[at];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// When storing transform iterators, operator[]()
|
||||||
|
// fails because it returns by reference. Therefore
|
||||||
|
// operator()() is provided for these cases.
|
||||||
|
//
|
||||||
|
abstract_value_type operator()(difference_type at) const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(at >= 0 && at < size());
|
||||||
|
return this->m_Begin[at];
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_front(difference_type n)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(n >= difference_type());
|
||||||
|
BOOST_ASSERT(size() >= static_cast<size_type>(n));
|
||||||
|
std::advance(this->m_Begin, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_back(difference_type n)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(n >= difference_type());
|
||||||
|
BOOST_ASSERT(size() >= static_cast<size_type>(n));
|
||||||
|
std::advance(this->m_End, -n);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_DEDUCED_TYPENAME base_type::size_type size() const
|
||||||
|
{
|
||||||
|
return this->m_End - this->m_Begin;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterator range template class -----------------------------------------//
|
// iterator range template class -----------------------------------------//
|
||||||
@ -128,217 +370,86 @@ namespace boost
|
|||||||
*/
|
*/
|
||||||
template<class IteratorT>
|
template<class IteratorT>
|
||||||
class iterator_range
|
class iterator_range
|
||||||
: public iterator_range_detail::iterator_range_tag
|
: public iterator_range_detail::iterator_range_base<
|
||||||
|
IteratorT,
|
||||||
|
typename iterator_traversal<IteratorT>::type
|
||||||
|
>
|
||||||
{
|
{
|
||||||
typedef range_detail::safe_bool< IteratorT iterator_range<IteratorT>::* > safe_bool_t;
|
typedef iterator_range_detail::iterator_range_base<
|
||||||
protected: // Used by sub_range
|
IteratorT,
|
||||||
//! implementation class
|
typename iterator_traversal<IteratorT>::type
|
||||||
|
> base_type;
|
||||||
|
|
||||||
|
protected:
|
||||||
typedef iterator_range_detail::iterator_range_impl<IteratorT> impl;
|
typedef iterator_range_detail::iterator_range_impl<IteratorT> impl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! this type
|
|
||||||
typedef iterator_range<IteratorT> type;
|
typedef iterator_range<IteratorT> type;
|
||||||
typedef BOOST_DEDUCED_TYPENAME safe_bool_t::unspecified_bool_type unspecified_bool_type;
|
|
||||||
//BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(value_type);
|
|
||||||
|
|
||||||
//! Encapsulated value type
|
iterator_range()
|
||||||
typedef BOOST_DEDUCED_TYPENAME
|
|
||||||
iterator_value<IteratorT>::type value_type;
|
|
||||||
|
|
||||||
//! Difference type
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME
|
|
||||||
iterator_difference<IteratorT>::type difference_type;
|
|
||||||
|
|
||||||
//! Size type
|
|
||||||
typedef std::size_t size_type; // note: must be unsigned
|
|
||||||
|
|
||||||
//! This type
|
|
||||||
typedef iterator_range<IteratorT> this_type;
|
|
||||||
|
|
||||||
//! Reference type
|
|
||||||
//
|
|
||||||
// Needed because value-type is the same for
|
|
||||||
// const and non-const iterators
|
|
||||||
//
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME
|
|
||||||
iterator_reference<IteratorT>::type reference;
|
|
||||||
|
|
||||||
//! const_iterator type
|
|
||||||
/*!
|
|
||||||
There is no distinction between const_iterator and iterator.
|
|
||||||
These typedefs are provides to fulfill container interface
|
|
||||||
*/
|
|
||||||
typedef IteratorT const_iterator;
|
|
||||||
//! iterator type
|
|
||||||
typedef IteratorT iterator;
|
|
||||||
|
|
||||||
private: // for return value of operator()()
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME
|
|
||||||
boost::mpl::if_< boost::mpl::or_< boost::is_abstract< value_type >,
|
|
||||||
boost::is_array< value_type > >,
|
|
||||||
reference, value_type >::type abstract_value_type;
|
|
||||||
|
|
||||||
public:
|
|
||||||
iterator_range() : m_Begin( iterator() ), m_End( iterator() )
|
|
||||||
{ }
|
|
||||||
|
|
||||||
//! Constructor from a pair of iterators
|
|
||||||
template< class Iterator >
|
|
||||||
iterator_range( Iterator Begin, Iterator End ) :
|
|
||||||
m_Begin(Begin), m_End(End)
|
|
||||||
{}
|
|
||||||
|
|
||||||
//! Constructor from a Range
|
|
||||||
template< class Range >
|
|
||||||
iterator_range( const Range& r ) :
|
|
||||||
m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
|
|
||||||
{}
|
|
||||||
|
|
||||||
//! Constructor from a Range
|
|
||||||
template< class Range >
|
|
||||||
iterator_range( Range& r ) :
|
|
||||||
m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
|
|
||||||
{}
|
|
||||||
|
|
||||||
//! Constructor from a Range
|
|
||||||
template< class Range >
|
|
||||||
iterator_range( const Range& r, iterator_range_detail::const_range_tag ) :
|
|
||||||
m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
|
|
||||||
{}
|
|
||||||
|
|
||||||
//! Constructor from a Range
|
|
||||||
template< class Range >
|
|
||||||
iterator_range( Range& r, iterator_range_detail::range_tag ) :
|
|
||||||
m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
|
|
||||||
{}
|
|
||||||
|
|
||||||
this_type& operator=( const this_type& r )
|
|
||||||
{
|
{
|
||||||
m_Begin = r.begin();
|
}
|
||||||
m_End = r.end();
|
|
||||||
|
template<class Iterator>
|
||||||
|
iterator_range(Iterator first, Iterator last)
|
||||||
|
: base_type(first, last)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
iterator_range(const SinglePassRange& r)
|
||||||
|
: base_type(impl::adl_begin(r), impl::adl_end(r))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
iterator_range(SinglePassRange& r)
|
||||||
|
: base_type(impl::adl_begin(r), impl::adl_end(r))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
iterator_range(const SinglePassRange& r,
|
||||||
|
iterator_range_detail::const_range_tag)
|
||||||
|
: base_type(impl::adl_begin(r), impl::adl_end(r))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class SinglePassRange>
|
||||||
|
iterator_range(SinglePassRange& r,
|
||||||
|
iterator_range_detail::range_tag)
|
||||||
|
: base_type(impl::adl_begin(r), impl::adl_end(r))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Iterator>
|
||||||
|
iterator_range& operator=(const iterator_range<Iterator>& other)
|
||||||
|
{
|
||||||
|
this->assign(other.begin(), other.end());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class Iterator >
|
template<class Iterator>
|
||||||
iterator_range& operator=( const iterator_range<Iterator>& r )
|
iterator_range& operator=(iterator_range<Iterator>& other)
|
||||||
{
|
{
|
||||||
m_Begin = r.begin();
|
this->assign(other.begin(), other.end());
|
||||||
m_End = r.end();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class ForwardRange >
|
template<class SinglePassRange>
|
||||||
iterator_range& operator=( ForwardRange& r )
|
iterator_range& operator=(SinglePassRange& r)
|
||||||
{
|
{
|
||||||
m_Begin = impl::adl_begin( r );
|
this->assign(r);
|
||||||
m_End = impl::adl_end( r );
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class ForwardRange >
|
template<class SinglePassRange>
|
||||||
iterator_range& operator=( const ForwardRange& r )
|
iterator_range& operator=(const SinglePassRange& r)
|
||||||
{
|
{
|
||||||
m_Begin = impl::adl_begin( r );
|
this->assign(r);
|
||||||
m_End = impl::adl_end( r );
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
IteratorT begin() const
|
|
||||||
{
|
|
||||||
return m_Begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
IteratorT end() const
|
|
||||||
{
|
|
||||||
return m_End;
|
|
||||||
}
|
|
||||||
|
|
||||||
difference_type size() const
|
|
||||||
{
|
|
||||||
return m_End - m_Begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const
|
|
||||||
{
|
|
||||||
return m_Begin == m_End;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator unspecified_bool_type() const
|
|
||||||
{
|
|
||||||
return safe_bool_t::to_unspecified_bool(m_Begin != m_End, &iterator_range::m_Begin);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!() const
|
|
||||||
{
|
|
||||||
return empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool equal(const iterator_range& r) const
|
|
||||||
{
|
|
||||||
return m_Begin == r.m_Begin && m_End == r.m_End;
|
|
||||||
}
|
|
||||||
|
|
||||||
public: // convenience
|
|
||||||
reference front() const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT( !empty() );
|
|
||||||
return *m_Begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
reference back() const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT( !empty() );
|
|
||||||
IteratorT last( m_End );
|
|
||||||
return *--last;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pop_front() - added to model the SinglePassRangePrimitiveConcept
|
|
||||||
void pop_front()
|
|
||||||
{
|
|
||||||
BOOST_ASSERT( !empty() );
|
|
||||||
++m_Begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pop_back() - added to model the BidirectionalRangePrimitiveConcept
|
|
||||||
void pop_back()
|
|
||||||
{
|
|
||||||
BOOST_ASSERT( !empty() );
|
|
||||||
--m_End;
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator[]( difference_type at ) const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT( at >= 0 && at < size() );
|
|
||||||
return m_Begin[at];
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// When storing transform iterators, operator[]()
|
|
||||||
// fails because it returns by reference. Therefore
|
|
||||||
// operator()() is provided for these cases.
|
|
||||||
//
|
|
||||||
abstract_value_type operator()( difference_type at ) const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT( at >= 0 && at < size() );
|
|
||||||
return m_Begin[at];
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator_range& advance_begin( difference_type n )
|
|
||||||
{
|
|
||||||
std::advance( m_Begin, n );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator_range& advance_end( difference_type n )
|
|
||||||
{
|
|
||||||
std::advance( m_End, n );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// begin and end iterators
|
|
||||||
IteratorT m_Begin;
|
|
||||||
IteratorT m_End;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//
|
//
|
||||||
// Allow subclasses an easy way to access the
|
// Allow subclasses an easy way to access the
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <boost/range/algorithm_ext.hpp>
|
#include <boost/range/algorithm_ext.hpp>
|
||||||
#include <boost/range/algorithm/fill.hpp>
|
#include <boost/range/algorithm/fill.hpp>
|
||||||
|
#include <boost/range/value_type.hpp>
|
||||||
#include <boost/assign.hpp>
|
#include <boost/assign.hpp>
|
||||||
#include <boost/array.hpp>
|
#include <boost/array.hpp>
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
@ -167,8 +168,6 @@ namespace boost_range_adaptor_type_erased_test
|
|||||||
{
|
{
|
||||||
using namespace boost::adaptors;
|
using namespace boost::adaptors;
|
||||||
|
|
||||||
typedef Buffer buffer_type;
|
|
||||||
|
|
||||||
typedef typename boost::range_value<Container>::type value_type;
|
typedef typename boost::range_value<Container>::type value_type;
|
||||||
|
|
||||||
typedef typename boost::any_range_type_generator<
|
typedef typename boost::any_range_type_generator<
|
||||||
@ -451,13 +450,24 @@ namespace boost_range_adaptor_type_erased_test
|
|||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
c.push_back(i);
|
c.push_back(i);
|
||||||
|
|
||||||
typedef boost::any_range<
|
typedef boost::any_range_type_generator<
|
||||||
int
|
std::vector<int> >::type any_range_type;
|
||||||
, boost::random_access_traversal_tag
|
|
||||||
, int
|
BOOST_STATIC_ASSERT(
|
||||||
, boost::range_difference< std::vector<int> >::type
|
boost::is_same<
|
||||||
, boost::use_default
|
int,
|
||||||
> any_range_type;
|
boost::range_value<any_range_type>::type
|
||||||
|
>::value
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
boost::is_same<
|
||||||
|
boost::random_access_traversal_tag,
|
||||||
|
boost::iterator_traversal<
|
||||||
|
boost::range_iterator<any_range_type>::type
|
||||||
|
>::type
|
||||||
|
>::value
|
||||||
|
);
|
||||||
|
|
||||||
any_range_type rng = c | type_erased_t();
|
any_range_type rng = c | type_erased_t();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user