forked from boostorg/range
[boost][range] - merge from trunk which fixes a defect in the strided range adaptor, and contains improvements to the documentation
[SVN r67454]
This commit is contained in:
@@ -137,6 +137,8 @@ test-suite range :
|
||||
[ range-test const_ranges ]
|
||||
[ range-test counting_range ]
|
||||
[ range-test extension_mechanism ]
|
||||
[ range-test extension_size ]
|
||||
[ range-test has_range_iterator ]
|
||||
[ range-test irange ]
|
||||
[ range-test istream_range ]
|
||||
[ range-test iterator_pair ]
|
||||
|
||||
+182
-16
@@ -8,6 +8,9 @@
|
||||
//
|
||||
// For more information, see http://www.boost.org/libs/range/
|
||||
//
|
||||
// The strided_defect_Trac5014 test case is a modified version of a test case
|
||||
// contribued by Michel Morin as part of the trac ticket.
|
||||
//
|
||||
#include <boost/range/adaptor/strided.hpp>
|
||||
|
||||
#include <boost/test/test_tools.hpp>
|
||||
@@ -24,35 +27,44 @@ namespace boost
|
||||
{
|
||||
namespace
|
||||
{
|
||||
const int STRIDE_SIZE = 2;
|
||||
|
||||
template< class Container >
|
||||
void strided_test_impl( Container& c )
|
||||
void strided_test_impl( Container& c, int stride_size )
|
||||
{
|
||||
using namespace boost::adaptors;
|
||||
|
||||
BOOST_ASSERT( c.size() % STRIDE_SIZE == 0 );
|
||||
// Rationale:
|
||||
// This requirement was too restrictive. It makes the use of the
|
||||
// strided adaptor too dangerous, and a simple solution existed
|
||||
// to make it safe, hence the strided adaptor has been modified
|
||||
// and this restriction no longer applies.
|
||||
//BOOST_ASSERT( c.size() % STRIDE_SIZE == 0 );
|
||||
|
||||
Container reference;
|
||||
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iterator_t;
|
||||
typedef BOOST_DEDUCED_TYPENAME Container::difference_type diff_t;
|
||||
typedef BOOST_DEDUCED_TYPENAME Container::size_type size_type;
|
||||
iterator_t it = c.begin();
|
||||
for (iterator_t last = c.end();
|
||||
it != last; it += STRIDE_SIZE)
|
||||
|
||||
iterator_t last = c.end();
|
||||
for (; it != last; )
|
||||
{
|
||||
reference.push_back(*it);
|
||||
|
||||
for (int i = 0; (it != last) && (i < stride_size); ++i)
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
Container test;
|
||||
boost::push_back( test, c | strided(2) );
|
||||
boost::push_back( test, c | strided(stride_size) );
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
|
||||
reference.begin(), reference.end() );
|
||||
|
||||
Container test2;
|
||||
boost::push_back( test2, adaptors::stride(c, 2) );
|
||||
boost::push_back( test2, adaptors::stride(c, stride_size) );
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( test2.begin(), test2.end(),
|
||||
reference.begin(), reference.end() );
|
||||
@@ -60,41 +72,193 @@ namespace boost
|
||||
// Test the const versions:
|
||||
const Container& cc = c;
|
||||
Container test3;
|
||||
boost::push_back( test3, cc | strided(2) );
|
||||
boost::push_back( test3, cc | strided(stride_size) );
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( test3.begin(), test3.end(),
|
||||
reference.begin(), reference.end() );
|
||||
|
||||
Container test4;
|
||||
boost::push_back( test4, adaptors::stride(cc, 2) );
|
||||
boost::push_back( test4, adaptors::stride(cc, stride_size) );
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( test4.begin(), test4.end(),
|
||||
reference.begin(), reference.end() );
|
||||
}
|
||||
|
||||
template< class Container >
|
||||
void strided_test_impl()
|
||||
void strided_test_impl(int stride_size)
|
||||
{
|
||||
using namespace boost::assign;
|
||||
|
||||
Container c;
|
||||
|
||||
// Test empty
|
||||
strided_test_impl(c);
|
||||
strided_test_impl(c, stride_size);
|
||||
|
||||
// Test two elements
|
||||
c += 1,2;
|
||||
strided_test_impl(c);
|
||||
strided_test_impl(c, stride_size);
|
||||
|
||||
// Test many elements
|
||||
c += 1,1,1,2,2,3,4,5,6,6,6,7,8,9;
|
||||
strided_test_impl(c);
|
||||
strided_test_impl(c, stride_size);
|
||||
|
||||
// Test an odd number of elements to determine that the relaxation
|
||||
// of the requirements has been successful
|
||||
// Test a sequence of length 1 with a stride of 2
|
||||
c.clear();
|
||||
c += 1;
|
||||
strided_test_impl(c, stride_size);
|
||||
|
||||
// Test a sequence of length 2 with a stride of 2
|
||||
c.clear();
|
||||
c += 1,2;
|
||||
strided_test_impl(c, stride_size);
|
||||
|
||||
// Test a sequence of length 3 with a stride of 2
|
||||
c.clear();
|
||||
c += 1,2,3;
|
||||
strided_test_impl(c, stride_size);
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
void strided_test_zero_stride()
|
||||
{
|
||||
Container c;
|
||||
c.push_back(1);
|
||||
|
||||
typedef boost::strided_range<Container> strided_range_t;
|
||||
strided_range_t rng( boost::adaptors::stride(c, 0) );
|
||||
typedef typename boost::range_iterator<strided_range_t>::type iter_t;
|
||||
|
||||
iter_t first(boost::begin(c), 0, 0, boost::size(c));
|
||||
iter_t last(boost::end(c), 0, boost::size(c), boost::size(c));
|
||||
|
||||
iter_t it = first;
|
||||
for (int i = 0; i < 10; ++i, ++it)
|
||||
{
|
||||
BOOST_CHECK(it == first);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
void strided_test_impl()
|
||||
{
|
||||
strided_test_zero_stride< Container >();
|
||||
|
||||
const int MAX_STRIDE_SIZE = 10;
|
||||
for (int stride_size = 1; stride_size <= MAX_STRIDE_SIZE; ++stride_size)
|
||||
{
|
||||
strided_test_impl< Container >(stride_size);
|
||||
}
|
||||
}
|
||||
|
||||
void strided_test()
|
||||
{
|
||||
strided_test_impl< std::vector< int > >();
|
||||
strided_test_impl< std::deque< int > >();
|
||||
strided_test_impl< std::vector<int> >();
|
||||
strided_test_impl< std::deque<int> >();
|
||||
strided_test_impl< std::list<int> >();
|
||||
}
|
||||
|
||||
void strided_defect_Trac5014()
|
||||
{
|
||||
using namespace boost::assign;
|
||||
|
||||
std::vector<int> v;
|
||||
for (int i = 0; i < 30; ++i)
|
||||
v.push_back(i);
|
||||
|
||||
std::vector<int> reference;
|
||||
reference += 0,4,8,12,16,20,24,28;
|
||||
|
||||
std::vector<int> output;
|
||||
boost::push_back(output, v | boost::adaptors::strided(4));
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
|
||||
output.begin(), output.end() );
|
||||
|
||||
BOOST_CHECK_EQUAL( output.back(), 28 );
|
||||
}
|
||||
|
||||
template<typename BaseIterator, typename Category>
|
||||
class strided_mock_iterator
|
||||
: public boost::iterator_adaptor<
|
||||
strided_mock_iterator<BaseIterator,Category>
|
||||
, BaseIterator
|
||||
, boost::use_default
|
||||
, Category
|
||||
>
|
||||
{
|
||||
typedef boost::iterator_adaptor<
|
||||
strided_mock_iterator
|
||||
, BaseIterator
|
||||
, boost::use_default
|
||||
, Category
|
||||
> super_t;
|
||||
public:
|
||||
explicit strided_mock_iterator(BaseIterator it)
|
||||
: super_t(it)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void increment()
|
||||
{
|
||||
++(this->base_reference());
|
||||
}
|
||||
|
||||
bool equal(const strided_mock_iterator& other) const
|
||||
{
|
||||
return this->base() == other.base();
|
||||
}
|
||||
|
||||
BOOST_DEDUCED_TYPENAME super_t::reference dereference() const
|
||||
{
|
||||
return *(this->base());
|
||||
}
|
||||
|
||||
friend class boost::iterator_core_access;
|
||||
};
|
||||
|
||||
template<typename Category, typename Range>
|
||||
boost::iterator_range<strided_mock_iterator<BOOST_DEDUCED_TYPENAME boost::range_iterator<Range>::type, Category> >
|
||||
as_mock_range(Range& rng)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Range>::type range_iter_t;
|
||||
typedef strided_mock_iterator<range_iter_t, Category> mock_iter_t;
|
||||
|
||||
return boost::iterator_range<mock_iter_t>(
|
||||
mock_iter_t(boost::begin(rng)),
|
||||
mock_iter_t(boost::end(rng)));
|
||||
}
|
||||
|
||||
void strided_test_traversal()
|
||||
{
|
||||
using namespace boost::assign;
|
||||
|
||||
std::vector<int> v;
|
||||
for (int i = 0; i < 30; ++i)
|
||||
v.push_back(i);
|
||||
|
||||
std::vector<int> reference;
|
||||
reference += 0,4,8,12,16,20,24,28;
|
||||
|
||||
std::vector<int> output;
|
||||
boost::push_back(output, as_mock_range<boost::forward_traversal_tag>(v) | boost::adaptors::strided(4));
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
|
||||
output.begin(), output.end() );
|
||||
|
||||
output.clear();
|
||||
boost::push_back(output, as_mock_range<boost::bidirectional_traversal_tag>(v) | boost::adaptors::strided(4));
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
|
||||
output.begin(), output.end() );
|
||||
|
||||
output.clear();
|
||||
boost::push_back(output, as_mock_range<boost::random_access_traversal_tag>(v) | boost::adaptors::strided(4));
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
|
||||
output.begin(), output.end() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,6 +270,8 @@ init_unit_test_suite(int argc, char* argv[])
|
||||
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.strided" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &boost::strided_test ) );
|
||||
test->add( BOOST_TEST_CASE( &boost::strided_defect_Trac5014 ) );
|
||||
test->add( BOOST_TEST_CASE( &boost::strided_test_traversal ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
+3
-5
@@ -67,9 +67,8 @@ void check_copy( Rng r )
|
||||
}
|
||||
|
||||
|
||||
|
||||
template< class Rng >
|
||||
void check()
|
||||
void check_direct()
|
||||
{
|
||||
using namespace boost::adaptors;
|
||||
|
||||
@@ -104,7 +103,6 @@ void check()
|
||||
}
|
||||
|
||||
|
||||
|
||||
template< class IndirectRng >
|
||||
void check_indirect()
|
||||
{
|
||||
@@ -189,8 +187,8 @@ void check_regex()
|
||||
|
||||
void check_adaptors()
|
||||
{
|
||||
check< std::vector<int> >();
|
||||
check< std::list<int> >();
|
||||
check_direct< std::vector<int> >();
|
||||
check_direct< std::list<int> >();
|
||||
check_indirect< std::vector<int*> >();
|
||||
check_indirect< std::list<int*> >();
|
||||
|
||||
|
||||
@@ -72,9 +72,9 @@ namespace boost
|
||||
BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, false_predicate()) );
|
||||
BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), false_predicate()) );
|
||||
|
||||
BOOST_CHECK_EQUAL( cont.size(), boost::count_if(cont, true_predicate()) );
|
||||
BOOST_CHECK_EQUAL( cont.size(), boost::count_if(cref_cont, true_predicate()) );
|
||||
BOOST_CHECK_EQUAL( cont.size(), boost::count_if(boost::make_iterator_range(cont), true_predicate()) );
|
||||
BOOST_CHECK_EQUAL( boost::size(cont), boost::count_if(cont, true_predicate()) );
|
||||
BOOST_CHECK_EQUAL( boost::size(cont), boost::count_if(cref_cont, true_predicate()) );
|
||||
BOOST_CHECK_EQUAL( boost::size(cont), boost::count_if(boost::make_iterator_range(cont), true_predicate()) );
|
||||
}
|
||||
|
||||
void test_count_if()
|
||||
|
||||
@@ -21,6 +21,104 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename ForwardIterator, typename Integer, typename Value>
|
||||
inline ForwardIterator
|
||||
reference_search_n(ForwardIterator first, ForwardIterator last,
|
||||
Integer count, const Value& value)
|
||||
{
|
||||
if (count <= 0)
|
||||
return first;
|
||||
else if (count == 1)
|
||||
return std::find(first, last, value);
|
||||
else
|
||||
{
|
||||
first = std::find(first, last, value);
|
||||
while (first != last)
|
||||
{
|
||||
typename std::iterator_traits<ForwardIterator>::difference_type n = count;
|
||||
ForwardIterator i = first;
|
||||
++i;
|
||||
while (i != last && n != 1 && *i==value)
|
||||
{
|
||||
++i;
|
||||
--n;
|
||||
}
|
||||
if (n == 1)
|
||||
return first;
|
||||
if (i == last)
|
||||
return last;
|
||||
first = std::find(++i, last, value);
|
||||
}
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
template<typename ForwardIterator, typename Integer, typename Value,
|
||||
typename BinaryPredicate>
|
||||
inline ForwardIterator
|
||||
reference_search_n(ForwardIterator first, ForwardIterator last,
|
||||
Integer count, const Value& value,
|
||||
BinaryPredicate pred)
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
|
||||
|
||||
if (count <= 0)
|
||||
return first;
|
||||
if (count == 1)
|
||||
{
|
||||
while (first != last && !static_cast<bool>(pred(*first, value)))
|
||||
++first;
|
||||
return first;
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_t;
|
||||
|
||||
while (first != last && !static_cast<bool>(pred(*first, value)))
|
||||
++first;
|
||||
|
||||
while (first != last)
|
||||
{
|
||||
difference_t n = count;
|
||||
ForwardIterator i = first;
|
||||
++i;
|
||||
while (i != last && n != 1 && static_cast<bool>(pred(*i, value)))
|
||||
{
|
||||
++i;
|
||||
--n;
|
||||
}
|
||||
if (n == 1)
|
||||
return first;
|
||||
if (i == last)
|
||||
return last;
|
||||
first = ++i;
|
||||
while (first != last && !static_cast<bool>(pred(*first, value)))
|
||||
++first;
|
||||
}
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
template< class Container1, class Value, class Pred >
|
||||
void test_search_n_pred_impl(Container1& cont1, Value value, Pred pred)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME Container1::const_iterator const_iterator1_t;
|
||||
typedef BOOST_DEDUCED_TYPENAME Container1::iterator iterator1_t;
|
||||
|
||||
const Container1& ccont1 = cont1;
|
||||
|
||||
for (std::size_t n = 0; n < cont1.size(); ++n)
|
||||
{
|
||||
iterator1_t it = boost::search_n(cont1, n, value, pred);
|
||||
BOOST_CHECK( it == boost::search_n(boost::make_iterator_range(cont1), n, value, pred) );
|
||||
BOOST_CHECK( it == reference_search_n(cont1.begin(), cont1.end(), n, value, pred) );
|
||||
|
||||
const_iterator1_t cit = boost::search_n(ccont1, n, value, pred);
|
||||
BOOST_CHECK( cit == boost::search_n(boost::make_iterator_range(ccont1), n, value, pred) );
|
||||
BOOST_CHECK( cit == reference_search_n(ccont1.begin(), ccont1.end(), n, value, pred) );
|
||||
}
|
||||
}
|
||||
|
||||
template< class Container1, class Value >
|
||||
void test_search_n_impl(Container1& cont1, Value value)
|
||||
{
|
||||
@@ -33,12 +131,17 @@ namespace
|
||||
{
|
||||
iterator1_t it = boost::search_n(cont1, n, value);
|
||||
BOOST_CHECK( it == boost::search_n(boost::make_iterator_range(cont1), n, value) );
|
||||
BOOST_CHECK( it == std::search_n(cont1.begin(), cont1.end(), n, value) );
|
||||
BOOST_CHECK( it == reference_search_n(cont1.begin(), cont1.end(), n, value) );
|
||||
|
||||
const_iterator1_t cit = boost::search_n(ccont1, n, value);
|
||||
BOOST_CHECK( cit == boost::search_n(boost::make_iterator_range(ccont1), n, value) );
|
||||
BOOST_CHECK( cit == std::search_n(ccont1.begin(), ccont1.end(), n, value) );
|
||||
BOOST_CHECK( cit == reference_search_n(ccont1.begin(), ccont1.end(), n, value) );
|
||||
}
|
||||
|
||||
test_search_n_pred_impl(cont1, value, std::less<int>());
|
||||
test_search_n_pred_impl(cont1, value, std::greater<int>());
|
||||
test_search_n_pred_impl(cont1, value, std::equal_to<int>());
|
||||
test_search_n_pred_impl(cont1, value, std::not_equal_to<int>());
|
||||
}
|
||||
|
||||
template< class Container1, class Container2 >
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
// Boost.Range library
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
# pragma warn -8091 // supress warning in Boost.Test
|
||||
# pragma warn -8057 // unused argument argc/argv in Boost.Test
|
||||
#endif
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
namespace boost_range_extension_size_test
|
||||
{
|
||||
class FooWithoutMemberSize
|
||||
{
|
||||
typedef std::list<int> impl_t;
|
||||
typedef impl_t::const_iterator const_iterator;
|
||||
typedef impl_t::iterator iterator;
|
||||
|
||||
public:
|
||||
friend inline const_iterator range_begin(const FooWithoutMemberSize& obj) { return obj.m_impl.begin(); }
|
||||
friend inline iterator range_begin(FooWithoutMemberSize& obj) { return obj.m_impl.begin(); }
|
||||
friend inline const_iterator range_end(const FooWithoutMemberSize& obj) { return obj.m_impl.end(); }
|
||||
friend inline iterator range_end(FooWithoutMemberSize& obj){ return obj.m_impl.end(); }
|
||||
|
||||
private:
|
||||
impl_t m_impl;
|
||||
};
|
||||
|
||||
boost::range_difference<std::list<int> >::type
|
||||
inline range_calculate_size(const FooWithoutMemberSize& rng)
|
||||
{
|
||||
return 2u;
|
||||
}
|
||||
}
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<> struct range_iterator<const ::boost_range_extension_size_test::FooWithoutMemberSize>
|
||||
{
|
||||
typedef std::list<int>::const_iterator type;
|
||||
};
|
||||
|
||||
template<> struct range_iterator< ::boost_range_extension_size_test::FooWithoutMemberSize >
|
||||
{
|
||||
typedef std::list<int>::iterator type;
|
||||
};
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void check_size_works_with_less_than_random_access()
|
||||
{
|
||||
std::list<int> container;
|
||||
container.push_back(1);
|
||||
BOOST_CHECK_EQUAL( boost::size(container), 1u );
|
||||
}
|
||||
|
||||
void check_size_works_with_random_access()
|
||||
{
|
||||
std::vector<int> container;
|
||||
container.push_back(1);
|
||||
BOOST_CHECK_EQUAL( boost::size(container), 1u );
|
||||
}
|
||||
|
||||
class FooWithMemberSize
|
||||
{
|
||||
public:
|
||||
typedef std::list<int> impl_t;
|
||||
typedef impl_t::const_iterator const_iterator;
|
||||
typedef impl_t::iterator iterator;
|
||||
typedef impl_t::value_type value_type;
|
||||
|
||||
std::size_t size() const { return 1u; }
|
||||
const_iterator begin() const { return m_impl.begin(); }
|
||||
iterator begin() { return m_impl.begin(); }
|
||||
const_iterator end() const { return m_impl.end(); }
|
||||
iterator end() { return m_impl.end(); }
|
||||
|
||||
private:
|
||||
std::list<int> m_impl;
|
||||
};
|
||||
|
||||
void check_extension_size()
|
||||
{
|
||||
BOOST_CHECK_EQUAL( boost::size(FooWithMemberSize()), 1u );
|
||||
BOOST_CHECK_EQUAL( boost::size(boost_range_extension_size_test::FooWithoutMemberSize()), 2u );
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
using boost::unit_test::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_size_works_with_less_than_random_access ));
|
||||
test->add( BOOST_TEST_CASE( &check_size_works_with_random_access ));
|
||||
test->add( BOOST_TEST_CASE( &check_extension_size ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// Boost.Range library
|
||||
//
|
||||
// Copyright Neil Groves 2010. 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/range/has_range_iterator.hpp>
|
||||
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
class MockClassWithoutIterators {};
|
||||
|
||||
template<typename Container>
|
||||
void test_has_range_iterator_impl(const bool expected_value)
|
||||
{
|
||||
BOOST_CHECK_EQUAL( boost::has_range_iterator<Container>::value, expected_value );
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
void test_has_range_const_iterator_impl(const bool expected_value)
|
||||
{
|
||||
BOOST_CHECK_EQUAL( boost::has_range_const_iterator<Container>::value, expected_value );
|
||||
}
|
||||
|
||||
void test_has_range_iterator()
|
||||
{
|
||||
test_has_range_iterator_impl< std::vector<int> >(true);
|
||||
test_has_range_iterator_impl< MockClassWithoutIterators >(false);
|
||||
}
|
||||
|
||||
void test_has_range_const_iterator()
|
||||
{
|
||||
test_has_range_const_iterator_impl< std::vector<int> >(true);
|
||||
test_has_range_const_iterator_impl< MockClassWithoutIterators >(false);
|
||||
}
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite*
|
||||
init_unit_test_suite(int argc, char* argv[])
|
||||
{
|
||||
boost::unit_test::test_suite* test
|
||||
= BOOST_TEST_SUITE( "RangeTestSuite.has_range_iterator" );
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_has_range_iterator));
|
||||
test->add(BOOST_TEST_CASE(&test_has_range_const_iterator));
|
||||
|
||||
return test;
|
||||
}
|
||||
+39
-37
@@ -42,7 +42,7 @@ namespace
|
||||
typedef std::size_t size_type;
|
||||
typedef value_type array_t[Length];
|
||||
typedef const value_type const_array_t[Length];
|
||||
|
||||
|
||||
explicit test_string(const CharT literal_sz[])
|
||||
{
|
||||
std::copy(literal_sz, literal_sz + Length, m_buffer.data());
|
||||
@@ -62,35 +62,35 @@ template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::type
|
||||
str_begin( T& r )
|
||||
{
|
||||
return boost::begin( boost::as_literal(r) );
|
||||
return boost::begin( boost::as_literal(r) );
|
||||
}
|
||||
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::type
|
||||
str_end( T& r )
|
||||
{
|
||||
return boost::end( boost::as_literal(r) );
|
||||
return boost::end( boost::as_literal(r) );
|
||||
}
|
||||
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME boost::range_size<T>::type
|
||||
inline BOOST_DEDUCED_TYPENAME boost::range_difference<T>::type
|
||||
str_size( const T& r )
|
||||
{
|
||||
return boost::size( boost::as_literal(r) );
|
||||
return boost::size( boost::as_literal(r) );
|
||||
}
|
||||
|
||||
template< class T >
|
||||
inline bool
|
||||
str_empty( T& r )
|
||||
{
|
||||
return boost::empty( boost::as_literal(r) );
|
||||
return boost::empty( boost::as_literal(r) );
|
||||
}
|
||||
|
||||
template< typename Container, typename T >
|
||||
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
|
||||
find( Container& c, T value )
|
||||
{
|
||||
return std::find( str_begin(c), str_end(c),
|
||||
return std::find( str_begin(c), str_end(c),
|
||||
value );
|
||||
}
|
||||
|
||||
@@ -98,16 +98,16 @@ template< typename Container, typename T >
|
||||
BOOST_DEDUCED_TYPENAME boost::range_iterator<const Container>::type
|
||||
find( const Container& c, T value )
|
||||
{
|
||||
return std::find( str_begin(c), str_end(c),
|
||||
return std::find( str_begin(c), str_end(c),
|
||||
value );
|
||||
}
|
||||
|
||||
template< typename Container, typename T >
|
||||
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
|
||||
find_mutable( Container& c, T value )
|
||||
{
|
||||
{
|
||||
str_size( c );
|
||||
return std::find( str_begin(c), str_end(c),
|
||||
return std::find( str_begin(c), str_end(c),
|
||||
value );
|
||||
}
|
||||
|
||||
@@ -116,15 +116,15 @@ BOOST_DEDUCED_TYPENAME boost::range_iterator<const Container>::type
|
||||
find_const( const Container& c, T value )
|
||||
{
|
||||
str_size( c );
|
||||
return std::find( str_begin(c), str_end(c),
|
||||
return std::find( str_begin(c), str_end(c),
|
||||
value );
|
||||
}
|
||||
|
||||
|
||||
std::vector<char>
|
||||
std::vector<char>
|
||||
check_rvalue_return()
|
||||
{
|
||||
return std::vector<char>( 10, 'm' );
|
||||
return std::vector<char>( 10, 'm' );
|
||||
}
|
||||
|
||||
using namespace boost;
|
||||
@@ -132,44 +132,45 @@ using namespace boost;
|
||||
|
||||
void check_char()
|
||||
{
|
||||
typedef boost::range_difference<std::string>::type diff_t;
|
||||
typedef char* char_iterator_t;
|
||||
typedef char char_array_t[10];
|
||||
|
||||
|
||||
test_string<char, 8> a_string("a string");
|
||||
test_string<char, 14> another_string("another string");
|
||||
|
||||
const char* char_s = a_string.const_sz();
|
||||
char my_string[] = "another_string";
|
||||
const char my_const_string[] = "another string";
|
||||
const unsigned my_string_length = 14;
|
||||
const diff_t my_string_length = 14;
|
||||
char* char_s2 = a_string.mutable_sz();
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<char_iterator_t>::type,
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<char_iterator_t>::type,
|
||||
detail::iterator_traits<char_iterator_t>::value_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<char_iterator_t>::type, char_iterator_t >::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<char_iterator_t>::type,
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<char_iterator_t>::type,
|
||||
::std::ptrdiff_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<char_iterator_t>::type, std::size_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<char_iterator_t>::type, char_iterator_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<const char*>::type, const char* >::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<char_array_t>::type,
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<char_array_t>::type,
|
||||
char>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<char_array_t>::type, char* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<const char_array_t>::type, const char* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<char_array_t>::type,
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<char_array_t>::type,
|
||||
::std::ptrdiff_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<char_array_t>::type, std::size_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<char_array_t>::type, char* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<const char_array_t>::type, const char* >::value ));
|
||||
|
||||
BOOST_CHECK_EQUAL( str_begin( char_s ), char_s );
|
||||
std::size_t sz = str_size(char_s);
|
||||
const char* str_end1 = str_begin( char_s ) + sz;
|
||||
const diff_t sz = str_size(char_s);
|
||||
const char* str_end1 = str_begin( char_s ) + sz;
|
||||
BOOST_CHECK_EQUAL( str_end( char_s ), str_end1 );
|
||||
BOOST_CHECK_EQUAL( str_empty( char_s ), (char_s == 0 || char_s[0] == char()) );
|
||||
BOOST_CHECK_EQUAL( sz, std::char_traits<char>::length( char_s ) );
|
||||
BOOST_CHECK_EQUAL( sz, static_cast<diff_t>(std::char_traits<char>::length(char_s)) );
|
||||
|
||||
BOOST_CHECK_EQUAL( str_begin( my_string ), my_string );
|
||||
range_iterator<char_array_t>::type str_end2 = str_begin( my_string ) + str_size(my_string);
|
||||
@@ -177,7 +178,7 @@ void check_char()
|
||||
BOOST_CHECK_EQUAL( str_end3, str_end2 );
|
||||
BOOST_CHECK_EQUAL( str_empty( my_string ), (my_string == 0 || my_string[0] == char()) );
|
||||
BOOST_CHECK_EQUAL( str_size( my_string ), my_string_length );
|
||||
BOOST_CHECK_EQUAL( str_size( my_string ), std::char_traits<char>::length( my_string ) );
|
||||
BOOST_CHECK_EQUAL( str_size( my_string ), static_cast<diff_t>(std::char_traits<char>::length(my_string)) );
|
||||
|
||||
char to_search = 'n';
|
||||
BOOST_CHECK( find_mutable( char_s, to_search ) != str_end( char_s ) );
|
||||
@@ -186,7 +187,7 @@ void check_char()
|
||||
BOOST_CHECK( find_mutable( my_string, to_search ) != str_end(my_string) );
|
||||
BOOST_CHECK( find_const( my_string, to_search ) != str_end(my_string) );
|
||||
|
||||
BOOST_CHECK( find_mutable( char_s2, to_search ) != str_end(char_s) );
|
||||
BOOST_CHECK( find_mutable( char_s2, to_search ) != str_end(char_s) );
|
||||
BOOST_CHECK( find_const( char_s2, to_search ) != str_end(char_s2) );
|
||||
|
||||
BOOST_CHECK( find_const( as_array( my_string ), to_search ) != str_end(my_string) );
|
||||
@@ -212,32 +213,33 @@ void check_char()
|
||||
void check_string()
|
||||
{
|
||||
check_char();
|
||||
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
typedef wchar_t* wchar_iterator_t;
|
||||
|
||||
test_string<wchar_t, 13> a_wide_string(L"a wide string");
|
||||
test_string<wchar_t, 19> another_wide_string(L"another wide string");
|
||||
|
||||
|
||||
const wchar_t* char_ws = a_wide_string.const_sz();
|
||||
wchar_t my_wstring[] = L"another wide string";
|
||||
wchar_t* char_ws2 = a_wide_string.mutable_sz();
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<wchar_iterator_t>::type,
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<wchar_iterator_t>::type,
|
||||
detail::iterator_traits<wchar_iterator_t>::value_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<const wchar_t*>::type, const wchar_t* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<wchar_iterator_t>::type,
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<wchar_iterator_t>::type,
|
||||
detail::iterator_traits<wchar_iterator_t>::difference_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<wchar_iterator_t>::type, std::size_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<const wchar_t*>::type, const wchar_t* >::value ));
|
||||
|
||||
std::size_t sz = str_size( char_ws );
|
||||
|
||||
typedef boost::range_difference<std::wstring>::type diff_t;
|
||||
const diff_t sz = str_size( char_ws );
|
||||
BOOST_CHECK_EQUAL( str_begin( char_ws ), char_ws );
|
||||
BOOST_CHECK_EQUAL( str_end(char_ws), (str_begin( char_ws ) + sz) );
|
||||
BOOST_CHECK_EQUAL( str_empty( char_ws ), (char_ws == 0 || char_ws[0] == wchar_t()) );
|
||||
BOOST_CHECK_EQUAL( sz, std::char_traits<wchar_t>::length( char_ws ) );
|
||||
BOOST_CHECK_EQUAL( sz, static_cast<diff_t>(std::char_traits<wchar_t>::length(char_ws)) );
|
||||
|
||||
wchar_t to_search = L'n';
|
||||
BOOST_CHECK( find( char_ws, to_search ) != str_end(char_ws) );
|
||||
@@ -250,10 +252,10 @@ void check_string()
|
||||
#else
|
||||
|
||||
boost::ignore_unused_variable_warning( my_wstring );
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
find( check_rvalue_return(), 'n' );
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace boost
|
||||
struct check_results
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
Iterator test_it,
|
||||
@@ -43,7 +43,7 @@ namespace boost
|
||||
struct check_results<return_found>
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
Iterator test_it,
|
||||
@@ -64,7 +64,7 @@ namespace boost
|
||||
struct check_results<return_next>
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
Iterator test_it,
|
||||
@@ -93,7 +93,7 @@ namespace boost
|
||||
struct check_results<return_prior>
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
Iterator test_it,
|
||||
@@ -122,7 +122,7 @@ namespace boost
|
||||
struct check_results<return_begin_found>
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
iterator_range<Iterator> test_rng,
|
||||
@@ -149,7 +149,7 @@ namespace boost
|
||||
struct check_results<return_begin_next>
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
iterator_range<Iterator> test_rng,
|
||||
@@ -182,7 +182,7 @@ namespace boost
|
||||
struct check_results<return_begin_prior>
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
iterator_range<Iterator> test_rng,
|
||||
@@ -212,7 +212,7 @@ namespace boost
|
||||
struct check_results<return_found_end>
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
iterator_range<Iterator> test_rng,
|
||||
@@ -236,7 +236,7 @@ namespace boost
|
||||
struct check_results<return_next_end>
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
iterator_range<Iterator> test_rng,
|
||||
@@ -270,7 +270,7 @@ namespace boost
|
||||
struct check_results<return_prior_end>
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
iterator_range<Iterator> test_rng,
|
||||
@@ -304,7 +304,7 @@ namespace boost
|
||||
struct check_results<return_begin_end>
|
||||
{
|
||||
template< class Container, class Iterator >
|
||||
static void check(
|
||||
static void test(
|
||||
Container& test,
|
||||
Container& reference,
|
||||
iterator_range<Iterator> test_rng,
|
||||
@@ -375,8 +375,8 @@ namespace boost
|
||||
iterator_t range_result = policy.test_iter(test);
|
||||
iterator_t reference_it = policy.reference(reference);
|
||||
|
||||
check_results<return_found>::check(test, reference,
|
||||
range_result, reference_it);
|
||||
check_results<return_found>::test(test, reference,
|
||||
range_result, reference_it);
|
||||
}
|
||||
|
||||
template< range_return_value result_type, class Container, class TestPolicy >
|
||||
@@ -394,8 +394,8 @@ namespace boost
|
||||
range_return_t range_result = test_range_t()(policy, test_cont);
|
||||
iterator_t reference_it = policy.reference(reference);
|
||||
|
||||
check_results<result_type>::check(test_cont, reference,
|
||||
range_result, reference_it);
|
||||
check_results<result_type>::test(test_cont, reference,
|
||||
range_result, reference_it);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user