forked from boostorg/range
Merge branch 'develop'
These changes are just to address some small issues on some compiler versions with newly introduced tests. It also includes a fix to a recent regression in the sub_range class so that it preserves constness propagation as before the SFINAE improvement changes.
This commit is contained in:
@ -61,11 +61,14 @@ namespace boost
|
|||||||
operator unspecified_bool_type() const;
|
operator unspecified_bool_type() const;
|
||||||
bool equal( const iterator_range& ) const;
|
bool equal( const iterator_range& ) const;
|
||||||
value_type& front() const;
|
value_type& front() const;
|
||||||
value_type& back() const;
|
void drop_front();
|
||||||
iterator_range& advance_begin(difference_type n);
|
void drop_front(difference_type n);
|
||||||
iterator_range& advance_end(difference_type n);
|
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
// for Random Access Range only:
|
// for Bidirectional:
|
||||||
|
value_type& back() const;
|
||||||
|
void drop_back();
|
||||||
|
void drop_back(difference_type n);
|
||||||
|
// for Random Access only:
|
||||||
reference operator[]( difference_type at ) const;
|
reference operator[]( difference_type at ) const;
|
||||||
value_type operator()( difference_type at ) const;
|
value_type operator()( difference_type at ) const;
|
||||||
size_type size() const;
|
size_type size() const;
|
||||||
@ -210,11 +213,17 @@ namespace boost
|
|||||||
class sub_range : public iterator_range< typename range_iterator<ForwardRange>::type >
|
class sub_range : public iterator_range< typename range_iterator<ForwardRange>::type >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef typename range_value<ForwardRange>::type value_type;
|
||||||
typedef typename range_iterator<ForwardRange>::type iterator;
|
typedef typename range_iterator<ForwardRange>::type iterator;
|
||||||
typedef typename range_iterator<const ForwardRange>::type const_iterator;
|
typedef typename range_iterator<const ForwardRange>::type const_iterator;
|
||||||
typedef typename iterator_difference<iterator>::type difference_type;
|
typedef typename range_difference<ForwardRange>::type difference_type;
|
||||||
|
typedef typename range_size<ForwardRange>::type size_type;
|
||||||
|
typedef typename range_reference<ForwardRange>::type reference;
|
||||||
|
typedef typename range_reference<const ForwardRange>::type const_reference;
|
||||||
|
|
||||||
public: // construction, assignment
|
public: // construction, assignment
|
||||||
|
sub_range();
|
||||||
|
|
||||||
template< class ForwardTraversalIterator >
|
template< class ForwardTraversalIterator >
|
||||||
sub_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
|
sub_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
|
||||||
|
|
||||||
@ -230,20 +239,22 @@ namespace boost
|
|||||||
template< class ForwardRange2 >
|
template< class ForwardRange2 >
|
||||||
sub_range& operator=( const ForwardRange2& r );
|
sub_range& operator=( const ForwardRange2& r );
|
||||||
|
|
||||||
public: // Forward Range functions
|
// iterator accessors
|
||||||
iterator begin();
|
const_iterator begin() const;
|
||||||
const_iterator begin() const;
|
iterator begin();
|
||||||
iterator end();
|
const_iterator end() const;
|
||||||
const_iterator end() const;
|
iterator end();
|
||||||
|
|
||||||
public: // convenience
|
reference front();
|
||||||
value_type& front();
|
const_reference front() const;
|
||||||
const value_type& front() const;
|
|
||||||
value_type& back();
|
// If traversal >= bidirectional:
|
||||||
const value_type& back() const;
|
reference back();
|
||||||
// for Random Access Range only:
|
const_reference back();
|
||||||
value_type& operator[]( size_type at );
|
|
||||||
const value_type& operator[]( size_type at ) const;
|
// If traversal >= random-access:
|
||||||
|
reference operator[](difference_type n);
|
||||||
|
const_reference operator[](difference_type n) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// rest of interface inherited from iterator_range
|
// rest of interface inherited from iterator_range
|
||||||
|
@ -206,12 +206,18 @@ public:
|
|||||||
return *m_Begin;
|
return *m_Begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_front()
|
void drop_front()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!empty());
|
BOOST_ASSERT(!empty());
|
||||||
++m_Begin;
|
++m_Begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drop_front(difference_type n)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(n >= difference_type());
|
||||||
|
std::advance(this->m_Begin, n);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template<class Iterator>
|
template<class Iterator>
|
||||||
void assign(Iterator first, Iterator last)
|
void assign(Iterator first, Iterator last)
|
||||||
@ -256,17 +262,26 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BOOST_DEDUCED_TYPENAME base_type::reference back() const
|
typedef BOOST_DEDUCED_TYPENAME base_type::difference_type difference_type;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME base_type::reference reference;
|
||||||
|
|
||||||
|
reference back() const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!this->empty());
|
BOOST_ASSERT(!this->empty());
|
||||||
return *boost::prior(this->m_End);
|
return *boost::prior(this->m_End);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_back()
|
void drop_back()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!this->empty());
|
BOOST_ASSERT(!this->empty());
|
||||||
--this->m_End;
|
--this->m_End;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drop_back(difference_type n)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(n >= difference_type());
|
||||||
|
std::advance(this->m_End, -n);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class IteratorT>
|
template<class IteratorT>
|
||||||
@ -328,20 +343,6 @@ public:
|
|||||||
return this->m_Begin[at];
|
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
|
BOOST_DEDUCED_TYPENAME base_type::size_type size() const
|
||||||
{
|
{
|
||||||
return this->m_End - this->m_Begin;
|
return this->m_End - this->m_Begin;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <boost/range/value_type.hpp>
|
#include <boost/range/value_type.hpp>
|
||||||
#include <boost/range/size_type.hpp>
|
#include <boost/range/size_type.hpp>
|
||||||
#include <boost/range/difference_type.hpp>
|
#include <boost/range/difference_type.hpp>
|
||||||
|
#include <boost/range/reference.hpp>
|
||||||
#include <boost/range/algorithm/equal.hpp>
|
#include <boost/range/algorithm/equal.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/type_traits/is_reference.hpp>
|
#include <boost/type_traits/is_reference.hpp>
|
||||||
@ -31,25 +32,135 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace range_detail
|
||||||
|
{
|
||||||
|
|
||||||
template< class ForwardRange >
|
template<class ForwardRange, class TraversalTag>
|
||||||
class sub_range
|
class sub_range_base
|
||||||
: public iterator_range<
|
: public iterator_range<
|
||||||
BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
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()
|
||||||
{
|
{
|
||||||
typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t;
|
}
|
||||||
typedef iterator_range< iterator_t > 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;
|
typedef BOOST_DEDUCED_TYPENAME base::impl impl;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type;
|
typedef BOOST_DEDUCED_TYPENAME base::iterator_range_ iterator_range_;
|
||||||
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;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<class Source>
|
template<class Source>
|
||||||
@ -60,7 +171,7 @@ namespace boost
|
|||||||
range_iterator<Source>,
|
range_iterator<Source>,
|
||||||
mpl::identity<void>
|
mpl::identity<void>
|
||||||
>::type,
|
>::type,
|
||||||
iterator
|
BOOST_DEDUCED_TYPENAME base::iterator
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
@ -70,8 +181,9 @@ namespace boost
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
|
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
|
||||||
sub_range( const sub_range& r )
|
sub_range(const sub_range& r)
|
||||||
: base( static_cast<const base&>( r ) )
|
: base(impl::adl_begin(static_cast<const base&>(r)),
|
||||||
|
impl::adl_end(static_cast<const base&>(r)))
|
||||||
{ }
|
{ }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -81,14 +193,10 @@ namespace boost
|
|||||||
BOOST_DEDUCED_TYPENAME enable_if<
|
BOOST_DEDUCED_TYPENAME enable_if<
|
||||||
is_compatible_range<ForwardRange2>
|
is_compatible_range<ForwardRange2>
|
||||||
>::type* = 0
|
>::type* = 0
|
||||||
) :
|
)
|
||||||
|
: base(impl::adl_begin(r), impl::adl_end(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 >
|
template< class ForwardRange2 >
|
||||||
sub_range(
|
sub_range(
|
||||||
@ -96,14 +204,30 @@ namespace boost
|
|||||||
BOOST_DEDUCED_TYPENAME enable_if<
|
BOOST_DEDUCED_TYPENAME enable_if<
|
||||||
is_compatible_range<const ForwardRange2>
|
is_compatible_range<const ForwardRange2>
|
||||||
>::type* = 0
|
>::type* = 0
|
||||||
) :
|
)
|
||||||
|
: base(impl::adl_begin(r), impl::adl_end(r))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
|
BOOST_DEDUCED_TYPENAME base::const_iterator begin() const
|
||||||
base( impl::adl_begin( r ), impl::adl_end( r ) )
|
{
|
||||||
#else
|
return base::begin();
|
||||||
base( r )
|
}
|
||||||
#endif
|
|
||||||
{ }
|
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 >
|
template< class Iter >
|
||||||
sub_range( Iter first, Iter last ) :
|
sub_range( Iter first, Iter last ) :
|
||||||
@ -117,7 +241,7 @@ namespace boost
|
|||||||
>::type
|
>::type
|
||||||
operator=(ForwardRange2& r)
|
operator=(ForwardRange2& r)
|
||||||
{
|
{
|
||||||
base::operator=( r );
|
iterator_range_::operator=( r );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,13 +252,13 @@ namespace boost
|
|||||||
>::type
|
>::type
|
||||||
operator=( const ForwardRange2& r )
|
operator=( const ForwardRange2& r )
|
||||||
{
|
{
|
||||||
base::operator=( r );
|
iterator_range_::operator=( r );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub_range& operator=( const sub_range& r )
|
sub_range& operator=( const sub_range& r )
|
||||||
{
|
{
|
||||||
base::operator=( static_cast<const base&>(r) );
|
iterator_range_::operator=( static_cast<const iterator_range_&>(r) );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -160,6 +160,7 @@ test-suite range :
|
|||||||
[ range-test istream_range ]
|
[ range-test istream_range ]
|
||||||
[ range-test iterator_pair ]
|
[ range-test iterator_pair ]
|
||||||
[ range-test iterator_range ]
|
[ range-test iterator_range ]
|
||||||
|
[ range-test iterator_range_drop ]
|
||||||
[ range-test iterator_range_variant ]
|
[ range-test iterator_range_variant ]
|
||||||
# [ range-test mfc : <include>$(VC71_ROOT)/atlmfc/include ]
|
# [ range-test mfc : <include>$(VC71_ROOT)/atlmfc/include ]
|
||||||
[ range-test join ]
|
[ range-test join ]
|
||||||
|
200
test/iterator_range_drop.cpp
Normal file
200
test/iterator_range_drop.cpp
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
// Boost.Range library
|
||||||
|
//
|
||||||
|
// Copyright Neil Groves 2014. 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/
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
#include <boost/range/iterator_range_core.hpp>
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
|
#include <boost/test/test_tools.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost_range_test
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
class single_pass_iterator
|
||||||
|
: public boost::iterator_facade<
|
||||||
|
single_pass_iterator,
|
||||||
|
boost::int32_t,
|
||||||
|
boost::single_pass_traversal_tag,
|
||||||
|
const boost::int32_t&
|
||||||
|
>
|
||||||
|
{
|
||||||
|
friend class boost::iterator_core_access;
|
||||||
|
|
||||||
|
typedef std::vector<boost::int32_t>::const_iterator iterator_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
single_pass_iterator() { }
|
||||||
|
|
||||||
|
explicit single_pass_iterator(iterator_t it)
|
||||||
|
: m_it(it)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
++m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal(single_pass_iterator other) const
|
||||||
|
{
|
||||||
|
return m_it == other.m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::int32_t dereference() const
|
||||||
|
{
|
||||||
|
return *m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator_t m_it;
|
||||||
|
};
|
||||||
|
|
||||||
|
class bidirectional_iterator
|
||||||
|
: public boost::iterator_facade<
|
||||||
|
bidirectional_iterator,
|
||||||
|
boost::int32_t,
|
||||||
|
boost::bidirectional_traversal_tag,
|
||||||
|
const boost::int32_t&
|
||||||
|
>
|
||||||
|
{
|
||||||
|
friend class boost::iterator_core_access;
|
||||||
|
|
||||||
|
typedef std::vector<boost::int32_t>::const_iterator iterator_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bidirectional_iterator() { }
|
||||||
|
|
||||||
|
explicit bidirectional_iterator(iterator_t it)
|
||||||
|
: m_it(it)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
++m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrement()
|
||||||
|
{
|
||||||
|
--m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal(bidirectional_iterator other) const
|
||||||
|
{
|
||||||
|
return m_it == other.m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::int32_t dereference() const
|
||||||
|
{
|
||||||
|
return *m_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator_t m_it;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename SinglePassRange>
|
||||||
|
boost::iterator_range<single_pass_iterator>
|
||||||
|
single_pass_range(const SinglePassRange& rng)
|
||||||
|
{
|
||||||
|
return boost::iterator_range<single_pass_iterator>(
|
||||||
|
single_pass_iterator(boost::begin(rng)),
|
||||||
|
single_pass_iterator(boost::end(rng)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename BidirectionalRange>
|
||||||
|
boost::iterator_range<bidirectional_iterator>
|
||||||
|
bidirectional_range(const BidirectionalRange& rng)
|
||||||
|
{
|
||||||
|
return boost::iterator_range<bidirectional_iterator>(
|
||||||
|
bidirectional_iterator(boost::begin(rng)),
|
||||||
|
bidirectional_iterator(boost::end(rng)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_drop_front()
|
||||||
|
{
|
||||||
|
std::vector<boost::int32_t> v;
|
||||||
|
std::vector<boost::int32_t> ref_output;
|
||||||
|
|
||||||
|
for (boost::int32_t i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
v.push_back(i);
|
||||||
|
ref_output.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::iterator_range<single_pass_iterator> rng = single_pass_range(v);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
|
||||||
|
ref_output.begin(), ref_output.end());
|
||||||
|
|
||||||
|
rng.drop_front();
|
||||||
|
|
||||||
|
ref_output.erase(ref_output.begin());
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
|
||||||
|
ref_output.begin(), ref_output.end());
|
||||||
|
|
||||||
|
rng.drop_front(5);
|
||||||
|
|
||||||
|
ref_output.erase(ref_output.begin(), ref_output.begin() + 5);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
|
||||||
|
ref_output.begin(), ref_output.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_drop_back()
|
||||||
|
{
|
||||||
|
std::vector<boost::int32_t> v;
|
||||||
|
std::vector<boost::int32_t> ref_output;
|
||||||
|
|
||||||
|
for (boost::int32_t i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
v.push_back(i);
|
||||||
|
ref_output.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::iterator_range<bidirectional_iterator> rng = bidirectional_range(v);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
|
||||||
|
ref_output.begin(), ref_output.end());
|
||||||
|
|
||||||
|
rng.drop_back();
|
||||||
|
|
||||||
|
ref_output.pop_back();
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
|
||||||
|
ref_output.begin(), ref_output.end());
|
||||||
|
|
||||||
|
rng.drop_back(5);
|
||||||
|
|
||||||
|
ref_output.erase(ref_output.end() - 5, ref_output.end());
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
|
||||||
|
ref_output.begin(), ref_output.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
} // namespace boost_range_test
|
||||||
|
|
||||||
|
boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||||
|
{
|
||||||
|
boost::unit_test::test_suite* test =
|
||||||
|
BOOST_TEST_SUITE("Boost.Range iterator_range drop functions");
|
||||||
|
|
||||||
|
test->add(BOOST_TEST_CASE(&boost_range_test::test_drop_front));
|
||||||
|
test->add(BOOST_TEST_CASE(&boost_range_test::test_drop_back));
|
||||||
|
|
||||||
|
return test;
|
||||||
|
}
|
@ -18,11 +18,17 @@
|
|||||||
|
|
||||||
#include <boost/range/sub_range.hpp>
|
#include <boost/range/sub_range.hpp>
|
||||||
#include <boost/range/as_literal.hpp>
|
#include <boost/range/as_literal.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <boost/test/test_tools.hpp>
|
#include <boost/test/test_tools.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost_range_test
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
void check_sub_range()
|
void check_sub_range()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -136,13 +142,107 @@ void check_sub_range()
|
|||||||
BOOST_CHECK( rrr == boost::as_literal("HEllo worlD") );
|
BOOST_CHECK( rrr == boost::as_literal("HEllo worlD") );
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
template<class T>
|
||||||
|
void check_mutable_type(T&)
|
||||||
boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
|
|
||||||
{
|
{
|
||||||
boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
BOOST_STATIC_ASSERT(!boost::is_const<T>::value);
|
||||||
|
}
|
||||||
|
|
||||||
test->add( BOOST_TEST_CASE( &check_sub_range ) );
|
template<class T>
|
||||||
|
void check_constant_type(T&)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT(boost::is_const<T>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Range, class Iterator>
|
||||||
|
void check_is_const_iterator(Iterator it)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_same<
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::add_const<Range>::type
|
||||||
|
>::type,
|
||||||
|
Iterator
|
||||||
|
>::value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Range, class Iterator>
|
||||||
|
void check_is_iterator(Iterator it)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_same<
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::remove_const<Range>::type
|
||||||
|
>::type,
|
||||||
|
Iterator
|
||||||
|
>::value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void const_propagation_mutable_collection(void)
|
||||||
|
{
|
||||||
|
typedef std::vector<int> coll_t;
|
||||||
|
typedef boost::sub_range<coll_t> sub_range_t;
|
||||||
|
|
||||||
|
coll_t c;
|
||||||
|
c.push_back(0);
|
||||||
|
|
||||||
|
sub_range_t rng(c);
|
||||||
|
const sub_range_t crng(c);
|
||||||
|
|
||||||
|
check_is_iterator<sub_range_t>(rng.begin());
|
||||||
|
check_is_iterator<sub_range_t>(rng.end());
|
||||||
|
|
||||||
|
check_is_const_iterator<sub_range_t>(crng.begin());
|
||||||
|
check_is_const_iterator<sub_range_t>(crng.end());
|
||||||
|
|
||||||
|
check_mutable_type(rng[0]);
|
||||||
|
check_mutable_type(rng.front());
|
||||||
|
check_mutable_type(rng.back());
|
||||||
|
check_constant_type(crng[0]);
|
||||||
|
check_constant_type(crng.front());
|
||||||
|
check_constant_type(crng.back());
|
||||||
|
}
|
||||||
|
|
||||||
|
void const_propagation_const_collection(void)
|
||||||
|
{
|
||||||
|
typedef std::vector<int> coll_t;
|
||||||
|
typedef boost::sub_range<const coll_t> sub_range_t;
|
||||||
|
|
||||||
|
coll_t c;
|
||||||
|
c.push_back(0);
|
||||||
|
|
||||||
|
sub_range_t rng(c);
|
||||||
|
const sub_range_t crng(c);
|
||||||
|
|
||||||
|
check_is_const_iterator<sub_range_t>(rng.begin());
|
||||||
|
check_is_const_iterator<sub_range_t>(rng.end());
|
||||||
|
|
||||||
|
check_is_const_iterator<sub_range_t>(crng.begin());
|
||||||
|
check_is_const_iterator<sub_range_t>(crng.end());
|
||||||
|
|
||||||
|
check_constant_type(rng[0]);
|
||||||
|
check_constant_type(rng.front());
|
||||||
|
check_constant_type(rng.back());
|
||||||
|
check_constant_type(crng[0]);
|
||||||
|
check_constant_type(crng.front());
|
||||||
|
check_constant_type(crng.back());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
} // namespace boost_range_test
|
||||||
|
|
||||||
|
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||||
|
{
|
||||||
|
boost::unit_test::test_suite* test =
|
||||||
|
BOOST_TEST_SUITE( "Boost.Range sub_range test suite" );
|
||||||
|
|
||||||
|
test->add(BOOST_TEST_CASE(&boost_range_test::check_sub_range));
|
||||||
|
|
||||||
|
test->add(BOOST_TEST_CASE(
|
||||||
|
&boost_range_test::const_propagation_const_collection));
|
||||||
|
|
||||||
|
test->add(BOOST_TEST_CASE(
|
||||||
|
&boost_range_test::const_propagation_mutable_collection));
|
||||||
|
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,9 @@ namespace boost
|
|||||||
|
|
||||||
void test_ticket_6715_iterator_range_equality()
|
void test_ticket_6715_iterator_range_equality()
|
||||||
{
|
{
|
||||||
str_ref a("test");
|
std::string src("test");
|
||||||
str_ref b("test");
|
str_ref a(src);
|
||||||
|
str_ref b(src);
|
||||||
BOOST_CHECK(a == b);
|
BOOST_CHECK(a == b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user