Merge branch 'feature/drop_front_back' into develop

This commit is contained in:
Neil Groves
2014-03-04 16:22:13 +00:00
4 changed files with 226 additions and 36 deletions

View File

@ -61,11 +61,14 @@ namespace boost
operator unspecified_bool_type() const;
bool equal( const iterator_range& ) const;
value_type& front() const;
value_type& back() const;
iterator_range& advance_begin(difference_type n);
iterator_range& advance_end(difference_type n);
void drop_front();
void drop_front(difference_type n);
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;
value_type operator()( difference_type at ) const;
size_type size() const;
@ -230,21 +233,6 @@ namespace boost
template< class ForwardRange2 >
sub_range& operator=( const ForwardRange2& r );
public: // Forward Range functions
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
public: // convenience
value_type& front();
const value_type& front() const;
value_type& back();
const value_type& back() const;
// for Random Access Range only:
value_type& operator[]( size_type at );
const value_type& operator[]( size_type at ) const;
public:
// rest of interface inherited from iterator_range
};

View File

@ -206,12 +206,18 @@ public:
return *m_Begin;
}
void pop_front()
void drop_front()
{
BOOST_ASSERT(!empty());
++m_Begin;
}
void drop_front(difference_type n)
{
BOOST_ASSERT(n >= difference_type());
std::advance(this->m_Begin, n);
}
protected:
template<class Iterator>
void assign(Iterator first, Iterator last)
@ -256,17 +262,26 @@ protected:
}
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());
return *boost::prior(this->m_End);
}
void pop_back()
void drop_back()
{
BOOST_ASSERT(!this->empty());
--this->m_End;
}
void drop_back(difference_type n)
{
BOOST_ASSERT(n >= difference_type());
std::advance(this->m_End, -n);
}
};
template<class IteratorT>
@ -328,20 +343,6 @@ public:
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;

View File

@ -160,6 +160,7 @@ test-suite range :
[ range-test istream_range ]
[ range-test iterator_pair ]
[ range-test iterator_range ]
[ range-test iterator_range_drop ]
[ range-test iterator_range_variant ]
# [ range-test mfc : <include>$(VC71_ROOT)/atlmfc/include ]
[ range-test join ]

View 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;
}