early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -0,0 +1,226 @@
# Boost.Range library
#
# Copyright Neil Groves 2009
# 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/
#
# bring in rules for testing
import testing ;
project
: requirements
<library>/boost/test//boost_unit_test_framework/
<library>/boost/regex//boost_regex/
<link>static
<threading>multi
;
rule range-test ( name : includes * )
{
return [
run $(name).cpp /boost/test//boost_unit_test_framework /boost/regex//boost_regex/<link>static
:
:
: <toolset>gcc:<cxxflags>"-Wall -Wunused "
] ;
}
test-suite range :
[ compile-fail compile_fail/iterator_range1.cpp ]
[ compile-fail compile_fail/adaptor/adjacent_filtered_concept.cpp ]
[ compile-fail compile_fail/adaptor/adjacent_filtered_concept2.cpp ]
[ compile-fail compile_fail/adaptor/adjacent_filtered_concept3.cpp ]
[ compile-fail compile_fail/adaptor/adjacent_filtered_concept4.cpp ]
[ compile-fail compile_fail/adaptor/copied_concept.cpp ]
[ compile-fail compile_fail/adaptor/copied_concept2.cpp ]
[ compile-fail compile_fail/adaptor/copied_concept3.cpp ]
[ compile-fail compile_fail/adaptor/copied_concept4.cpp ]
[ compile-fail compile_fail/adaptor/reversed_concept.cpp ]
[ compile-fail compile_fail/adaptor/reversed_concept2.cpp ]
[ compile-fail compile_fail/adaptor/reversed_concept3.cpp ]
[ compile-fail compile_fail/adaptor/reversed_concept4.cpp ]
[ compile-fail compile_fail/adaptor/sliced_concept.cpp ]
[ compile-fail compile_fail/adaptor/sliced_concept2.cpp ]
[ compile-fail compile_fail/adaptor/sliced_concept3.cpp ]
[ compile-fail compile_fail/adaptor/sliced_concept4.cpp ]
[ compile-fail compile_fail/adaptor/uniqued_concept.cpp ]
[ compile-fail compile_fail/adaptor/uniqued_concept2.cpp ]
[ compile-fail compile_fail/adaptor/uniqued_concept3.cpp ]
[ compile-fail compile_fail/adaptor/uniqued_concept4.cpp ]
[ range-test adaptor_test/adjacent_filtered ]
[ range-test adaptor_test/chained ]
[ range-test adaptor_test/copied ]
[ range-test adaptor_test/filtered ]
[ range-test adaptor_test/indexed ]
[ range-test adaptor_test/indirected ]
[ range-test adaptor_test/map ]
[ range-test adaptor_test/ref_unwrapped ]
[ range-test adaptor_test/ref_unwrapped_example ]
[ range-test adaptor_test/replaced ]
[ range-test adaptor_test/replaced_if ]
[ range-test adaptor_test/reversed ]
[ range-test adaptor_test/sliced ]
[ range-test adaptor_test/strided ]
[ range-test adaptor_test/strided2 ]
[ range-test adaptor_test/ticket_6742_transformed_c4789_warning ]
[ range-test adaptor_test/ticket_8676_sliced_transformed ]
[ range-test adaptor_test/ticket_9519_strided_reversed ]
[ range-test adaptor_test/tokenized ]
[ range-test adaptor_test/transformed ]
[ range-test adaptor_test/type_erased ]
[ range-test adaptor_test/type_erased_abstract ]
[ range-test adaptor_test/type_erased_brackets ]
[ range-test adaptor_test/type_erased_mix_values ]
[ range-test adaptor_test/type_erased_tparam_conv ]
[ range-test adaptor_test/type_erased_single_pass ]
[ range-test adaptor_test/type_erased_forward ]
[ range-test adaptor_test/type_erased_bidirectional ]
[ range-test adaptor_test/type_erased_random_access ]
[ range-test adaptor_test/type_erased_transformed ]
[ range-test adaptor_test/uniqued ]
[ range-test adaptor_test/adjacent_filtered_example ]
[ range-test adaptor_test/copied_example ]
[ range-test adaptor_test/filtered_example ]
[ range-test adaptor_test/formatted ]
[ range-test adaptor_test/formatted_example ]
[ range-test adaptor_test/indexed_example ]
[ range-test adaptor_test/indirected_example ]
[ range-test adaptor_test/map_keys_example ]
[ range-test adaptor_test/map_values_example ]
[ range-test adaptor_test/replaced_example ]
[ range-test adaptor_test/replaced_if_example ]
[ range-test adaptor_test/reversed_example ]
[ range-test adaptor_test/sliced_example ]
[ range-test adaptor_test/strided_example ]
[ range-test adaptor_test/transformed_example ]
[ range-test adaptor_test/tokenized_example ]
[ range-test adaptor_test/type_erased_example ]
[ range-test adaptor_test/uniqued_example ]
[ range-test algorithm_test/adjacent_find ]
[ range-test algorithm_test/binary_search ]
[ range-test algorithm_test/copy ]
[ range-test algorithm_test/copy_backward ]
[ range-test algorithm_test/count ]
[ range-test algorithm_test/count_if ]
[ range-test algorithm_test/equal ]
[ range-test algorithm_test/equal_range ]
[ range-test algorithm_test/fill ]
[ range-test algorithm_test/find ]
[ range-test algorithm_test/find_if ]
[ range-test algorithm_test/find_end ]
[ range-test algorithm_test/find_first_of ]
[ range-test algorithm_test/for_each ]
[ range-test algorithm_test/generate ]
[ range-test algorithm_test/heap ]
[ range-test algorithm_test/includes ]
[ range-test algorithm_test/inplace_merge ]
[ range-test algorithm_test/lexicographical_compare ]
[ range-test algorithm_test/lower_bound ]
[ range-test algorithm_test/max_element ]
[ range-test algorithm_test/merge ]
[ range-test algorithm_test/min_element ]
[ range-test algorithm_test/mismatch ]
[ range-test algorithm_test/next_permutation ]
[ range-test algorithm_test/nth_element ]
[ range-test algorithm_test/partial_sort ]
[ range-test algorithm_test/partition ]
[ range-test algorithm_test/prev_permutation ]
[ range-test algorithm_test/random_shuffle ]
[ range-test algorithm_test/remove ]
[ range-test algorithm_test/remove_copy ]
[ range-test algorithm_test/remove_copy_if ]
[ range-test algorithm_test/remove_if ]
[ range-test algorithm_test/replace ]
[ range-test algorithm_test/replace_copy ]
[ range-test algorithm_test/replace_copy_if ]
[ range-test algorithm_test/replace_if ]
[ range-test algorithm_test/reverse ]
[ range-test algorithm_test/reverse_copy ]
[ range-test algorithm_test/rotate ]
[ range-test algorithm_test/rotate_copy ]
[ range-test algorithm_test/search ]
[ range-test algorithm_test/search_n ]
[ range-test algorithm_test/set_difference ]
[ range-test algorithm_test/set_intersection ]
[ range-test algorithm_test/set_symmetric_difference ]
[ range-test algorithm_test/set_union ]
[ range-test algorithm_test/sort ]
[ range-test algorithm_test/stable_partition ]
[ range-test algorithm_test/stable_sort ]
[ range-test algorithm_test/swap_ranges ]
[ range-test algorithm_test/transform ]
[ range-test algorithm_test/unique ]
[ range-test algorithm_test/unique_copy ]
[ range-test algorithm_test/upper_bound ]
[ range-test algorithm_ext_test/copy_n ]
[ range-test algorithm_ext_test/erase ]
[ range-test algorithm_ext_test/for_each_ext ]
[ range-test algorithm_ext_test/insert ]
[ range-test algorithm_ext_test/iota ]
[ range-test algorithm_ext_test/is_sorted ]
[ range-test algorithm_ext_test/overwrite ]
[ range-test algorithm_ext_test/push_back ]
[ range-test algorithm_ext_test/push_front ]
[ range-test adl_conformance ]
[ range-test adl_conformance_no_using ]
[ range-test algorithm ]
[ range-test algorithm_example ]
[ range-test array ]
# [ range-test atl : <include>$(VC71_ROOT)/atlmfc/include ]
[ range-test begin ]
[ range-test category ]
[ range-test combine ]
[ range-test compat2 ]
[ range-test compat3 ]
[ range-test const_iterator ]
[ range-test const_ranges ]
[ range-test const_reverse_iterator ]
[ range-test counting_range ]
[ range-test difference_type ]
[ range-test end ]
[ range-test extension_mechanism ]
[ range-test extension_size ]
[ range-test has_range_iterator ]
[ range-test irange ]
[ range-test istream_range ]
[ range-test iterator ]
[ range-test iterator_ext ]
[ range-test iterator_pair ]
[ range-test iterator_range ]
[ range-test iterator_range_drop ]
[ range-test iterator_range_equality_bug ]
[ range-test iterator_range_hash ]
[ range-test iterator_range_variant ]
# [ range-test mfc : <include>$(VC71_ROOT)/atlmfc/include ]
[ range-test join ]
[ range-test mutable_iterator ]
[ range-test partial_workaround ]
[ range-test pointer ]
[ range-test pointer_as_iterator ]
[ range-test reference ]
[ range-test result_iterator ]
[ range-test reverse_iterator ]
[ range-test reverse_result_iterator ]
[ range-test reversible_range ]
[ range-test size_type ]
[ range-test std_container ]
[ range-test string ]
[ range-test sub_range ]
[ range-test ticket_5486 ]
[ range-test ticket_5544_terminate_irange ]
[ range-test ticket_5547 ]
[ range-test ticket_5556_is_sorted_namespace ]
[ range-test ticket_5811_indirected_optional ]
[ range-test ticket_6715_iterator_range_equality ]
[ range-test ticket_6944 ]
[ range-test ticket_10336 ]
[ range-test value_type ]
;
# `quick` target (for CI)
alias quick : std_container ;

View File

@@ -0,0 +1,110 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/adjacent_filtered.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <string>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void adjacent_filtered_test_impl( Container& c )
{
using namespace boost::adaptors;
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
// This is my preferred syntax using the | operator.
std::vector< value_t > test_result1
= boost::copy_range< std::vector< value_t > >(
c | adjacent_filtered(std::not_equal_to< value_t >()));
// This is an alternative syntax preferred by some.
std::vector< value_t > test_result2
= boost::copy_range< std::vector< value_t > >(
adaptors::adjacent_filter(c, std::not_equal_to< value_t >()));
// Calculate the reference result.
std::vector< value_t > reference_result;
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iter_t;
value_t prev_v = value_t();
for (iter_t it = c.begin(); it != c.end(); ++it)
{
if (it == c.begin())
{
reference_result.push_back(*it);
}
else if (*it != prev_v)
{
reference_result.push_back(*it);
}
prev_v = *it;
}
BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
reference_result.end(),
test_result1.begin(),
test_result1.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
reference_result.end(),
test_result2.begin(),
test_result2.end() );
}
template< class Collection >
void adjacent_filtered_test_impl()
{
using namespace boost::assign;
Collection c;
// test empty collection
adjacent_filtered_test_impl(c);
// test one element;
c += 1;
adjacent_filtered_test_impl(c);
// test many elements;
c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
adjacent_filtered_test_impl(c);
}
void adjacent_filtered_test()
{
adjacent_filtered_test_impl< std::vector< int > >();
adjacent_filtered_test_impl< std::list< int > >();
adjacent_filtered_test_impl< std::set< int > >();
adjacent_filtered_test_impl< std::multiset< int > >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.adjacent_filtered" );
test->add( BOOST_TEST_CASE( &boost::adjacent_filtered_test ) );
return test;
}

View File

@@ -0,0 +1,65 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[adjacent_filtered_example
#include <boost/range/adaptor/adjacent_filtered.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <functional>
#include <iostream>
#include <vector>
//<-
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
namespace
{
void adjacent_filtered_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::assign;
using namespace boost::adaptors;
std::vector<int> input;
input += 1,1,2,2,2,3,4,5,6;
boost::copy(
input | adjacent_filtered(std::not_equal_to<int>()),
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 1,2,3,4,5,6;
std::vector<int> test;
boost::push_back(test, input | adjacent_filtered(std::not_equal_to<int>()));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.adjacent_filtered_example" );
test->add( BOOST_TEST_CASE( &adjacent_filtered_example_test ) );
return test;
}

View File

@@ -0,0 +1,119 @@
// 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/
//
// Credits:
// Jurgen Hunold provided a test case that demonstrated that the range adaptors
// were producing iterators that were not default constructible. This became
// symptomatic after enabling concept checking assertions. This test is a
// lightly modified version of his supplied code to ensure that his use case
// never breaks again. (hopefully!)
//
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/bind/bind.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <vector>
#include <set>
namespace boost_range_test
{
namespace
{
class foo
{
public:
static foo from_string(const std::string& source)
{
foo f;
f.m_valid = true;
f.m_value = 0u;
for (std::string::const_iterator it = source.begin();
it != source.end(); ++it)
{
f.m_value += *it;
if ((*it < 'a') || (*it > 'z'))
f.m_valid = false;
}
return f;
}
bool is_valid() const
{
return m_valid;
}
bool operator<(const foo& other) const
{
return m_value < other.m_value;
}
bool operator==(const foo& other) const
{
return m_value == other.m_value && m_valid == other.m_valid;
}
bool operator!=(const foo& other) const
{
return !operator==(other);
}
friend inline std::ostream& operator<<(std::ostream& out, const foo& obj)
{
out << "{value=" << obj.m_value
<< ", valid=" << std::boolalpha << obj.m_valid << "}\n";
return out;
}
private:
boost::uint64_t m_value;
bool m_valid;
};
void chained_adaptors_test()
{
std::vector<std::string> sep;
sep.push_back("AB");
sep.push_back("ab");
sep.push_back("aghj");
std::set<foo> foos;
using namespace boost::placeholders;
boost::copy(sep
| boost::adaptors::transformed(boost::bind(&foo::from_string, _1))
| boost::adaptors::filtered(boost::bind(&foo::is_valid, _1)),
std::inserter(foos, foos.end()));
std::vector<foo> reference;
reference.push_back(foo::from_string("ab"));
reference.push_back(foo::from_string("aghj"));
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
foos.begin(), foos.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( "RangeTestSuite.adaptor.chained adaptors" );
test->add(BOOST_TEST_CASE( boost_range_test::chained_adaptors_test));
return test;
}

View File

@@ -0,0 +1,84 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/copied.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <deque>
#include <string>
#include <vector>
#include <boost/range/algorithm_ext.hpp>
namespace boost
{
namespace
{
template< class Container >
void copied_test_impl( Container& c )
{
using namespace boost::adaptors;
// This is my preferred syntax using the | operator.
std::vector< int > test_result1;
boost::push_back(test_result1, c | copied(0u, c.size()));
// This is the alternative syntax preferred by some.
std::vector< int > test_result2;
boost::push_back(test_result2, adaptors::copy(c, 0u, c.size()));
BOOST_CHECK_EQUAL_COLLECTIONS( test_result1.begin(), test_result1.end(),
c.begin(), c.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( test_result2.begin(), test_result2.end(),
c.begin(), c.end() );
}
template< class Container >
void copied_test_impl()
{
using namespace boost::assign;
Container c;
// test empty collection
copied_test_impl(c);
// test one element
c += 1;
copied_test_impl(c);
// test many elements
c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
copied_test_impl(c);
}
void copied_test()
{
copied_test_impl< std::vector< int > >();
copied_test_impl< std::deque< int > >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.copied" );
test->add( BOOST_TEST_CASE( &boost::copied_test ) );
return test;
}

View File

@@ -0,0 +1,64 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[copied_example
#include <boost/range/adaptor/copied.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
namespace
{
void copied_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::assign;
using namespace boost::adaptors;
std::vector<int> input;
input += 1,2,3,4,5,6,7,8,9,10;
boost::copy(
input | copied(1, 5),
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 2,3,4,5;
std::vector<int> test;
boost::push_back(test, input | copied(1, 5));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.copied_example" );
test->add( BOOST_TEST_CASE( &copied_example_test ) );
return test;
}

View File

@@ -0,0 +1,197 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/filtered.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <string>
#include <vector>
#include <sstream>
namespace boost
{
namespace
{
struct always_false_pred
{
template< class T1 >
bool operator()(T1) const { return false; }
};
struct always_true_pred
{
template< class T1 >
bool operator()(T1) const { return true; }
};
struct is_even
{
template< class IntegerT >
bool operator()( IntegerT x ) const { return x % 2 == 0; }
};
struct is_odd
{
template< class IntegerT >
bool operator()( IntegerT x ) const { return x % 2 != 0; }
};
struct lambda_init
{
};
struct lambda
{
lambda(const lambda_init& init) {}
lambda(const lambda& rhs) {}
template< class T1 >
bool operator()(T1) const { return false; }
private:
lambda() {}
lambda& operator=(const lambda& rhs) { return *this; }
};
template< class Container, class Pred >
void filtered_test_impl( Container& c, Pred pred )
{
using namespace boost::adaptors;
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
// This is my preferred syntax using the | operator.
std::vector< value_t > test_result1;
boost::push_back(test_result1, c | filtered(pred));
// This is an alternative syntax preferred by some.
std::vector< value_t > test_result2;
boost::push_back(test_result2, adaptors::filter(c, pred));
// Calculate the reference result.
std::vector< value_t > reference_result;
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iter_t;
for (iter_t it = c.begin(); it != c.end(); ++it)
{
if (pred(*it))
reference_result.push_back(*it);
}
BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
reference_result.end(),
test_result1.begin(),
test_result1.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
reference_result.end(),
test_result2.begin(),
test_result2.end() );
}
template< class Rng >
void check_copy_assign(Rng r)
{
Rng r2 = r;
r2 = r;
}
template< class Container, class Pred >
void filtered_range_copy_assign(Container& c, Pred pred)
{
using namespace boost::adaptors;
check_copy_assign(c | filtered(pred));
check_copy_assign(adaptors::filter(c, pred));
}
template< class Container, class Pred, class PredInit >
void filtered_test_impl()
{
using namespace boost::assign;
Container c;
PredInit init;
Pred pred(init);
// test empty container
filtered_test_impl(c, pred);
// test one element
c += 1;
filtered_test_impl(c, pred);
// test many elements
c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
filtered_test_impl(c, pred);
// test the range and iterator are copy assignable
filtered_range_copy_assign(c, pred);
}
template< class Container >
void filtered_test_all_predicates()
{
filtered_test_impl< Container, always_false_pred, always_false_pred >();
filtered_test_impl< Container, always_true_pred, always_true_pred >();
filtered_test_impl< Container, is_odd, is_odd >();
filtered_test_impl< Container, is_even, is_even >();
filtered_test_impl< Container, lambda, lambda_init >();
}
void ticket_10988_single_pass()
{
std::vector<int> v;
std::string str("0 1 2 3 4 5");
std::istringstream in(str);
boost::push_back(v,
boost::make_iterator_range(
std::istream_iterator<int>(in),
std::istream_iterator<int>())
| boost::adaptors::filtered(is_even()));
std::vector<int> reference;
for (int i = 0; i < 6; i += 2)
{
reference.push_back(i);
}
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
v.begin(), v.end());
}
void filtered_test()
{
filtered_test_all_predicates< std::vector< int > >();
filtered_test_all_predicates< std::list< int > >();
filtered_test_all_predicates< std::set< int > >();
filtered_test_all_predicates< std::multiset< int > >();
ticket_10988_single_pass();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.filtered" );
test->add( BOOST_TEST_CASE( &boost::filtered_test ) );
return test;
}

View File

@@ -0,0 +1,71 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[filtered_example
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
//->
struct is_even
{
bool operator()( int x ) const { return x % 2 == 0; }
};
//<-
void filtered_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::assign;
using namespace boost::adaptors;
std::vector<int> input;
input += 1,2,3,4,5,6,7,8,9;
boost::copy(
input | filtered(is_even()),
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 2,4,6,8;
std::vector<int> test;
boost::push_back(test, input | filtered(is_even()));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.filtered_example" );
test->add( BOOST_TEST_CASE( &filtered_example_test ) );
return test;
}

View File

@@ -0,0 +1,311 @@
// 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/range/adaptor/formatted.hpp>
#include <boost/cstdint.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
namespace boost_range_test
{
namespace
{
template<typename T>
std::string make_string(T x)
{
std::ostringstream result;
result << x;
return result.str();
}
template<typename T1, typename T2>
std::string make_string(T1 x, T2 y)
{
std::ostringstream result;
result << x << y;
return result.str();
}
std::string reference_result(const std::vector<boost::int32_t>& v,
const std::string& separator,
const std::string& prefix,
const std::string& postfix)
{
std::ostringstream out;
out << prefix;
if (!v.empty())
{
out << v.at(0);
std::vector<boost::int32_t>::const_iterator it = v.begin();
for (++it; it != v.end(); ++it)
{
out << separator << *it;
}
}
out << postfix;
return out.str();
}
void test_formatted_0args_impl(const std::vector<boost::int32_t>& v)
{
std::ostringstream out1;
out1 << '[' << (v | boost::adaptors::formatted()) << ']';
BOOST_CHECK_EQUAL(out1.str(), reference_result(v, ",", "[{", "}]"));
std::ostringstream out2;
out2 << '[' << boost::adaptors::format(v) << ']';
BOOST_CHECK_EQUAL(out2.str(), reference_result(v, ",", "[{", "}]"));
std::ostringstream out3;
out3 << (v | boost::adaptors::formatted());
BOOST_CHECK_EQUAL(out3.str(), reference_result(v, ",", "{", "}"));
std::ostringstream out4;
out4 << boost::adaptors::format(v);
BOOST_CHECK_EQUAL(out4.str(), reference_result(v, ",", "{", "}"));
}
template<typename Sep>
void test_formatted_1arg_impl(
const std::vector<boost::int32_t>& v,
const Sep& sep)
{
const std::string ref_sep = make_string(sep);
std::ostringstream out1;
out1 << '[' << (v | boost::adaptors::formatted(sep)) << ']';
BOOST_CHECK_EQUAL(out1.str(), reference_result(v, ref_sep, "[{", "}]"));
std::ostringstream out2;
out2 << '[' << boost::adaptors::format(v, sep) << ']';
BOOST_CHECK_EQUAL(out2.str(), reference_result(v, ref_sep, "[{", "}]"));
std::ostringstream out3;
out3 << (v | boost::adaptors::formatted(sep));
BOOST_CHECK_EQUAL(out3.str(), reference_result(v, ref_sep, "{", "}"));
std::ostringstream out4;
out4 << boost::adaptors::format(v, sep);
BOOST_CHECK_EQUAL(out4.str(), reference_result(v, ref_sep, "{", "}"));
}
void test_formatted_1arg_impl(const std::vector<boost::int32_t>& v)
{
test_formatted_1arg_impl(v, ',');
test_formatted_1arg_impl(v, ' ');
test_formatted_1arg_impl<const char[3]>(v, ":?");
}
template<typename Sep, typename Prefix>
void test_formatted_2args_impl(
const std::vector<boost::int32_t>& v,
const Sep& sep,
const Prefix& prefix
)
{
const std::string ref_sep = make_string(sep);
std::ostringstream out1;
out1 << '[' << (v | boost::adaptors::formatted(sep, prefix)) << ']';
BOOST_CHECK_EQUAL(
out1.str(),
reference_result(v, ref_sep, make_string('[', prefix), "}]"));
std::ostringstream out2;
out2 << '[' << boost::adaptors::format(v, sep, prefix) << ']';
BOOST_CHECK_EQUAL(
out2.str(),
reference_result(v, ref_sep, make_string('[', prefix), "}]"));
std::ostringstream out3;
out3 << (v | boost::adaptors::formatted(sep, prefix));
BOOST_CHECK_EQUAL(
out3.str(),
reference_result(v, ref_sep, make_string(prefix), "}"));
std::ostringstream out4;
out4 << boost::adaptors::format(v, sep, prefix);
BOOST_CHECK_EQUAL(
out4.str(),
reference_result(v, ref_sep, make_string(prefix), "}"));
}
void test_formatted_2args_impl(const std::vector<boost::int32_t>& v)
{
test_formatted_2args_impl(v, ',', '{');
test_formatted_2args_impl(v, ':', '(');
test_formatted_2args_impl<char, const char[3]>(v, ',', "{!");
test_formatted_2args_impl<const char[3], char>(v, "#$", '{');
test_formatted_2args_impl<const char[3], const char[3]>(v, "#$", "{!");
}
template<typename Sep, typename Prefix, typename Postfix>
void test_formatted_3args_impl(
const std::vector<boost::int32_t>& v,
const Sep& sep,
const Prefix& prefix,
const Postfix& postfix
)
{
const std::string ref_sep = make_string(sep);
std::ostringstream out1;
out1 << '[' << (v | boost::adaptors::formatted(sep, prefix, postfix))
<< ']';
BOOST_CHECK_EQUAL(
out1.str(),
reference_result(v, ref_sep, make_string('[', prefix),
make_string(postfix, ']')));
}
void test_formatted_3args_impl(const std::vector<boost::int32_t>& v)
{
test_formatted_3args_impl(v, ',', '{', '}');
test_formatted_3args_impl(v, ':', '(', ')');
test_formatted_3args_impl<char, char, const char[3]>(v, ',', '{', "!}");
test_formatted_3args_impl<char, const char[3], char>(v, ',', "{!", '}');
test_formatted_3args_impl<const char[3], char, char>(v, "#$", '{', '}');
test_formatted_3args_impl<
const char[3], const char[3], const char[3]
>(v, "#$", "{!", "!}");
}
void test_formatted_impl(const std::vector<boost::int32_t>& v)
{
test_formatted_0args_impl(v);
test_formatted_1arg_impl(v);
test_formatted_2args_impl(v);
test_formatted_3args_impl(v);
}
void test_formatted1()
{
std::vector<boost::int32_t> v;
for (boost::int32_t i = 0; i < 10; ++i)
v.push_back(i);
test_formatted_impl(v);
}
void test_formatted2()
{
std::vector<boost::int32_t> v;
v.push_back(3);
test_formatted_impl(v);
}
void test_formatted3()
{
std::vector<boost::int32_t> v;
test_formatted_impl(v);
}
void test_formatted4()
{
std::vector<boost::int32_t> v;
for (boost::int32_t i = 0; i < 5; ++i)
v.push_back(i);
test_formatted_impl(v);
}
struct udt_separator
{
};
template<typename Char, typename Traits>
inline std::basic_ostream<Char,Traits>&
operator<<(std::basic_ostream<Char,Traits>& out, udt_separator)
{
return out << "[sep]";
}
void test_formatted5()
{
std::vector<boost::int32_t> v;
for (boost::int32_t i = 0; i < 5; ++i)
v.push_back(i);
std::ostringstream out1;
out1 << (v | boost::adaptors::formatted(udt_separator()));
BOOST_CHECK_EQUAL(out1.str(), "{0[sep]1[sep]2[sep]3[sep]4}");
std::ostringstream out2;
out2 << boost::adaptors::format(v, udt_separator());
BOOST_CHECK_EQUAL(out2.str(), "{0[sep]1[sep]2[sep]3[sep]4}");
}
// This test is already covered by the more complex code above. This
// code duplicates coverage to ensure that char literal arrays are handled
// correctly. I was particularly concerned that my test code above may pass
// erroneously by decaying a char literal to a pointer. This function makes
// it very plain that character literal strings work.
void test_formatted_empty()
{
std::vector<boost::int32_t> v;
std::ostringstream out1;
out1 << (v | boost::adaptors::formatted());
BOOST_CHECK_EQUAL(out1.str(), "{}");
std::ostringstream out2;
out2 << boost::adaptors::format(v);
BOOST_CHECK_EQUAL(out2.str(), "{}");
std::ostringstream out3;
out3 << (v | boost::adaptors::formatted(','));
BOOST_CHECK_EQUAL(out3.str(), "{}");
std::ostringstream out4;
out4 << boost::adaptors::format(v, ',');
BOOST_CHECK_EQUAL(out4.str(), "{}");
std::ostringstream out5;
out5 << (v | boost::adaptors::formatted("#$"));
BOOST_CHECK_EQUAL(out5.str(), "{}");
std::ostringstream out6;
out6 << boost::adaptors::format(v, "#$");
BOOST_CHECK_EQUAL(out6.str(), "{}");
std::ostringstream out7;
out7 << (v | boost::adaptors::formatted("", "12", "34"));
BOOST_CHECK_EQUAL(out7.str(), "1234");
std::ostringstream out8;
out8 << boost::adaptors::format(v, "", "12", "34");
BOOST_CHECK_EQUAL(out8.str(), "1234");
}
} // 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 formatted test suite" );
test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted1));
test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted2));
test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted3));
test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted4));
test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted5));
test->add(BOOST_TEST_CASE(&boost_range_test::test_formatted_empty));
return test;
}

View File

@@ -0,0 +1,61 @@
// 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/
//
//[formatted_example
#include <boost/range/adaptor/formatted.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
void formatted_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::assign;
std::vector<int> input;
input += 1,2,3,4,5;
std::cout << boost::adaptors::format(input) << std::endl;
// Alternatively this can be written:
// std::cout << (input | boost::adaptors::formatted()) << std::endl;
//= return 0;
//=}
//]
std::ostringstream test;
test << boost::adaptors::format(input);
BOOST_CHECK_EQUAL(test.str(), "{1,2,3,4,5}");
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.formatted_example" );
test->add( BOOST_TEST_CASE( &formatted_example_test ) );
return test;
}

View File

@@ -0,0 +1,152 @@
// 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/range/adaptor/indexed.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/foreach.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <boost/range/concepts.hpp>
#include <algorithm>
#include <list>
#include <vector>
#include "../test_utils.hpp"
namespace boost_range_test
{
namespace
{
template<typename Container, typename AdaptedRange>
void check_result(
const Container& reference_range,
const AdaptedRange& adapted_range,
std::ptrdiff_t start_index
)
{
typedef typename boost::range_iterator<const Container>::type
reference_iterator;
typedef typename boost::range_iterator<const AdaptedRange>::type
adapted_iterator;
BOOST_REQUIRE_EQUAL(boost::size(reference_range),
boost::size(adapted_range));
reference_iterator reference_it = boost::begin(reference_range);
adapted_iterator adapted_it = boost::begin(adapted_range);
for (std::ptrdiff_t i = start_index;
reference_it != boost::end(reference_range);
++reference_it, ++adapted_it, ++i)
{
BOOST_CHECK_EQUAL(i, adapted_it->index());
BOOST_CHECK_EQUAL(*reference_it, adapted_it->value());
}
}
template<typename Container>
void indexed_test_impl(Container& c, std::ptrdiff_t start_index)
{
// This is my preferred syntax using the | operator.
check_result(c, c | boost::adaptors::indexed(), 0);
check_result(c, c | boost::adaptors::indexed(start_index), start_index);
// This is the function syntax
check_result(c, boost::adaptors::index(c), 0);
check_result(c, boost::adaptors::index(c, start_index), start_index);
}
template<typename Container>
void indexed_test_impl(Container& c)
{
indexed_test_impl(c, 0);
indexed_test_impl(c, -1);
indexed_test_impl(c, 4);
}
template<typename Container>
void indexed_test_impl()
{
using namespace boost::assign;
Container c;
// test empty container
indexed_test_impl(c);
// test one element
c += 1;
indexed_test_impl(c);
// test many elements
c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
indexed_test_impl(c);
}
template<typename Traversal, typename Range>
void check_traversal(const Range& rng)
{
BOOST_STATIC_ASSERT(
boost::is_convertible<
typename boost::range_traversal<const Range>::type,
Traversal
>::value);
}
template<typename Traversal, typename Range>
void check_not_traversal(const Range& rng)
{
BOOST_STATIC_ASSERT(
!boost::is_convertible<
typename boost::range_traversal<const Range>::type,
Traversal
>::value);
}
void indexed_test()
{
indexed_test_impl< std::vector< int > >();
indexed_test_impl< std::list< int > >();
std::vector<int> vi;
check_traversal<boost::random_access_traversal_tag>(
vi | boost::adaptors::indexed());
std::list<int> li;
check_traversal<boost::forward_traversal_tag>(
li | boost::adaptors::indexed());
check_not_traversal<boost::bidirectional_traversal_tag>(
li | boost::adaptors::indexed());
check_not_traversal<boost::random_access_traversal_tag>(
li | boost::adaptors::indexed());
}
} // anonymous namesapce
} // 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 indexed adaptor test suite" );
test->add(BOOST_TEST_CASE(&boost_range_test::indexed_test));
return test;
}

View File

@@ -0,0 +1,104 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[indexed_example
//<-
#include <boost/config.hpp>
//->
#include <boost/range/adaptor/indexed.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
namespace
{
template<class Iterator1, class Iterator2>
void check_element_and_index(
Iterator1 test_first,
Iterator1 test_last,
Iterator2 reference_first,
Iterator2 reference_last)
{
BOOST_CHECK_EQUAL( std::distance(test_first, test_last),
std::distance(reference_first, reference_last) );
std::ptrdiff_t reference_index = 0;
Iterator1 test_it = test_first;
Iterator2 reference_it = reference_first;
for (; test_it != test_last; ++test_it, ++reference_it, ++reference_index)
{
BOOST_CHECK_EQUAL(test_it->value(), *reference_it);
BOOST_CHECK_EQUAL(test_it->index(), reference_index);
}
}
template<class SinglePassRange1, class SinglePassRange2>
void check_element_and_index(
const SinglePassRange1& test_rng,
const SinglePassRange2& reference_rng)
{
check_element_and_index(
boost::begin(test_rng), boost::end(test_rng),
boost::begin(reference_rng), boost::end(reference_rng));
}
//->
//<-
void indexed_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::assign;
using namespace boost::adaptors;
std::vector<int> input;
input += 10,20,30,40,50,60,70,80,90;
//<-
#ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
//->
for (const auto& element : input | indexed(0))
{
std::cout << "Element = " << element.value()
<< " Index = " << element.index()
<< std::endl;
}
//<-
#endif // C++11 has range for loop
//->
//= return 0;
//=}
//]
check_element_and_index(
input | indexed(0),
input);
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.indexed_example" );
test->add( BOOST_TEST_CASE( &indexed_example_test ) );
return test;
}

View File

@@ -0,0 +1,99 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/indirected.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void indirected_test_impl( Container& c )
{
using namespace boost::adaptors;
// This is my preferred syntax using the | operator.
std::vector< int > test_result1;
boost::push_back(test_result1, c | indirected);
// This is an alternative syntax preferred by some.
std::vector< int > test_result2;
boost::push_back(test_result2, adaptors::indirect(c));
// Calculate the reference result.
std::vector< int > reference_result;
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iter_t;
for (iter_t it = c.begin(); it != c.end(); ++it)
{
reference_result.push_back(**it);
}
BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
reference_result.end(),
test_result1.begin(),
test_result1.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( reference_result.begin(),
reference_result.end(),
test_result2.begin(),
test_result2.end() );
}
template< class Container >
void indirected_test_impl()
{
using namespace boost::assign;
Container c;
indirected_test_impl(c);
c += boost::shared_ptr<int>(new int(1));
indirected_test_impl(c);
std::vector<int> v;
v += 1,1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
for (std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it)
{
c += boost::shared_ptr<int>(new int(*it));
}
indirected_test_impl(c);
}
void indirected_test()
{
indirected_test_impl< std::vector< boost::shared_ptr< int > > >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.indirected" );
test->add( BOOST_TEST_CASE( &boost::indirected_test ) );
return test;
}

View File

@@ -0,0 +1,66 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[indirected_example
#include <boost/range/adaptor/indirected.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/shared_ptr.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
void indirected_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::adaptors;
std::vector<boost::shared_ptr<int> > input;
for (int i = 0; i < 10; ++i)
input.push_back(boost::shared_ptr<int>(new int(i)));
boost::copy(
input | indirected,
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
for (int i = 0; i < 10; ++i)
reference.push_back(i);
std::vector<int> test;
boost::push_back(test, input | indirected);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.indirected_example" );
test->add( BOOST_TEST_CASE( &indirected_example_test ) );
return test;
}

View File

@@ -0,0 +1,171 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/map.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/array.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <map>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void map_test_keys( Container& c )
{
using namespace boost::adaptors;
std::vector<int> keys;
boost::push_back(keys, c | map_keys);
std::vector<int> keys2;
boost::push_back(keys2, adaptors::keys(c));
std::vector<int> reference_keys;
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iter_t;
for (iter_t it = c.begin(); it != c.end(); ++it)
{
reference_keys.push_back(it->first);
}
BOOST_CHECK_EQUAL_COLLECTIONS( reference_keys.begin(),
reference_keys.end(),
keys.begin(),
keys.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( reference_keys.begin(),
reference_keys.end(),
keys2.begin(),
keys2.end() );
}
template< class Container >
void map_test_values( Container& c )
{
using namespace boost::adaptors;
std::vector<int> values;
boost::push_back(values, c | map_values);
std::vector<int> values2;
boost::push_back(values2, adaptors::values(c));
std::vector<int> reference_values;
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iter_t;
for (iter_t it = c.begin(); it != c.end(); ++it)
{
reference_values.push_back(it->second);
}
BOOST_CHECK_EQUAL_COLLECTIONS( reference_values.begin(),
reference_values.end(),
values.begin(),
values.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( reference_values.begin(),
reference_values.end(),
values2.begin(),
values2.end() );
}
template< class Container >
void map_test_impl()
{
using namespace boost::assign;
Container c;
// Test empty
map_test_keys(c);
map_test_values(c);
// Test one element
c.insert(std::make_pair(1,2));
map_test_keys(c);
map_test_values(c);
// Test many elements
for (int x = 2; x < 10; ++x)
{
c.insert(std::make_pair(x, x * 2));
}
map_test_keys(c);
map_test_values(c);
}
void map_test()
{
map_test_impl< std::map<int,int> >();
}
void test_trac_item_4388()
{
typedef std::pair<int,char> pair_t;
const boost::array<pair_t,3> ar = {{
pair_t(3, 'a'),
pair_t(1, 'b'),
pair_t(4, 'c')
}};
const boost::array<int, 3> expected_keys = {{ 3, 1, 4 }};
const boost::array<char, 3> expected_values = {{ 'a', 'b', 'c' }};
{
std::vector<int> test;
boost::push_back(test, ar | boost::adaptors::map_keys);
BOOST_CHECK_EQUAL_COLLECTIONS(
expected_keys.begin(), expected_keys.end(),
test.begin(), test.end()
);
}
{
std::vector<char> test;
boost::push_back(test, ar | boost::adaptors::map_values);
BOOST_CHECK_EQUAL_COLLECTIONS(
expected_values.begin(), expected_values.end(),
test.begin(), test.end()
);
}
{
std::vector<char> test;
boost::array<std::pair<int, char>, 3> src(ar);
boost::push_back(test, src | boost::adaptors::map_values);
BOOST_CHECK_EQUAL_COLLECTIONS(
expected_values.begin(), expected_values.end(),
test.begin(), test.end()
);
}
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.map" );
test->add( BOOST_TEST_CASE( &boost::map_test ) );
test->add( BOOST_TEST_CASE( &boost::test_trac_item_4388 ) );
return test;
}

View File

@@ -0,0 +1,66 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[map_keys_example
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <map>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
void map_keys_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::assign;
using namespace boost::adaptors;
std::map<int,int> input;
for (int i = 0; i < 10; ++i)
input.insert(std::make_pair(i, i * 10));
boost::copy(
input | map_keys,
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 0,1,2,3,4,5,6,7,8,9;
std::vector<int> test;
boost::push_back(test, input | map_keys);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.map_keys_example" );
test->add( BOOST_TEST_CASE( &map_keys_example_test ) );
return test;
}

View File

@@ -0,0 +1,66 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[map_values_example
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <map>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
void map_values_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::assign;
using namespace boost::adaptors;
std::map<int,int> input;
for (int i = 0; i < 10; ++i)
input.insert(std::make_pair(i, i * 10));
boost::copy(
input | map_values,
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 0,10,20,30,40,50,60,70,80,90;
std::vector<int> test;
boost::push_back(test, input | map_values);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.map_values_example" );
test->add( BOOST_TEST_CASE( &map_values_example_test ) );
return test;
}

View File

@@ -0,0 +1,101 @@
// Boost.Range library
//
// Copyright Robin Eckert 2015. 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/adaptor/ref_unwrapped.hpp>
#define BOOST_TEST_MAIN
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <vector>
#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_CXX11_RANGE_BASED_FOR) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
namespace boost
{
BOOST_AUTO_TEST_CASE(test_mutable)
{
int one = 1;
int two = 2;
int three = 3;
std::vector<std::reference_wrapper<int>> input_values{one, two, three};
const std::vector<int*> expected{&one, &two, &three};
std::vector<int*> actual;
for (auto&& value : input_values | adaptors::ref_unwrapped)
{
actual.push_back(&value);
}
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(),
expected.end(),
actual.begin(),
actual.end());
}
BOOST_AUTO_TEST_CASE(test_const_range)
{
int one = 1;
int two = 2;
int three = 3;
const std::vector<std::reference_wrapper<int>> input_values{one, two, three};
const std::vector<int*> expected{&one, &two, &three};
std::vector<int*> actual;
for (auto&& value : input_values | adaptors::ref_unwrapped)
{
actual.push_back(&value);
}
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(),
expected.end(),
actual.begin(),
actual.end());
}
BOOST_AUTO_TEST_CASE(test_const_reference)
{
const int one = 1;
const int two = 2;
const int three = 3;
const std::vector<std::reference_wrapper<const int>> input_values{one, two, three};
const std::vector<const int*> expected{&one, &two, &three};
std::vector<const int*> actual;
for (auto&& value : input_values | adaptors::ref_unwrapped)
{
actual.push_back(&value);
}
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(),
expected.end(),
actual.begin(),
actual.end());
}
}
#else
BOOST_AUTO_TEST_CASE(empty)
{
// C++11 only
}
#endif

View File

@@ -0,0 +1,47 @@
// Boost.Range library
//
// Copyright Robin Eckert 2015. 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/
//
//[ref_unwrapped_example
#include <boost/range/adaptor/ref_unwrapped.hpp>
#include <iostream>
#include <vector>
struct example
{
int value;
};
int main(int argc, const char* argv[])
{
//<-
#if !defined(BOOST_NO_CXX11_DECLTYPE) \
&& !defined(BOOST_NO_CXX11_RANGE_BASED_FOR) \
&& !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) \
&& !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
//->
using boost::adaptors::ref_unwrapped;
example one{1};
example two{2};
example three{3};
std::vector<std::reference_wrapper<example> > input{one, two, three};
for (auto&& entry : input | ref_unwrapped)
{
std::cout << entry.value;
}
return 0;
//<-
#endif
//->
}
//]

View File

@@ -0,0 +1,87 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/replaced.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void replaced_test_impl( Container& c )
{
using namespace boost::adaptors;
const int value_to_replace = 1;
const int replacement_value = 0;
std::vector< int > test_result1;
boost::push_back(test_result1, c | replaced(value_to_replace, replacement_value));
std::vector< int > test_result2;
boost::push_back(test_result2, adaptors::replace(c, value_to_replace, replacement_value));
std::vector< int > reference( c.begin(), c.end() );
std::replace(reference.begin(), reference.end(), value_to_replace, replacement_value);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test_result1.begin(), test_result1.end() );
}
template< class Container >
void replaced_test_impl()
{
using namespace boost::assign;
Container c;
// Test empty
replaced_test_impl(c);
// Test one
c += 1;
replaced_test_impl(c);
// Test many
c += 1,1,1,2,2,2,3,3,3,3,3,4,5,6,6,6,7,8,9;
replaced_test_impl(c);
}
void replaced_test()
{
replaced_test_impl< std::vector< int > >();
replaced_test_impl< std::list< int > >();
replaced_test_impl< std::set< int > >();
replaced_test_impl< std::multiset< int > >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.replaced" );
test->add( BOOST_TEST_CASE( &boost::replaced_test ) );
return test;
}

View File

@@ -0,0 +1,64 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[replaced_example
#include <boost/range/adaptor/replaced.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
void replaced_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::adaptors;
using namespace boost::assign;
std::vector<int> input;
input += 1,2,3,2,5,2,7,2,9;
boost::copy(
input | replaced(2, 10),
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 1,10,3,10,5,10,7,10,9;
std::vector<int> test;
boost::push_back(test, input | replaced(2, 10));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.replaced_example" );
test->add( BOOST_TEST_CASE( &replaced_example_test ) );
return test;
}

View File

@@ -0,0 +1,96 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/replaced_if.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
struct if_value_is_one
{
bool operator()(int x) const { return x == 1; }
};
template< class Container >
void replaced_if_test_impl( Container& c )
{
using namespace boost::adaptors;
if_value_is_one pred;
const int replacement_value = 0;
std::vector< int > test_result1;
boost::push_back(test_result1, c | replaced_if(pred, replacement_value));
std::vector< int > test_result2;
boost::push_back(test_result2, boost::adaptors::replace_if(c, pred, replacement_value));
std::vector< int > reference( c.begin(), c.end() );
std::replace_if(reference.begin(), reference.end(), pred, replacement_value);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test_result1.begin(), test_result1.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test_result2.begin(), test_result2.end() );
}
template< class Container >
void replaced_if_test_impl()
{
using namespace boost::assign;
Container c;
// Test empty
replaced_if_test_impl(c);
// Test one
c += 1;
replaced_if_test_impl(c);
// Test many
c += 1,1,1,2,2,2,3,3,3,3,3,4,5,6,6,6,7,8,9;
replaced_if_test_impl(c);
}
void replaced_if_test()
{
replaced_if_test_impl< std::vector< int > >();
replaced_if_test_impl< std::list< int > >();
replaced_if_test_impl< std::set< int > >();
replaced_if_test_impl< std::multiset< int > >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.replaced_if" );
test->add( BOOST_TEST_CASE( &boost::replaced_if_test ) );
return test;
}

View File

@@ -0,0 +1,71 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[replaced_if_example
#include <boost/range/adaptor/replaced_if.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
//->
struct is_even
{
bool operator()(int x) const { return x % 2 == 0; }
};
//<-
void replaced_if_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::adaptors;
using namespace boost::assign;
std::vector<int> input;
input += 1,2,3,4,5,6,7,8,9;
boost::copy(
input | replaced_if(is_even(), 10),
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 1,10,3,10,5,10,7,10,9;
std::vector<int> test;
boost::push_back(test, input | replaced_if(is_even(), 10));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.replaced_if_example" );
test->add( BOOST_TEST_CASE( &replaced_if_example_test ) );
return test;
}

View File

@@ -0,0 +1,84 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/reversed.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
template< class Container >
void reversed_test_impl( Container& c )
{
using namespace boost::adaptors;
std::vector< int > test_result1;
boost::push_back(test_result1, c | reversed);
std::vector< int > test_result2;
boost::push_back(test_result2, adaptors::reverse(c));
std::vector< int > reference( c.rbegin(), c.rend() );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test_result1.begin(), test_result1.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test_result2.begin(), test_result2.end() );
}
template< class Container >
void reversed_test_impl()
{
using namespace boost::assign;
Container c;
// Test empty
reversed_test_impl(c);
// Test one
c += 1;
reversed_test_impl(c);
// Test many
c += 1,1,1,2,2,2,2,2,3,3,3,3,3,3,4,5,6,7,8,9;
reversed_test_impl(c);
}
void reversed_test()
{
reversed_test_impl< std::vector< int > >();
reversed_test_impl< std::list< int > >();
reversed_test_impl< std::set< int > >();
reversed_test_impl< std::multiset< int > >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.reversed" );
test->add( BOOST_TEST_CASE( &boost::reversed_test ) );
return test;
}

View File

@@ -0,0 +1,61 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[reversed_example
#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
void reversed_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::adaptors;
using namespace boost::assign;
std::vector<int> input;
input += 1,2,3,4,5,6,7,8,9;
boost::copy(
input | reversed,
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> test;
boost::push_back(test, input | reversed);
BOOST_CHECK_EQUAL_COLLECTIONS( input.rbegin(), input.rend(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.reversed_example" );
test->add( BOOST_TEST_CASE( &reversed_example_test ) );
return test;
}

View File

@@ -0,0 +1,99 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/sliced.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void sliced_test_impl( Container& c )
{
using namespace boost::adaptors;
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
std::vector< value_t > test_result1;
boost::push_back(test_result1, c | sliced(0u,c.size()));
BOOST_CHECK_EQUAL_COLLECTIONS( test_result1.begin(), test_result1.end(),
c.begin(), c.end() );
std::vector< value_t > test_alt_result1;
boost::push_back(test_alt_result1, adaptors::slice(c, 0u, c.size()));
BOOST_CHECK_EQUAL_COLLECTIONS( test_alt_result1.begin(), test_alt_result1.end(),
c.begin(), c.end() );
BOOST_CHECK( boost::empty(c | sliced(0u, 0u)) );
const std::size_t half_count = c.size() / 2u;
if (half_count > 0u)
{
std::vector< value_t > test_result2;
boost::push_back(test_result2, c | sliced(0u, half_count));
BOOST_CHECK_EQUAL_COLLECTIONS( test_result2.begin(), test_result2.end(),
c.begin(), c.begin() + half_count );
std::vector< value_t > test_alt_result2;
boost::push_back(test_alt_result2, adaptors::slice(c, 0u, half_count));
BOOST_CHECK_EQUAL_COLLECTIONS( test_alt_result2.begin(), test_alt_result2.end(),
c.begin(), c.begin() + half_count );
}
}
template< class Container >
void sliced_test_impl()
{
using namespace boost::assign;
Container c;
// Test empty
sliced_test_impl(c);
// Test one element
c += 1;
sliced_test_impl(c);
// Test many elements
c += 1,1,1,2,2,3,4,5,6,6,6,7,8,9;
sliced_test_impl(c);
}
void sliced_test()
{
sliced_test_impl< std::vector< int > >();
sliced_test_impl< std::deque< int > >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.sliced" );
test->add( BOOST_TEST_CASE( &boost::sliced_test ) );
return test;
}

View File

@@ -0,0 +1,64 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[sliced_example
#include <boost/range/adaptor/sliced.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
void sliced_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::adaptors;
using namespace boost::assign;
std::vector<int> input;
input += 1,2,3,4,5,6,7,8,9;
boost::copy(
input | sliced(2, 5),
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 3,4,5;
std::vector<int> test;
boost::push_back(test, input | sliced(2, 5));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.sliced_example" );
test->add( BOOST_TEST_CASE( &sliced_example_test ) );
return test;
}

View File

@@ -0,0 +1,313 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
// The strided_defect_Trac5014 test case is a modified version of a test case
// contributed by Maxim Yanchenko as part of the trac ticket.
//
// The deque test case has been removed due to erroneous standard library
// implementations causing test failures.
//
#include <boost/range/adaptor/strided.hpp>
#include <boost/config.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void strided_test_impl( Container& c, int stride_size )
{
using namespace boost::adaptors;
// 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 BOOST_RANGE_UNUSED;
typedef BOOST_DEDUCED_TYPENAME Container::difference_type
diff_t BOOST_RANGE_UNUSED;
typedef BOOST_DEDUCED_TYPENAME Container::size_type
size_type BOOST_RANGE_UNUSED;
iterator_t it = c.begin();
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(stride_size) );
BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
reference.begin(), reference.end() );
Container test2;
boost::push_back( test2, adaptors::stride(c, stride_size) );
BOOST_CHECK_EQUAL_COLLECTIONS( test2.begin(), test2.end(),
reference.begin(), reference.end() );
// Test the const versions:
const Container& cc = c;
Container test3;
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, stride_size) );
BOOST_CHECK_EQUAL_COLLECTIONS( test4.begin(), test4.end(),
reference.begin(), reference.end() );
}
template< class Container >
void strided_test_impl(int stride_size)
{
using namespace boost::assign;
Container c;
// Test empty
strided_test_impl(c, stride_size);
// Test two elements
c += 1,2;
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, 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) );
boost::ignore_unused_variable_warning(rng);
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<strided_range_t>::type iter_t;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_traversal<
BOOST_DEDUCED_TYPENAME Container::const_iterator
>::type container_traversal_tag;
iter_t first = boost::range_detail::make_begin_strided_iterator(
c, 0, container_traversal_tag());
iter_t last = boost::range_detail::make_end_strided_iterator(
c, 0, container_traversal_tag());
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::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());
}
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() );
}
template<typename Range>
void strided_test_ticket_5236_check_bidirectional(const Range& rng)
{
BOOST_CHECK_EQUAL( boost::distance(rng), 1 );
BOOST_CHECK_EQUAL( std::distance(boost::begin(rng), boost::prior(boost::end(rng))), 0 );
}
template<typename Range>
void strided_test_ticket_5236_check(const Range& rng)
{
strided_test_ticket_5236_check_bidirectional(rng);
typename boost::range_iterator<const Range>::type it = boost::end(rng);
it = it - 1;
BOOST_CHECK_EQUAL( std::distance(boost::begin(rng), it), 0 );
}
void strided_test_ticket_5236()
{
std::vector<int> v;
v.push_back(1);
strided_test_ticket_5236_check( v | boost::adaptors::strided(2) );
// Ensure that there is consistency between the random-access implementation
// and the bidirectional.
std::list<int> l;
l.push_back(1);
strided_test_ticket_5236_check_bidirectional( l | boost::adaptors::strided(2) );
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= 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 ) );
test->add( BOOST_TEST_CASE( &boost::strided_test_ticket_5236 ) );
return test;
}

View File

@@ -0,0 +1,67 @@
// 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/
//
// This test was added due to a report that the Range Adaptors:
// 1. Caused havoc when using namespace boost::adaptors was used
// 2. Did not work with non-member functions
// 3. The strided adaptor could not be composed with sliced
//
// None of these issues could be reproduced on GCC 4.4, but this
// work makes for useful additional test coverage since this
// uses chaining of adaptors and non-member functions whereas
// most of the tests avoid this use case.
#include <boost/range/adaptor/strided.hpp>
#include <boost/range/adaptor/sliced.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/irange.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <vector>
namespace boost
{
namespace
{
int times_two(int x) { return x * 2; }
void strided_test2()
{
using namespace boost::adaptors;
using namespace boost::assign;
std::vector<int> v;
boost::push_back(v, boost::irange(0,10));
std::vector<int> z;
boost::push_back(z, v | sliced(2,6) | strided(2) | transformed(&times_two));
std::vector<int> reference;
reference += 4,8;
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
z.begin(), z.end() );
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.strided2" );
test->add( BOOST_TEST_CASE( &boost::strided_test2 ) );
return test;
}

View File

@@ -0,0 +1,64 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[strided_example
#include <boost/range/adaptor/strided.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
void strided_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::adaptors;
using namespace boost::assign;
std::vector<int> input;
input += 1,2,3,4,5,6,7,8,9,10;
boost::copy(
input | strided(2),
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 1,3,5,7,9;
std::vector<int> test;
boost::push_back(test, input | strided(2));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.strided_example" );
test->add( BOOST_TEST_CASE( &strided_example_test ) );
return test;
}

View File

@@ -0,0 +1,69 @@
// 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/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <iterator>
#include <iostream>
#include <vector>
namespace
{
struct test_struct
{
double x;
double y;
};
struct get_x
{
typedef double result_type;
double operator()(const test_struct& s) const
{
return s.x;
}
};
void range_transformed_warning()
{
using namespace boost::phoenix::arg_names;
using namespace boost::adaptors;
test_struct t;
t.x = 2.0;
t.y = -4.0;
std::vector<test_struct> v(10u, t);
std::vector<double> output1;
boost::push_back(output1, v | transformed((&arg1)->*& test_struct::x));
std::vector<double> output2;
boost::push_back(output2, v | transformed(get_x()));
BOOST_CHECK_EQUAL_COLLECTIONS(
output1.begin(), output1.end(),
output2.begin(), output2.end());
}
} // anonymous namespace
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "Range adaptors - transformed warning" );
test->add(BOOST_TEST_CASE(&range_transformed_warning));
return test;
}

View File

@@ -0,0 +1,56 @@
// 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/range/adaptor/sliced.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <vector>
namespace
{
struct identity
{
typedef int result_type;
result_type operator()(int i) const { return i; }
};
void sliced_and_transformed()
{
using namespace boost::adaptors;
std::vector<int> input;
for (int i = 0; i < 10; ++i)
input.push_back(i);
std::vector<int> out1;
boost::push_back(out1, input | sliced(2, 8)
| transformed(identity()));
std::vector<int> out2;
boost::push_back(out2, input | transformed(identity())
| sliced(2, 8));
BOOST_CHECK_EQUAL_COLLECTIONS(out1.begin(), out1.end(),
out2.begin(), out2.end());
}
} // anonymous namespace
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "Range adaptors - sliced and transformed" );
test->add(BOOST_TEST_CASE(&sliced_and_transformed));
return test;
}

View File

@@ -0,0 +1,67 @@
// 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/
//
// Credit goes to Eric Niebler for providing an example to demonstrate this
// issue. This has been trivially modified to create this test case.
//
#include <boost/range/adaptor/strided.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <list>
#include <vector>
#include <numeric>
namespace boost
{
namespace
{
void ticket_9519_strided_reversed_test()
{
using namespace boost::adaptors;
std::vector<int> vi;
for (int i = 0; i < 50; ++i)
{
vi.push_back(i);
}
std::vector<int> output;
boost::push_back(output, vi | strided(3) | reversed);
std::list<int> reference;
for (int i = 0; i < 50; i += 3)
{
reference.push_front(i);
}
BOOST_CHECK_EQUAL_COLLECTIONS(output.begin(), output.end(),
reference.begin(), reference.end());
}
} // anonymous namespace
} // namespace boost
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE(
"RangeTestSuite.adaptor.ticket_9519_strided_reversed");
test->add(BOOST_TEST_CASE(&boost::ticket_9519_strided_reversed_test));
return test;
}

View File

@@ -0,0 +1,79 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/tokenized.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <algorithm>
#include <string>
#include <vector>
namespace boost
{
namespace
{
template< class Iterator, class Container >
void tokenized_test_impl( Container& c, std::size_t expected_result )
{
using namespace boost::adaptors;
std::vector< boost::sub_match< Iterator > > test_result1;
boost::push_back(test_result1, c | tokenized(boost::regex("\\b")));
BOOST_CHECK_EQUAL( test_result1.size(), expected_result );
// std::vector< boost::sub_match< Iterator > > test_result2;
// boost::push_back(test_result2, adaptors::tokenize(c, boost::regex("\\b")));
// BOOST_CHECK_EQUAL( test_result2.size(), expected_result );
}
template< class Container1, class Container2 >
void tokenized_test_impl()
{
Container1 c;
Container2& r = c;
typedef typename boost::range_iterator<Container2>::type It;
// Test empty
tokenized_test_impl<It, Container2>(r, 0u);
// Test one element
c = "a";
tokenized_test_impl<It, Container2>(r, 2u);
// Test many elements
c = "a b c d e f g hijlmnopqrstuvwxyz";
tokenized_test_impl<It, Container2>(r, 16u);
}
void tokenized_test()
{
// tokenized_test_impl<std::string, const std::string>();
tokenized_test_impl<std::string, std::string>();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.tokenized" );
test->add( BOOST_TEST_CASE( &boost::tokenized_test ) );
return test;
}

View File

@@ -0,0 +1,65 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[tokenized_example
#include <boost/range/adaptor/tokenized.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
void tokenized_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::adaptors;
typedef boost::sub_match< std::string::iterator > match_type;
std::string input = " a b c d e f g hijklmnopqrstuvwxyz";
boost::copy(
input | tokenized(boost::regex("\\w+")),
std::ostream_iterator<match_type>(std::cout, "\n"));
//= return 0;
//=}
//]
using namespace boost::assign;
std::vector<std::string> reference;
reference += "a","b","c","d","e","f","g","hijklmnopqrstuvwxyz";
std::vector<match_type> test;
boost::push_back(test, input | tokenized(boost::regex("\\w+")));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.tokenized_example" );
test->add( BOOST_TEST_CASE( &tokenized_example_test ) );
return test;
}

View File

@@ -0,0 +1,171 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/transformed.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/bind/bind.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
struct double_x
{
typedef int result_type;
int operator()(int x) const { return x * 2; }
};
struct halve_x
{
typedef int result_type;
int operator()(int x) const { return x / 2; }
};
struct lambda_init
{
};
struct lambda
{
typedef int result_type;
lambda(const lambda_init& init) {}
lambda(const lambda& rhs) {}
int operator()(int x) const { return x + 1; }
private:
lambda() {}
lambda& operator=(const lambda& rhs) { return *this; }
};
template< class Container, class TransformFn >
void transformed_test_impl_core( Container& c, TransformFn fn )
{
using namespace boost::adaptors;
std::vector< int > test_result1;
boost::push_back(test_result1, c | transformed(fn));
std::vector< int > test_result2;
boost::push_back(test_result2, adaptors::transform(c, fn));
std::vector< int > reference;
std::transform(c.begin(), c.end(), std::back_inserter(reference), fn);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test_result1.begin(), test_result1.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test_result2.begin(), test_result2.end() );
}
template< class Rng >
void check_copy_assign(Rng r)
{
Rng r2 = r;
r2 = r;
}
template< class Container, class TransformFn >
void transformed_range_copy_assign(Container& c, TransformFn fn)
{
using namespace boost::adaptors;
check_copy_assign(c | transformed(fn));
check_copy_assign(adaptors::transform(c, fn));
}
template< class Container, class TransformFn, class TransformFnInit >
void transformed_test_fn_impl()
{
using namespace boost::assign;
Container c;
TransformFnInit init;
TransformFn fn( init );
// Test empty
transformed_test_impl_core(c, fn);
// Test one element
c += 1;
transformed_test_impl_core(c, fn);
// Test many elements
c += 1,1,1,2,2,2,2,2,3,4,5,6,7,8,9;
transformed_test_impl_core(c, fn);
// test the range and iterator are copy assignable
transformed_range_copy_assign(c, fn);
}
template< class Container >
void transformed_test_impl()
{
transformed_test_fn_impl< Container, double_x, double_x >();
transformed_test_fn_impl< Container, halve_x, halve_x >();
transformed_test_fn_impl< Container, lambda, lambda_init >();
}
void transformed_test()
{
transformed_test_impl< std::vector< int > >();
transformed_test_impl< std::list< int > >();
transformed_test_impl< std::set< int > >();
transformed_test_impl< std::multiset< int > >();
}
struct foo_bind
{
int foo() const { return 7; }
};
void transformed_bind()
{
using namespace boost::adaptors;
using namespace boost::placeholders;
std::vector<foo_bind> input(5);
std::vector<int> output;
boost::range::push_back(
output,
input | transformed(boost::bind(&foo_bind::foo, _1)));
BOOST_CHECK_EQUAL(output.size(), input.size());
std::vector<int> reference_output(5, 7);
BOOST_CHECK_EQUAL_COLLECTIONS(
output.begin(), output.end(),
reference_output.begin(), reference_output.end());
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed" );
test->add(BOOST_TEST_CASE(&boost::transformed_test));
test->add(BOOST_TEST_CASE(&boost::transformed_bind));
return test;
}

View File

@@ -0,0 +1,72 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[transformed_example
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
namespace
{
//->
struct double_int
{
typedef int result_type;
int operator()(int x) const { return x * 2; }
};
//<-
void transformed_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::adaptors;
using namespace boost::assign;
std::vector<int> input;
input += 1,2,3,4,5,6,7,8,9,10;
boost::copy(
input | transformed(double_int()),
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 2,4,6,8,10,12,14,16,18,20;
std::vector<int> test;
boost::push_back(test, input | transformed(double_int()));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed_example" );
test->add( BOOST_TEST_CASE( &transformed_example_test ) );
return test;
}

View File

@@ -0,0 +1,44 @@
// 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)
//
#include <boost/range/adaptor/type_erased.hpp>
#include "type_erased_test.hpp"
#include <boost/test/unit_test.hpp>
#include <list>
#include <vector>
namespace boost_range_adaptor_type_erased_test
{
namespace
{
void test_type_erased()
{
test_driver< std::list<int> >();
test_driver< std::vector<int> >();
test_driver< std::list<MockType> >();
test_driver< std::vector<MockType> >();
}
} // anonymous namespace
} // namespace boost_range_adaptor_type_erased_test
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test =
BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased");
test->add(BOOST_TEST_CASE(
&boost_range_adaptor_type_erased_test::test_type_erased));
return test;
}

View File

@@ -0,0 +1,88 @@
// 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)
//
#include <boost/range/adaptor/type_erased.hpp>
#include "type_erased_test.hpp"
#include <boost/test/unit_test.hpp>
#include <vector>
namespace boost_range_adaptor_type_erased_test
{
namespace
{
class dummy_interface
{
public:
virtual ~dummy_interface() { }
virtual void test() = 0;
protected:
dummy_interface() { }
private:
dummy_interface(const dummy_interface&);
void operator=(const dummy_interface&);
};
class dummy_impl
: public dummy_interface
{
public:
dummy_impl() { }
dummy_impl(const dummy_impl&) { }
dummy_impl& operator=(const dummy_impl&) { return *this; }
virtual void test() { }
};
typedef boost::any_range<
dummy_interface,
boost::random_access_traversal_tag,
dummy_interface&,
std::ptrdiff_t
> any_interface_range;
struct foo_dummy_interface_fn
{
void operator()(dummy_interface& iface)
{
iface.test();
}
};
void foo_test_dummy_interface_range(any_interface_range rng)
{
std::for_each(boost::begin(rng), boost::end(rng),
foo_dummy_interface_fn());
}
void test_type_erased_abstract()
{
std::vector<dummy_impl> v(10);
any_interface_range r(v);
foo_test_dummy_interface_range(r);
foo_test_dummy_interface_range(any_interface_range(v));
}
} // anonymous namespace
} // namespace boost_range_adaptor_type_erased_test
boost::unit_test::test_suite*
init_unit_test_suite(int, char*[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_abstract");
test->add(
BOOST_TEST_CASE(
&boost_range_adaptor_type_erased_test::test_type_erased_abstract));
return test;
}

View File

@@ -0,0 +1,57 @@
// 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)
//
#include <boost/range/adaptor/type_erased.hpp>
#include "type_erased_test.hpp"
#include <boost/test/unit_test.hpp>
#include <list>
#include <deque>
#include <vector>
namespace boost_range_adaptor_type_erased_test
{
namespace
{
void test_bidirectional()
{
test_type_erased_exercise_buffer_types<
std::list<int>, boost::bidirectional_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::deque<int>, boost::bidirectional_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::vector<int>, boost::bidirectional_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::list<MockType>, boost::bidirectional_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::deque<MockType>, boost::bidirectional_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::vector<MockType>, boost::bidirectional_traversal_tag >();
}
} // anonymous namespace
} // namespace boost_range_adaptor_type_erased_test
boost::unit_test::test_suite*
init_unit_test_suite(int, char*[])
{
boost::unit_test::test_suite* test =
BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_bidirectional");
test->add(BOOST_TEST_CASE(
&boost_range_adaptor_type_erased_test::test_bidirectional));
return test;
}

View File

@@ -0,0 +1,70 @@
// 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)
//
#include <boost/range/adaptor/type_erased.hpp>
#include "type_erased_test.hpp"
#include <boost/test/unit_test.hpp>
#include <vector>
namespace boost_range_adaptor_type_erased_test
{
namespace
{
void test_operator_brackets()
{
typedef boost::adaptors::type_erased<> type_erased_t;
std::vector<int> c;
for (int i = 0; i < 10; ++i)
c.push_back(i);
typedef boost::any_range_type_generator<
std::vector<int> >::type any_range_type;
BOOST_STATIC_ASSERT((
boost::is_same<
int,
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();
for (int i = 0; i < 10; ++i)
{
BOOST_CHECK_EQUAL(rng[i], i);
}
}
} // anonymous namespace
} // namespace boost_range_adaptor_type_erased_test
boost::unit_test::test_suite*
init_unit_test_suite(int, char*[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_brackets");
test->add(
BOOST_TEST_CASE(
&boost_range_adaptor_type_erased_test::test_operator_brackets));
return test;
}

View File

@@ -0,0 +1,124 @@
// 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/
//
//[type_erased_example
#include <boost/range/adaptor/type_erased.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <boost/foreach.hpp>
#include <iterator>
#include <iostream>
#include <list>
#include <vector>
//<-
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
namespace
{
namespace boost_range_test
{
namespace type_erased_example
{
//->
// The client interface from an OO perspective merely requires a sequence
// of integers that can be forward traversed
typedef boost::any_range<
int
, boost::forward_traversal_tag
, int
, std::ptrdiff_t
> integer_range;
namespace server
{
void display_integers(const integer_range& rng)
{
boost::copy(rng,
std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl;
}
}
namespace client
{
void run()
{
using namespace boost::assign;
using namespace boost::adaptors;
// Under most conditions one would simply use an appropriate
// any_range as a function parameter. The type_erased adaptor
// is often superfluous. However because the type_erased
// adaptor is applied to a range, we can use default template
// arguments that are generated in conjunction with the
// range type to which we are applying the adaptor.
std::vector<int> input;
input += 1,2,3,4,5;
// Note that this call is to a non-template function
server::display_integers(input);
std::list<int> input2;
input2 += 6,7,8,9,10;
// Note that this call is to the same non-tempate function
server::display_integers(input2);
input2.clear();
input2 += 11,12,13,14,15;
// Calling using the adaptor looks like this:
// Notice that here I have a type_erased that would be a
// bidirectional_traversal_tag, but this is convertible
// to the forward_traversal_tag equivalent hence this
// works.
server::display_integers(input2 | type_erased<>());
// However we may simply wish to define an adaptor that
// takes a range and makes it into an appropriate
// forward_traversal any_range...
typedef boost::adaptors::type_erased<
boost::use_default
, boost::forward_traversal_tag
> type_erased_forward;
// This adaptor can turn other containers with different
// value_types and reference_types into the appropriate
// any_range.
server::display_integers(input2 | type_erased_forward());
}
}
//=int main(int argc, const char* argv[])
//={
//= client::run();
//= return 0;
//=}
//]
} // namespace type_erased_example
} // namespace boost_range_test
} // anonymous namespace
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased_example" );
test->add( BOOST_TEST_CASE( &boost_range_test::type_erased_example::client::run) );
return test;
}

View File

@@ -0,0 +1,57 @@
// 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)
//
#include <boost/range/adaptor/type_erased.hpp>
#include "type_erased_test.hpp"
#include <boost/test/unit_test.hpp>
#include <deque>
#include <list>
#include <vector>
namespace boost_range_adaptor_type_erased_test
{
namespace
{
void test_forward()
{
test_type_erased_exercise_buffer_types<
std::list<int>, boost::forward_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::deque<int>, boost::forward_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::vector<int>, boost::forward_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::list<MockType>, boost::forward_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::deque<MockType>, boost::forward_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::vector<MockType>, boost::forward_traversal_tag >();
}
} // anonymous namespace
} // namespace boost_range_adaptor_type_erased_test
boost::unit_test::test_suite*
init_unit_test_suite(int, char*[])
{
boost::unit_test::test_suite* test =
BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased_forward" );
test->add(BOOST_TEST_CASE(
&boost_range_adaptor_type_erased_test::test_forward));
return test;
}

View File

@@ -0,0 +1,94 @@
// 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)
//
#include <boost/range/adaptor/type_erased.hpp>
#include "type_erased_test.hpp"
#include <boost/test/unit_test.hpp>
#include <vector>
namespace boost_range_adaptor_type_erased_test
{
namespace
{
template<
class Traversal
, class ValueType
, class SourceValueType
, class SourceReference
, class TargetValueType
, class TargetReference
>
void mix_values_impl()
{
typedef std::vector<ValueType> Container;
typedef typename boost::any_range_type_generator<
Container
, SourceValueType
, Traversal
, SourceReference
>::type source_type;
typedef typename boost::any_range_type_generator<
Container
, TargetValueType
, Traversal
, TargetReference
>::type target_type;
Container test_data;
for (int i = 0; i < 10; ++i)
test_data.push_back(i);
const source_type source_data(test_data);
target_type t1(source_data);
BOOST_CHECK_EQUAL_COLLECTIONS(source_data.begin(), source_data.end(),
t1.begin(), t1.end());
target_type t2;
t2 = source_data;
BOOST_CHECK_EQUAL_COLLECTIONS(source_data.begin(), source_data.end(),
t2.begin(), t2.end());
}
template<class Traversal>
void mix_values_driver()
{
mix_values_impl<
Traversal,
MockType,
MockType2, const MockType&,
MockType, const MockType&
>();
}
void mix_values()
{
mix_values_driver<boost::single_pass_traversal_tag >();
mix_values_driver<boost::forward_traversal_tag >();
mix_values_driver<boost::bidirectional_traversal_tag >();
mix_values_driver<boost::random_access_traversal_tag >();
}
} // anonymous namespace
} // namespace boost_range_adaptor_type_erased_test
boost::unit_test::test_suite*
init_unit_test_suite(int, char*[])
{
boost::unit_test::test_suite* test =
BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_mix_values");
test->add(BOOST_TEST_CASE(
&boost_range_adaptor_type_erased_test::mix_values));
return test;
}

View File

@@ -0,0 +1,50 @@
// 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)
//
#include <boost/range/adaptor/type_erased.hpp>
#include "type_erased_test.hpp"
#include <boost/test/unit_test.hpp>
#include <deque>
#include <vector>
namespace boost_range_adaptor_type_erased_test
{
namespace
{
void test_random_access()
{
test_type_erased_exercise_buffer_types<
std::deque<int>, boost::random_access_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::vector<int>, boost::random_access_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::deque<MockType>, boost::random_access_traversal_tag >();
test_type_erased_exercise_buffer_types<
std::vector<MockType>, boost::random_access_traversal_tag >();
}
} // anonymous namespace
} // namespace boost_range_adaptor_type_erased_test
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test =
BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_random_access");
test->add(BOOST_TEST_CASE(
&boost_range_adaptor_type_erased_test::test_random_access));
return test;
}

View File

@@ -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)
//
#include <boost/range/adaptor/type_erased.hpp>
#include "type_erased_test.hpp"
#include <boost/test/unit_test.hpp>
#include <deque>
#include <list>
#include <vector>
namespace boost_range_adaptor_type_erased_test
{
namespace
{
void test_single_pass()
{
test_type_erased_exercise_buffer_types<
std::list<int>, boost::single_pass_traversal_tag>();
test_type_erased_exercise_buffer_types<
std::deque<int>, boost::single_pass_traversal_tag>();
test_type_erased_exercise_buffer_types<
std::vector<int>, boost::single_pass_traversal_tag>();
test_type_erased_exercise_buffer_types<
std::list<MockType>, boost::single_pass_traversal_tag>();
test_type_erased_exercise_buffer_types<
std::deque<MockType>, boost::single_pass_traversal_tag>();
test_type_erased_exercise_buffer_types<
std::vector<MockType>, boost::single_pass_traversal_tag>();
}
} // anonymous namespace
} // namespace boost_range_adaptor_type_erased_test
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test =
BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_single_pass");
test->add(BOOST_TEST_CASE(
&boost_range_adaptor_type_erased_test::test_single_pass));
return test;
}

View File

@@ -0,0 +1,289 @@
// 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)
//
#ifndef BOOST_RANGE_ADAPTOR_TEST_TYPE_ERASED_TEST_HPP
#define BOOST_RANGE_ADAPTOR_TEST_TYPE_ERASED_TEST_HPP
#include <boost/range/algorithm/fill.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/assign.hpp>
#include <boost/test/test_tools.hpp>
namespace boost_range_adaptor_type_erased_test
{
class MockType
{
public:
MockType()
: m_x(0)
{
}
MockType(boost::int32_t x)
: m_x(x)
{
}
boost::int32_t get() const { return m_x; }
inline bool operator==(const MockType& other) const
{
return m_x == other.m_x;
}
inline bool operator!=(const MockType& other) const
{
return m_x != other.m_x;
}
private:
boost::int32_t m_x;
};
class MockType2 : public MockType
{
public:
MockType2() {}
MockType2(boost::int32_t x) : MockType(x) { }
MockType2(const MockType& other) : MockType(other) { }
};
inline std::ostream& operator<<(std::ostream& out, const MockType& obj)
{
out << obj.get();
return out;
}
template<class Container>
void test_type_erased_impl(Container& c)
{
using namespace boost::adaptors;
typedef typename boost::range_value<Container>::type value_type;
typedef typename boost::adaptors::type_erased<> type_erased_t;
std::vector<value_type> output;
boost::push_back(output, boost::adaptors::type_erase(c, type_erased_t()));
BOOST_CHECK_EQUAL_COLLECTIONS( output.begin(), output.end(),
c.begin(), c.end() );
output.clear();
boost::push_back(output, c | type_erased_t());
BOOST_CHECK_EQUAL_COLLECTIONS( output.begin(), output.end(),
c.begin(), c.end() );
}
template<class Container>
void test_const_and_mutable(Container& c)
{
test_type_erased_impl(c);
const Container& const_c = c;
test_type_erased_impl(const_c);
}
template<class Container>
void test_driver()
{
using namespace boost::assign;
typedef typename boost::range_value<Container>::type value_type;
Container c;
test_const_and_mutable(c);
c += value_type(1);
test_const_and_mutable(c);
c += value_type(2);
test_const_and_mutable(c);
}
template<
class Traversal
, class Container
>
void test_writeable(Container&, boost::single_pass_traversal_tag)
{}
template<
class Traversal
, class Container
>
void test_writeable(Container& source, boost::forward_traversal_tag)
{
using namespace boost::adaptors;
typedef typename boost::range_value<Container>::type value_type;
typedef typename boost::range_difference<Container>::type difference_type;
typedef typename boost::range_reference<Container>::type mutable_reference_type;
typedef boost::any_range<
value_type
, Traversal
, mutable_reference_type
, difference_type
> mutable_any_range;
mutable_any_range r = source | boost::adaptors::type_erased<>();
std::vector<value_type> output_test;
boost::fill(r, value_type(1));
BOOST_CHECK_EQUAL( boost::distance(r), boost::distance(source) );
std::vector<value_type> reference_output(source.size(), value_type(1));
BOOST_CHECK_EQUAL_COLLECTIONS( reference_output.begin(), reference_output.end(),
r.begin(), r.end() );
}
template<
class Container
, class Traversal
, class Buffer
>
void test_type_erased_impl()
{
using namespace boost::adaptors;
typedef typename boost::range_value<Container>::type value_type;
typedef typename boost::any_range_type_generator<
Container
, boost::use_default
, Traversal
, boost::use_default
, boost::use_default
, Buffer
>::type mutable_any_range;
typedef typename boost::any_range_type_generator<
const Container
, boost::use_default
, Traversal
, boost::use_default
, boost::use_default
, Buffer
>::type const_any_range;
typedef boost::adaptors::type_erased<
boost::use_default
, Traversal
, boost::use_default
, boost::use_default
, Buffer
> type_erased_t;
Container source;
for (int i = 0; i < 10; ++i)
source.push_back(value_type(i));
mutable_any_range r(source);
BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(),
r.begin(), r.end() );
r = mutable_any_range();
BOOST_CHECK_EQUAL( r.empty(), true );
r = source | type_erased_t();
BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(),
r.begin(), r.end() );
r = mutable_any_range();
r = boost::adaptors::type_erase(source, type_erased_t());
BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(),
r.begin(), r.end() );
r = mutable_any_range();
test_writeable<Traversal>(source, Traversal());
// convert and construct a const any_range from a mutable source
// range
const_any_range cr(source);
BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(),
cr.begin(), cr.end() );
// assign an empty range and ensure that this correctly results
// in an empty range. This is important for the validity of
// the rest of the tests.
cr = const_any_range();
BOOST_CHECK_EQUAL( cr.empty(), true );
// Test the pipe type_erased adaptor from a constant source
// range to a constant any_range
const Container& const_source = source;
cr = const_any_range();
cr = const_source | type_erased_t();
BOOST_CHECK_EQUAL_COLLECTIONS( const_source.begin(), const_source.end(),
cr.begin(), cr.end() );
// Test the pipe type erased adaptor from a mutable source
// range to a constant any_range
cr = const_any_range();
cr = source | type_erased_t();
BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(),
cr.begin(), cr.end() );
// Use the function form of the type_erase adaptor from a constant
// source range
cr = const_any_range();
cr = boost::adaptors::type_erase(const_source, type_erased_t());
BOOST_CHECK_EQUAL_COLLECTIONS( const_source.begin(), const_source.end(),
cr.begin(), cr.end() );
// Assignment from mutable to const...
cr = const_any_range();
cr = r;
BOOST_CHECK_EQUAL_COLLECTIONS( cr.begin(), cr.end(),
r.begin(), r.end() );
// Converting copy from mutable to const...
cr = const_any_range();
cr = const_any_range(r);
BOOST_CHECK_EQUAL_COLLECTIONS( cr.begin(), cr.end(),
r.begin(), r.end() );
}
template<
class Container
, class Traversal
, class Buffer
>
class test_type_erased_impl_fn
{
public:
typedef void result_type;
void operator()()
{
test_type_erased_impl< Container, Traversal, Buffer >();
}
};
template<
class Container
, class Traversal
>
void test_type_erased_exercise_buffer_types()
{
using boost::any_iterator_default_buffer;
using boost::any_iterator_buffer;
using boost::any_iterator_heap_only_buffer;
using boost::any_iterator_stack_only_buffer;
test_type_erased_impl_fn< Container, Traversal, any_iterator_default_buffer >()();
test_type_erased_impl_fn< Container, Traversal, any_iterator_heap_only_buffer >()();
test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<1> >()();
test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<2> >()();
test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<32> >()();
test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<64> >()();
test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<128> >()();
test_type_erased_impl_fn< Container, Traversal, any_iterator_stack_only_buffer<128> >()();
}
} // namespace boost_range_adaptor_type_erased_test
#endif // include guard

View File

@@ -0,0 +1,74 @@
// 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)
//
#include <boost/range/adaptor/type_erased.hpp>
#include "type_erased_test.hpp"
#include <boost/test/unit_test.hpp>
#include <algorithm>
#include <vector>
namespace boost_range_adaptor_type_erased_test
{
namespace
{
void template_parameter_conversion()
{
typedef boost::any_range<
int
, boost::random_access_traversal_tag
, int&
, std::ptrdiff_t
> source_range_type;
typedef boost::any_range<
int
, boost::single_pass_traversal_tag
, const int&
, std::ptrdiff_t
> target_range_type;
source_range_type source;
// Converting via construction
target_range_type t1(source);
// Converting via assignment
target_range_type t2;
t2 = source;
// Converting via construction to a type with a reference type
// that is a value
typedef boost::any_range<
int
, boost::single_pass_traversal_tag
, int
, std::ptrdiff_t
> target_range2_type;
target_range2_type t3(source);
target_range2_type t4;
t4 = source;
}
} // anonymous namespace
} // namespace boost_range_adaptor_type_erased_test
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test =
BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_tparam_conv");
test->add(BOOST_TEST_CASE(
&boost_range_adaptor_type_erased_test::template_parameter_conversion));
return test;
}

View File

@@ -0,0 +1,67 @@
// 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)
//
#include <boost/range/adaptor/type_erased.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/numeric.hpp>
#include "type_erased_test.hpp"
#include <boost/test/unit_test.hpp>
#include <vector>
namespace boost_range_adaptor_type_erased_test
{
namespace
{
typedef boost::any_range<
int,
boost::random_access_traversal_tag,
int,
std::ptrdiff_t
> any_integer_value_range;
struct get_fn
{
typedef boost::int32_t result_type;
boost::int32_t operator()(const MockType& val) const
{
return val.get();
}
};
int accumulate_any_integer_value_range(any_integer_value_range rng)
{
return boost::accumulate(rng, 0);
}
void test_type_erased_transformed()
{
std::vector<MockType> v(5, MockType(3));
const int sum = accumulate_any_integer_value_range(
v | boost::adaptors::transformed(get_fn()));
BOOST_CHECK_EQUAL(15, sum);
}
} // anonymous namespace
} // namespace boost_range_adaptor_type_erased_test
boost::unit_test::test_suite*
init_unit_test_suite(int, char*[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_transformed");
test->add(
BOOST_TEST_CASE(
&boost_range_adaptor_type_erased_test::test_type_erased_transformed));
return test;
}

View File

@@ -0,0 +1,168 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/adaptor/uniqued.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/unique_copy.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void uniqued_test_impl( Container& c )
{
using namespace boost::adaptors;
std::vector< int > test_result1;
boost::push_back(test_result1, c | uniqued);
std::vector< int > test_result2;
boost::push_back(test_result2, adaptors::unique(c));
std::vector< int > reference(c.begin(), c.end());
reference.erase(
std::unique(reference.begin(), reference.end()),
reference.end());
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test_result1.begin(), test_result1.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test_result2.begin(), test_result2.end() );
}
template< class Container >
void uniqued_test_impl()
{
using namespace boost::assign;
Container c;
// Test empty
uniqued_test_impl(c);
// Test one
c += 1;
uniqued_test_impl(c);
// Test many
c += 1,1,1,2,2,2,2,2,3,3,3,3,4,5,6,6,6,7,7,7,8,8,9,9,9,9,9,10;
uniqued_test_impl(c);
}
void uniqued_test()
{
uniqued_test_impl< std::vector< int > >();
uniqued_test_impl< std::list< int > >();
uniqued_test_impl< std::set< int > >();
uniqued_test_impl< std::multiset< int > >();
}
class istring
{
public:
istring()
: m_value("")
{
}
explicit istring(const char* value)
: m_value(value)
{
}
bool operator==(istring r) const
{
return boost::iequals(m_value, r.m_value);
}
bool operator!=(istring r) const
{
return !operator==(r);
}
inline friend std::ostream& operator<<(std::ostream& out, istring o)
{
return out << o.m_value;
}
const char* get() const { return m_value; }
private:
const char* m_value;
};
struct istring_to_string
{
typedef std::string result_type;
std::string operator()(istring s) const
{
return s.get();
}
};
// This is based on a test-case provided by Eric Neibler.
void uniqued_return_first()
{
using namespace boost::adaptors;
std::vector<istring> strs;
strs.push_back(istring("hello"));
strs.push_back(istring("hElLo"));
strs.push_back(istring("HELLO"));
strs.push_back(istring("ZZZZ"));
std::vector<istring> output1;
boost::unique_copy(strs, std::back_inserter(output1));
std::vector<istring> output2;
boost::push_back(output2, strs | uniqued);
std::vector<std::string> test1;
boost::push_back(test1, output1 | transformed(istring_to_string()));
std::vector<std::string> test2;
boost::push_back(test2, output2 | transformed(istring_to_string()));
BOOST_CHECK_EQUAL_COLLECTIONS(test1.begin(), test1.end(),
test2.begin(), test2.end());
}
} // anonymous namespace
} // namespace boost
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.uniqued" );
test->add( BOOST_TEST_CASE( &boost::uniqued_test ) );
test->add(BOOST_TEST_CASE(&boost::uniqued_return_first));
return test;
}

View File

@@ -0,0 +1,64 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
//[uniqued_example
#include <boost/range/adaptor/uniqued.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
//<-
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
namespace
{
void uniqued_example_test()
//->
//=int main(int argc, const char* argv[])
{
using namespace boost::assign;
using namespace boost::adaptors;
std::vector<int> input;
input += 1,1,2,2,2,3,4,5,6;
boost::copy(
input | uniqued,
std::ostream_iterator<int>(std::cout, ","));
//= return 0;
//=}
//]
std::vector<int> reference;
reference += 1,2,3,4,5,6;
std::vector<int> test;
boost::push_back( test, input | uniqued );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.uniqued_example" );
test->add( BOOST_TEST_CASE( &uniqued_example_test ) );
return test;
}

View File

@@ -0,0 +1,236 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2006. 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/adaptors.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/foreach.hpp>
#include <boost/assign/list_of.hpp>
#include <vector>
#include <list>
#include <string>
#include <map>
template< class T >
struct less_than
{
T val;
less_than() : val(0)
{}
less_than( T t ) : val(t)
{}
bool operator()( const T& r ) const
{
return r < val;
}
};
template< class T >
struct multiply
{
T val;
typedef T& result_type;
multiply( T t ) : val(t)
{ }
T& operator()( T& r ) const
{
return r *= 2;
}
};
template< class Rng >
void check_copy( Rng r )
{
//
// Make sure the generated iterators
// can actually be copied
//
Rng r2 = r;
r2 = r;
}
template< class Rng >
void check_direct()
{
using namespace boost::adaptors;
Rng rng = boost::assign::list_of(1)(2)(3)(4)(5).to_container( rng );
Rng out;
//
// test each alphabetically
//
BOOST_FOREACH( int i, rng | filtered( less_than<int>(4) )
/*| reversed*/
| transformed( multiply<int>(2) ) )
{
out.push_back( i );
}
BOOST_CHECK_EQUAL( out.size(), 3u );
BOOST_CHECK_EQUAL( *out.begin(), 2 );
BOOST_CHECK_EQUAL( *boost::next(out.begin()), 4 );
BOOST_CHECK_EQUAL( *boost::next(out.begin(),2), 6 );
rng = boost::assign::list_of(1)(1)(2)(2)(3)(3)(4)(5).to_container( rng );
out.clear();
/*
BOOST_FOREACH( int i, rng | adjacent_filtered( std::equal_to<int>() )
| uniqued )
{
out.push_back( i );
}*/
}
template< class IndirectRng >
void check_indirect()
{
using namespace boost::adaptors;
IndirectRng rng;
std::vector< boost::shared_ptr< int > > holder;
for( unsigned i = 0u; i != 20u; ++i )
{
boost::shared_ptr<int> v(new int(i));
rng.push_back( v.get() );
}
BOOST_FOREACH( int& i, rng | indirected | reversed
| transformed( multiply<int>(2) ) )
{
i += 1;
}
}
template< class RandomAccessRng >
void check_random_access()
{
using namespace boost::adaptors;
RandomAccessRng rng(1, 20u);
RandomAccessRng out;
BOOST_FOREACH( int i, rng | reversed
| transformed( multiply<int>(2) )
/* | sliced(0,15) */ )
{
out.push_back( i );
}
BOOST_FOREACH( int i, rng | copied(3u,13u) )
{
out.push_back( i );
}
}
template< class Map >
void check_map()
{
using namespace boost::adaptors;
Map m;
m.insert( std::make_pair(1,2) );
m.insert( std::make_pair(2,2) );
m.insert( std::make_pair(3,2) );
m.insert( std::make_pair(4,2) );
m.insert( std::make_pair(5,2) );
m.insert( std::make_pair(6,2) );
m.insert( std::make_pair(7,2) );
std::vector<int> keys
= boost::copy_range< std::vector<int> >( m | map_keys );
std::vector<int> values
= boost::copy_range< std::vector<int> >( m | map_values );
}
void check_regex()
{
using namespace boost::adaptors;
std::string s("This is a string of tokens");
std::vector<std::string> tokens =
boost::copy_range< std::vector<std::string> >( s | tokenized( "\\s+", -1 ) );
}
void check_adaptors()
{
check_direct< std::vector<int> >();
check_direct< std::list<int> >();
check_indirect< std::vector<int*> >();
check_indirect< std::list<int*> >();
check_map< std::map<int,int> >();
// check_random_access< std::vector<int> >();
check_regex();
using namespace boost::adaptors;
std::vector<int> vec(10u,20);
std::vector<int*> pvec;
std::map<int,int> map;
check_copy( vec | adjacent_filtered( std::equal_to<int>() ) );
// check_copy( vec | indexed );
check_copy( vec | reversed );
check_copy( vec | uniqued );
check_copy( pvec | indirected );
// check_copy( vec | sliced(1,5) );
//
// This does not return an iterator_range<>, so
// won't pass this test of implicit conversion
// check_copy( vec | copied(1,5) );
//
check_copy( map | map_values );
check_copy( map | map_keys );
check_copy( std::string( "a string" ) | tokenized( "\\s+", -1 ) );
check_copy( vec | filtered( less_than<int>(2) ) );
check_copy( vec | transformed( multiply<int>(2) ) );
}
using boost::unit_test::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
using namespace boost;
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - Adaptors" );
test->add( BOOST_TEST_CASE( &check_adaptors ) );
return test;
}

View File

@@ -0,0 +1,188 @@
// 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(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
# pragma warn -8091 // suppress warning in Boost.Test
# pragma warn -8057 // unused argument argc/argv in Boost.Test
#endif
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
enum adl_types
{
unused,
boost_namespace,
templated_namespace,
non_templated_namespace,
global_namespace
};
// Use boost_test rather than boost as the namespace for this test
// to allow the test framework to use boost::begin() etc. without
// violating the One Defintion Rule.
namespace boost_test
{
namespace range_detail
{
template< class Range >
inline typename Range::iterator begin( Range& r )
{
return boost_namespace;
}
template< class Range >
inline typename Range::iterator begin( const Range& r )
{
return boost_namespace;
}
}
template< class Range >
inline typename Range::iterator begin( Range& r )
{
using range_detail::begin; // create ADL hook
return begin( r );
}
template< class Range >
inline typename Range::iterator begin( const Range& r )
{
using range_detail::begin; // create ADL hook
return begin( r );
}
} // 'boost_test'
namespace find_templated
{
template< class T >
struct range
{
typedef adl_types iterator;
range() { /* allow const objects */ }
iterator begin() { return unused; }
iterator begin() const { return unused; }
iterator end() { return unused; }
iterator end() const { return unused; }
};
//
// A fully generic version here will create
// ambiguity.
//
template< class T >
inline typename range<T>::iterator begin( range<T>& r )
{
return templated_namespace;
}
template< class T >
inline typename range<T>::iterator begin( const range<T>& r )
{
return templated_namespace;
}
}
namespace find_non_templated
{
struct range
{
typedef adl_types iterator;
range() { /* allow const objects */ }
iterator begin() { return unused; }
iterator begin() const { return unused; }
iterator end() { return unused; }
iterator end() const { return unused; }
};
inline range::iterator begin( range& r )
{
return non_templated_namespace;
}
inline range::iterator begin( const range& r )
{
return non_templated_namespace;
}
}
struct range
{
typedef adl_types iterator;
range() { /* allow const objects */ }
iterator begin() { return unused; }
iterator begin() const { return unused; }
iterator end() { return unused; }
iterator end() const { return unused; }
};
inline range::iterator begin( range& r )
{
return global_namespace;
}
inline range::iterator begin( const range& r )
{
return global_namespace;
}
void check_adl_conformance()
{
find_templated::range<int> r;
const find_templated::range<int> r2;
find_non_templated::range r3;
const find_non_templated::range r4;
range r5;
const range r6;
//
// Notice how ADL kicks in even when we have qualified
// notation!
//
BOOST_CHECK( boost_test::begin( r ) != boost_namespace );
BOOST_CHECK( boost_test::begin( r2 ) != boost_namespace );
BOOST_CHECK( boost_test::begin( r3 ) != boost_namespace );
BOOST_CHECK( boost_test::begin( r4 ) != boost_namespace );
BOOST_CHECK( boost_test::begin( r5 ) != boost_namespace );
BOOST_CHECK( boost_test::begin( r6 ) != boost_namespace );
BOOST_CHECK_EQUAL( boost_test::begin( r ), templated_namespace ) ;
BOOST_CHECK_EQUAL( boost_test::begin( r2 ), templated_namespace );
BOOST_CHECK_EQUAL( boost_test::begin( r3 ), non_templated_namespace );
BOOST_CHECK_EQUAL( boost_test::begin( r4 ), non_templated_namespace );
BOOST_CHECK_EQUAL( boost_test::begin( r5 ), global_namespace );
BOOST_CHECK_EQUAL( boost_test::begin( r6 ), global_namespace );
}
#include <boost/test/included/unit_test.hpp>
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_adl_conformance ) );
return test;
}

View File

@@ -0,0 +1,110 @@
// 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 <iostream>
namespace A
{
namespace detail
{
template< typename T >
int f( const T& x )
{
// Default:
std::cout << 1 << std::endl;
return 1;
}
template< typename T >
int adl_f2( const T& x, int* )
{
return f( x );
}
template< typename T >
int adl_f( const T& x )
{
return adl_f2( x, 0 );
}
}
template< typename T >
int f( const T& x )
{
return detail::adl_f( x );
}
template< typename T >
int adl_f2( const T& x, int )
{
return detail::f( x );
}
//--------------------------------
class C {};
/*
// Optional:
int f( const C& x )
{
std::cout << 2 << std::endl;
}
*/
template< typename T >
class D {};
/*
// Optional:
template< typename T >
int f( const D< T >& x )
{
std::cout << 3 << std::endl;
}
*/
}
namespace B
{
class C {};
// Optional:
/* int f( const C& )
{
std::cout << 4 << std::endl;
}
*/
template< typename T >
class D {};
/*
// Optional:
template< typename T >
int f( const D< T >& x )
{
std::cout << 5 << std::endl;
}
*/
}
int main()
{
A::f( 42 );
A::C ac;
A::f( ac );
A::D< int > ad;
A::f( ad );
B::C bc;
A::f( bc );
B::D< int > bd;
A::f( bd );
}

View File

@@ -0,0 +1,478 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2006. 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/
//
// (C) Copyright Eric Niebler 2004.
// Use, modification and distribution are 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)
/*
Revision history:
13 December 2004 : Initial version.
*/
#ifdef _MSC_VER
// The 'secure' library warnings produce so much noise that it makes it
// impossible to see more useful warnings.
#define _SCL_SECURE_NO_WARNINGS
#endif
#ifdef _MSC_VER
// counting_iterator generates a warning about truncating an integer
#pragma warning(push)
#pragma warning(disable : 4244)
#endif
#include <boost/iterator/counting_iterator.hpp>
#ifdef _MSC_VER
template ::boost::counting_iterator<int>;
#pragma warning(pop)
#endif
#include <boost/assign.hpp>
#include <boost/config.hpp>
#include <boost/array.hpp>
#include <boost/range/numeric.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/size_type.hpp>
#include <boost/range/size.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <list>
#include <vector>
#include <iterator>
#include <functional>
///////////////////////////////////////////////////////////////////////////////
// dummy function object, used with algorithms
//
struct null_fun
{
template<typename T>
void operator()(T const &t) const
{
}
};
///////////////////////////////////////////////////////////////////////////////
// dummy predicate, used with algorithms
//
struct null_pred
{
template<typename T>
bool operator()(T const &t) const
{
return t == T();
}
};
///////////////////////////////////////////////////////////////////////////////
// dummy unary op, used with algorithms
//
struct null_op1
{
template<typename T>
T const & operator()(T const & t) const
{
return t;
}
};
///////////////////////////////////////////////////////////////////////////////
// dummy binary op, used with algorithms
//
struct null_op2
{
template<typename T,typename U>
T const & operator()(T const & t, U const & u) const
{
return t;
}
};
template<typename Rng>
void test_random_algorithms(Rng & rng, std::random_access_iterator_tag)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Rng>::type iterator;
typedef BOOST_DEDUCED_TYPENAME boost::range_value<Rng>::type value_type;
typedef BOOST_DEDUCED_TYPENAME boost::range_size<Rng>::type
size_type BOOST_RANGE_UNUSED;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_category<iterator>::type
iterator_category BOOST_RANGE_UNUSED;
// just make sure these compile (for now)
if(0)
{
boost::random_shuffle(rng);
// Must be a value since random_shuffle must take the generator by
// reference to match the standard.
null_op1 rng_generator;
boost::random_shuffle(rng, rng_generator);
boost::sort(rng);
boost::sort(rng, std::less<value_type>());
boost::stable_sort(rng);
boost::stable_sort(rng, std::less<value_type>());
boost::partial_sort(rng, boost::begin(rng));
boost::partial_sort(rng, boost::begin(rng), std::less<value_type>());
boost::nth_element(rng, boost::begin(rng));
boost::nth_element(rng, boost::begin(rng), std::less<value_type>());
boost::push_heap(rng);
boost::push_heap(rng, std::less<value_type>());
boost::pop_heap(rng);
boost::pop_heap(rng, std::less<value_type>());
boost::make_heap(rng);
boost::make_heap(rng, std::less<value_type>());
boost::sort_heap(rng);
boost::sort_heap(rng, std::less<value_type>());
}
}
template<typename Rng>
void test_random_algorithms(Rng & rng, std::input_iterator_tag)
{
// no-op
}
template<typename Rng>
void test_algorithms(Rng & rng)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Rng>::type iterator;
typedef BOOST_DEDUCED_TYPENAME boost::range_value<Rng>::type value_type;
typedef BOOST_DEDUCED_TYPENAME boost::range_size<Rng>::type size_type;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_category<iterator>::type iterator_category;
// just make sure these compile (for now)
if(0)
{
value_type val = value_type();
value_type rng2[] = {value_type(),value_type(),value_type()};
typedef value_type* iterator2;
value_type out[100] = {};
typedef value_type* out_iterator;
null_fun f = null_fun();
iterator i = iterator();
bool b = bool();
out_iterator o = out_iterator();
size_type s = size_type();
f = boost::for_each(rng, null_fun());
i = boost::find(rng, val);
i = boost::find_if(rng, null_pred());
i = boost::find_end(rng, rng2);
i = boost::find_end(rng, rng2, std::equal_to<value_type>());
i = boost::find_first_of(rng, rng2);
i = boost::find_first_of(rng, rng2, std::equal_to<value_type>());
i = boost::adjacent_find(rng);
i = boost::adjacent_find(rng, std::equal_to<value_type>());
s = boost::count(rng, val);
s = boost::count_if(rng, null_pred());
std::pair<iterator,iterator2> p1;
p1 = boost::mismatch(rng, rng2);
p1 = boost::mismatch(rng, rng2, std::equal_to<value_type>());
b = boost::equal(rng, rng2);
b = boost::equal(rng, rng2, std::equal_to<value_type>());
i = boost::search(rng, rng2);
i = boost::search(rng, rng2, std::equal_to<value_type>());
o = boost::copy(rng, boost::begin(out));
o = boost::copy_backward(rng, boost::end(out));
o = boost::transform(rng, boost::begin(out), null_op1());
o = boost::transform(rng, rng2, boost::begin(out), null_op2());
boost::replace(rng, val, val);
boost::replace_if(rng, null_pred(), val);
/*
o = boost::replace_copy(rng, boost::begin(out), val, val);
o = boost::replace_copy_if(rng, boost::begin(out), null_pred(), val);
*/
boost::fill(rng, val);
//
// size requires RandomAccess
//
//boost::fill_n(rng, boost::size(rng), val);
//boost::fill_n(rng, std::distance(boost::begin(rng),boost::end(rng)),val);
boost::generate(rng, &std::rand);
//
// size requires RandomAccess
//
//boost::generate_n(rng, boost::size(rng), &std::rand);
//boost::generate_n(rng,std::distance(boost::begin(rng),boost::end(rng)), &std::rand);
i = boost::remove(rng, val);
i = boost::remove_if(rng, null_pred());
/*
o = boost::remove_copy(rng, boost::begin(out), val);
o = boost::remove_copy_if(rng, boost::begin(out), null_pred());
*/
typename boost::range_return<Rng, boost::return_begin_found>::type rrng = boost::unique(rng);
rrng = boost::unique(rng, std::equal_to<value_type>());
/*
o = boost::unique_copy(rng, boost::begin(out));
o = boost::unique_copy(rng, boost::begin(out), std::equal_to<value_type>());
*/
boost::reverse(rng);
/*
o = boost::reverse_copy(rng, boost::begin(out));
*/
boost::rotate(rng, boost::begin(rng));
/*
o = boost::rotate_copy(rng, boost::begin(rng), boost::begin(out));
*/
i = boost::partition(rng, null_pred());
i = boost::stable_partition(rng, null_pred());
/*
o = boost::partial_sort_copy(rng, out);
o = boost::partial_sort_copy(rng, out, std::less<value_type>());
*/
i = boost::lower_bound(rng, val);
i = boost::lower_bound(rng, val, std::less<value_type>());
i = boost::upper_bound(rng, val);
i = boost::upper_bound(rng, val, std::less<value_type>());
std::pair<iterator,iterator> p2;
p2 = boost::equal_range(rng, val);
p2 = boost::equal_range(rng, val, std::less<value_type>());
b = boost::binary_search(rng, val);
b = boost::binary_search(rng, val, std::less<value_type>());
boost::inplace_merge(rng, boost::begin(rng));
boost::inplace_merge(rng, boost::begin(rng), std::less<value_type>());
b = boost::includes(rng, rng2);
b = boost::includes(rng, rng2, std::equal_to<value_type>());
o = boost::set_union(rng, rng2, boost::begin(out));
o = boost::set_union(rng, rng2, boost::begin(out), std::equal_to<value_type>());
o = boost::set_intersection(rng, rng2, boost::begin(out));
o = boost::set_intersection(rng, rng2, boost::begin(out), std::equal_to<value_type>());
o = boost::set_difference(rng, rng2, boost::begin(out));
o = boost::set_difference(rng, rng2, boost::begin(out), std::equal_to<value_type>());
o = boost::set_symmetric_difference(rng, rng2, boost::begin(out));
o = boost::set_symmetric_difference(rng, rng2, boost::begin(out), std::equal_to<value_type>());
i = boost::min_element(rng);
i = boost::min_element(rng, std::less<value_type>());
i = boost::max_element(rng);
i = boost::max_element(rng, std::less<value_type>());
b = boost::lexicographical_compare(rng, rng);
b = boost::lexicographical_compare(rng, rng, std::equal_to<value_type>());
b = boost::next_permutation(rng);
b = boost::next_permutation(rng, std::less<value_type>());
b = boost::prev_permutation(rng);
b = boost::prev_permutation(rng, std::less<value_type>());
/////////////////////////////////////////////////////////////////////
// numeric algorithms
/////////////////////////////////////////////////////////////////////
val = boost::accumulate( rng, val );
val = boost::accumulate( rng, val, null_op2() );
val = boost::inner_product( rng, rng, val );
val = boost::inner_product( rng, rng, val,
null_op2(), null_op2() );
o = boost::partial_sum( rng, boost::begin(out) );
o = boost::partial_sum( rng, boost::begin(out), null_op2() );
o = boost::adjacent_difference( rng, boost::begin(out) );
o = boost::adjacent_difference( rng, boost::begin(out),
null_op2() );
boost::ignore_unused_variable_warning(b);
}
// test the algorithms that require a random-access range
test_random_algorithms(rng, iterator_category());
}
int* addr(int &i) { return &i; }
bool true_(int) { return true; }
///////////////////////////////////////////////////////////////////////////////
// test_main
//
void simple_compile_test()
{
// int_iterator
typedef ::boost::counting_iterator<int> int_iterator;
// define come containers
std::list<int> my_list(int_iterator(1),int_iterator(6));
std::vector<int> my_vector(int_iterator(1),int_iterator(6));
std::pair<std::vector<int>::iterator,std::vector<int>::iterator> my_pair(my_vector.begin(),my_vector.end());
// test the algorithms with list and const list
test_algorithms(my_list);
test_algorithms(my_vector);
test_algorithms(my_pair);
std::vector<int> v;
std::vector<int>& cv = v;
using namespace boost;
#define BOOST_RANGE_RETURNS_TEST( function_name, cont ) \
function_name (cont); \
function_name <return_found> (cont); \
function_name <return_next> (cont); \
function_name <return_prior> (cont); \
function_name <return_begin_found> (cont); \
function_name <return_begin_next> (cont); \
function_name <return_begin_prior> (cont); \
function_name <return_found_end> (cont); \
function_name <return_next_end>(cont); \
function_name <return_prior_end>(cont);
BOOST_RANGE_RETURNS_TEST( adjacent_find, cv );
BOOST_RANGE_RETURNS_TEST( adjacent_find, v );
BOOST_RANGE_RETURNS_TEST( max_element, cv );
BOOST_RANGE_RETURNS_TEST( max_element, v );
BOOST_RANGE_RETURNS_TEST( min_element, cv );
BOOST_RANGE_RETURNS_TEST( min_element, v );
BOOST_RANGE_RETURNS_TEST( unique, v );
#undef BOOST_RANGE_RETURNS_TEST
#define BOOST_RANGE_RETURNS_TEST1( function_name, cont, arg1 ) \
function_name (cont, arg1); \
function_name <return_found> (cont, arg1); \
function_name <return_next> (cont, arg1); \
function_name <return_prior> (cont, arg1); \
function_name <return_begin_found> (cont, arg1); \
function_name <return_begin_next> (cont, arg1); \
function_name <return_begin_prior> (cont, arg1); \
function_name <return_found_end> (cont, arg1); \
function_name <return_next_end>(cont, arg1); \
function_name <return_prior_end>(cont, arg1);
BOOST_RANGE_RETURNS_TEST1( adjacent_find, cv, std::less<int>() );
BOOST_RANGE_RETURNS_TEST1( adjacent_find, v, std::less<int>() );
BOOST_RANGE_RETURNS_TEST1( find, cv, 0 );
BOOST_RANGE_RETURNS_TEST1( find, v, 0 );
BOOST_RANGE_RETURNS_TEST1( find_end, cv, cv );
BOOST_RANGE_RETURNS_TEST1( find_end, cv, v );
BOOST_RANGE_RETURNS_TEST1( find_end, v, cv );
BOOST_RANGE_RETURNS_TEST1( find_end, v, v );
BOOST_RANGE_RETURNS_TEST1( find_first_of, cv, cv );
BOOST_RANGE_RETURNS_TEST1( find_first_of, cv, v );
BOOST_RANGE_RETURNS_TEST1( find_first_of, v, cv );
BOOST_RANGE_RETURNS_TEST1( find_first_of, v, v );
BOOST_RANGE_RETURNS_TEST1( find_if, cv, std::negate<int>() );
BOOST_RANGE_RETURNS_TEST1( find_if, v, std::negate<int>() );
BOOST_RANGE_RETURNS_TEST1( search, cv, cv );
BOOST_RANGE_RETURNS_TEST1( search, cv, v );
BOOST_RANGE_RETURNS_TEST1( search, v, cv );
BOOST_RANGE_RETURNS_TEST1( search, v, v );
BOOST_RANGE_RETURNS_TEST1( remove, v, 0 );
BOOST_RANGE_RETURNS_TEST1( remove_if, v, std::negate<int>() );
BOOST_RANGE_RETURNS_TEST1( lower_bound, cv, 0 );
BOOST_RANGE_RETURNS_TEST1( lower_bound, v, 0 );
BOOST_RANGE_RETURNS_TEST1( max_element, cv, std::less<int>() );
BOOST_RANGE_RETURNS_TEST1( max_element, v, std::less<int>() );
BOOST_RANGE_RETURNS_TEST1( min_element, cv, std::less<int>() );
BOOST_RANGE_RETURNS_TEST1( min_element, v, std::less<int>() );
BOOST_RANGE_RETURNS_TEST1( upper_bound, cv, 0 );
BOOST_RANGE_RETURNS_TEST1( upper_bound, v, 0 );
BOOST_RANGE_RETURNS_TEST1( partition, cv, std::negate<int>() );
BOOST_RANGE_RETURNS_TEST1( partition, v, std::negate<int>() );
BOOST_RANGE_RETURNS_TEST1( stable_partition, cv, std::negate<int>() );
BOOST_RANGE_RETURNS_TEST1( stable_partition, v, std::negate<int>() );
#undef BOOST_RANGE_RETURNS_TEST1
#define BOOST_RANGE_RETURNS_TEST2( function_name, arg1, arg2 ) \
function_name (v, arg1, arg2); \
function_name <return_found> (v, arg1, arg2); \
function_name <return_next> (v, arg1, arg2); \
function_name <return_prior> (v, arg1, arg2); \
function_name <return_begin_found> (v, arg1, arg2); \
function_name <return_begin_next> (v, arg1, arg2); \
function_name <return_begin_prior> (v, arg1, arg2); \
function_name <return_found_end> (v, arg1, arg2); \
function_name <return_next_end>(v, arg1, arg2); \
function_name <return_prior_end>(v, arg1, arg2);
BOOST_RANGE_RETURNS_TEST2( find_end, v, std::less<int>() );
BOOST_RANGE_RETURNS_TEST2( find_first_of, v, std::less<int>() );
BOOST_RANGE_RETURNS_TEST2( boost::search, v, std::less<int>() );
BOOST_RANGE_RETURNS_TEST2( lower_bound, 0, std::less<int>() );
BOOST_RANGE_RETURNS_TEST2( upper_bound, 0, std::less<int>() );
#undef BOOST_RANGE_RETURNS_TEST2
}
using boost::unit_test::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
using namespace boost;
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - Algorithm" );
test->add( BOOST_TEST_CASE( &simple_compile_test ) );
return test;
}

View File

@@ -0,0 +1,92 @@
// 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(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
# pragma warn -8091 // suppress warning in Boost.Test
# pragma warn -8057 // unused argument argc/argv in Boost.Test
#endif
#include <boost/range/functions.hpp>
#include <boost/range/metafunctions.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/test/test_tools.hpp>
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
namespace
{
//
// example: extracting bounds in a generic algorithm
//
template< typename Range, typename T >
inline typename boost::range_iterator<Range>::type
find( Range& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
template< typename Range, typename T >
inline typename boost::range_iterator<Range>::type
find( const Range& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
//
// replace first value and return its index
//
template< class Range, class T >
inline typename boost::range_difference<Range>::type
my_generic_replace( Range& c, const T& value, const T& replacement )
{
typename boost::range_iterator<Range>::type found = find( c, value );
if( found != boost::end( c ) )
*found = replacement;
return std::distance( boost::begin( c ), found );
}
}
void check_algorithm()
{
//
// usage
//
const int N = 5;
std::vector<int> my_vector;
int values[] = { 1,2,3,4,5,6,7,8,9 };
my_vector.assign( values, values + 9 );
typedef std::vector<int>::iterator iterator;
std::pair<iterator,iterator> my_view( boost::begin( my_vector ),
boost::begin( my_vector ) + N );
BOOST_CHECK_EQUAL( my_generic_replace( my_vector, 4, 2 ), 3 );
BOOST_CHECK_EQUAL( my_generic_replace( my_view, 4, 2 ), N );
}
#include <boost/test/unit_test.hpp>
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_algorithm ) );
return test;
}

View File

@@ -0,0 +1,60 @@
// 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/algorithm_ext/copy_n.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator.hpp>
#include <algorithm>
#include <list>
#include <vector>
namespace
{
template< class Container >
void test_copy_n_impl()
{
std::vector<std::size_t> source;
for (std::size_t i = 0; i < 10; ++i)
source.push_back(i);
for (std::size_t k = 0; k < 10; ++k)
{
std::vector<std::size_t> reference;
for (std::size_t j = 0; j < k; ++j)
reference.push_back(j);
Container test;
boost::copy_n(source, k, std::back_inserter(test));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
}
void test_copy_n()
{
test_copy_n_impl< std::vector<std::size_t> >();
test_copy_n_impl< std::list<std::size_t> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.copy_n" );
test->add( BOOST_TEST_CASE( &test_copy_n ) );
return test;
}

View File

@@ -0,0 +1,188 @@
// 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/algorithm_ext/erase.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator.hpp>
#include <algorithm>
#include <list>
#include <vector>
namespace
{
template< class Container >
void test_erase_impl()
{
Container source;
for (int i = 0; i < 10; ++i)
source.push_back(i);
Container reference(source);
Container test(source);
typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator_t;
iterator_t first_ref = reference.begin();
iterator_t last_ref = reference.end();
boost::iterator_range< iterator_t > test_range(test.begin(), test.end());
reference.erase(first_ref, last_ref);
boost::erase(test, test_range);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
void test_erase()
{
test_erase_impl<std::vector<int> >();
test_erase_impl<std::list<int> >();
}
template< class Container >
void test_remove_erase_impl()
{
Container source;
for (int i = 0; i < 10; ++i)
source.push_back(i);
Container reference(source);
Container test(source);
boost::remove_erase(test, 5);
reference.erase( std::find(reference.begin(), reference.end(), 5) );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
void test_remove_erase()
{
test_remove_erase_impl<std::vector<int> >();
test_remove_erase_impl<std::list<int> >();
}
struct is_even
{
typedef bool result_type;
typedef int argument_type;
bool operator()(int x) const { return x % 2 == 0; }
};
template< class Container >
void test_remove_erase_if_impl()
{
Container source;
for (int i = 0; i < 10; ++i)
source.push_back(i);
Container reference;
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iterator_t;
iterator_t last_source = source.end();
is_even pred;
for (iterator_t it_source = source.begin(); it_source != last_source; ++it_source)
{
if (!pred(*it_source))
reference.push_back(*it_source);
}
Container test(source);
boost::remove_erase_if(test, is_even());
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
void test_remove_erase_if()
{
test_remove_erase_if_impl<std::vector<int> >();
test_remove_erase_if_impl<std::list<int> >();
}
template< class Container >
void test_unique_erase_impl()
{
Container source;
source.push_back(1);
source.push_back(1);
source.push_back(1);
source.push_back(2);
source.push_back(3);
source.push_back(3);
Container reference;
reference.push_back(1);
reference.push_back(2);
reference.push_back(3);
boost::unique_erase(source);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
source.begin(), source.end() );
}
void test_unique_erase()
{
test_unique_erase_impl<std::vector<int> >();
test_unique_erase_impl<std::list<int> >();
}
struct distance_smaller_2
{
typedef bool result_type;
typedef int argument_type;
bool operator()(int x, int y) const { return std::abs(x - y) < 2; }
};
template< class Container >
void test_unique_erase_pred_impl()
{
Container source;
for (int i = 0; i < 10; ++i)
source.push_back(i);
Container reference;
for (int i = 0; i < 10; i += 2)
reference.push_back(i);
boost::unique_erase(source, distance_smaller_2());
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
source.begin(), source.end() );
}
void test_unique_erase_pred()
{
test_unique_erase_pred_impl<std::vector<int> >();
test_unique_erase_pred_impl<std::list<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.erase" );
test->add( BOOST_TEST_CASE( &test_erase ) );
test->add( BOOST_TEST_CASE( &test_remove_erase ) );
test->add( BOOST_TEST_CASE( &test_remove_erase_if ) );
test->add( BOOST_TEST_CASE( &test_unique_erase ) );
test->add( BOOST_TEST_CASE( &test_unique_erase_pred ) );
return test;
}

View File

@@ -0,0 +1,98 @@
// 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/algorithm_ext/for_each.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator.hpp>
#include <algorithm>
#include <list>
#include <vector>
namespace
{
struct MockBinaryFn
{
typedef void result_type;
typedef int first_argument_type;
typedef int second_argument_type;
void operator()(int x, int y)
{
xs.push_back(x);
ys.push_back(y);
}
std::vector<int> xs;
std::vector<int> ys;
};
template< class Range1, class Range2 >
void test_for_each_impl( Range1& rng1, Range2& rng2 )
{
MockBinaryFn fn = boost::range::for_each(rng1, rng2, MockBinaryFn());
BOOST_CHECK_EQUAL_COLLECTIONS( ::boost::begin(rng1), ::boost::end(rng1),
fn.xs.begin(), fn.xs.end() );
BOOST_CHECK_EQUAL_COLLECTIONS( ::boost::begin(rng2), ::boost::end(rng2),
fn.ys.begin(), fn.ys.end() );
}
template< class Collection1, class Collection2 >
void test_for_each_impl(const int max_count)
{
Collection1 c1;
for (int i = 0; i < max_count; ++i)
c1.push_back(i);
Collection2 c2;
for (int i = 0; i < max_count; ++i)
c2.push_back(i);
test_for_each_impl(c1, c2);
const Collection1& const_c1 = c1;
const Collection2& const_c2 = c2;
test_for_each_impl(c1, const_c2);
test_for_each_impl(const_c1, c2);
test_for_each_impl(const_c1, const_c2);
}
template< class Collection1, class Collection2 >
void test_for_each_impl()
{
test_for_each_impl< Collection1, Collection2 >(0);
test_for_each_impl< Collection1, Collection2 >(1);
test_for_each_impl< Collection1, Collection2 >(10);
}
void test_for_each()
{
test_for_each_impl< std::vector<int>, std::vector<int> >();
test_for_each_impl< std::list<int>, std::list<int> >();
test_for_each_impl< std::vector<int>, std::list<int> >();
test_for_each_impl< std::list<int>, std::vector<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.for_each" );
test->add( BOOST_TEST_CASE( &test_for_each ) );
return test;
}

View File

@@ -0,0 +1,72 @@
// 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/algorithm_ext/insert.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/irange.hpp>
#include <algorithm>
#include <list>
#include <vector>
namespace
{
template< class Container >
void test_insert_impl( int n )
{
Container test;
boost::insert( test, test.end(), boost::irange(0, n) );
Container reference;
for (int i = 0; i < n; ++i)
reference.push_back(i);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
// Do it again so that we are inserting into a non-empty target
boost::insert( test, test.end(), boost::irange(0, n) );
for (int j = 0; j < n; ++j)
reference.push_back(j);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
template< class Container >
void test_insert_impl()
{
test_insert_impl< Container >(0);
test_insert_impl< Container >(1);
test_insert_impl< Container >(2);
test_insert_impl< Container >(100);
}
void test_insert()
{
test_insert_impl< std::vector<std::size_t> >();
test_insert_impl< std::list<std::size_t> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.insert" );
test->add( BOOST_TEST_CASE( &test_insert ) );
return test;
}

View File

@@ -0,0 +1,70 @@
// 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/algorithm_ext/iota.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator.hpp>
#include <algorithm>
#include <list>
#include <vector>
namespace
{
template< class Container >
void test_iota_impl(std::size_t n)
{
Container test;
test.resize( n );
boost::iota( test, n );
Container reference;
reference.resize( n );
std::size_t i = n;
typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator_t;
iterator_t last = reference.end();
for (iterator_t it = reference.begin(); it != last; ++it, ++i)
{
*it = i;
}
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
template< class Container >
void test_iota_impl()
{
test_iota_impl< Container >(0);
test_iota_impl< Container >(1);
test_iota_impl< Container >(2);
test_iota_impl< Container >(100);
}
void test_iota()
{
test_iota_impl< std::vector<std::size_t> >();
test_iota_impl< std::list<std::size_t> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.iota" );
test->add( BOOST_TEST_CASE( &test_iota ) );
return test;
}

View File

@@ -0,0 +1,62 @@
// 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/algorithm_ext/is_sorted.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator.hpp>
#include <algorithm>
#include <list>
#include <vector>
namespace
{
template< class Container >
void test_is_sorted_impl()
{
Container ascending;
Container descending;
// Empty ranges are regarded as sorted against any predicate.
BOOST_CHECK( boost::is_sorted(ascending) );
BOOST_CHECK( boost::is_sorted(ascending, std::less<std::size_t>()) );
BOOST_CHECK( boost::is_sorted(ascending, std::greater<std::size_t>()) );
for (std::size_t i = 0; i < 10; ++i)
{
ascending.push_back(i);
descending.push_back(9 - i);
}
BOOST_CHECK( boost::is_sorted(ascending) );
BOOST_CHECK( !boost::is_sorted(descending) );
BOOST_CHECK( !boost::is_sorted(ascending, std::greater<std::size_t>()) );
BOOST_CHECK( boost::is_sorted(descending, std::greater<std::size_t>()) );
}
void test_is_sorted()
{
test_is_sorted_impl< std::vector<std::size_t> >();
test_is_sorted_impl< std::list<std::size_t> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.is_sorted" );
test->add( BOOST_TEST_CASE( &test_is_sorted ) );
return test;
}

View File

@@ -0,0 +1,74 @@
// 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/algorithm_ext/overwrite.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator.hpp>
#include <algorithm>
#include <list>
#include <vector>
namespace
{
template< class Container >
void test_overwrite_impl(std::size_t n)
{
Container overwrite_source;
for (std::size_t i = 0; i < n; ++i)
overwrite_source.push_back(i);
Container reference;
reference.resize(n);
std::copy(overwrite_source.begin(), overwrite_source.end(), reference.begin());
Container test;
test.resize(n);
boost::overwrite(overwrite_source, test);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
test.clear();
test.resize(n);
const Container& const_overwrite_source = overwrite_source;
boost::overwrite(const_overwrite_source, test);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
template< class Container >
void test_overwrite_impl()
{
test_overwrite_impl<Container>(0);
test_overwrite_impl<Container>(1);
test_overwrite_impl<Container>(10);
}
void test_overwrite()
{
test_overwrite_impl< std::vector<std::size_t> >();
test_overwrite_impl< std::list<std::size_t> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.overwrite" );
test->add( BOOST_TEST_CASE( &test_overwrite ) );
return test;
}

View File

@@ -0,0 +1,72 @@
// 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/algorithm_ext/push_back.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/irange.hpp>
#include <algorithm>
#include <list>
#include <vector>
namespace
{
template< class Container >
void test_push_back_impl(std::size_t n)
{
Container reference;
for (std::size_t i = 0; i < n; ++i)
reference.push_back(i);
Container test;
boost::push_back(test, boost::irange<std::size_t>(0, n));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
// Do it again to push onto non-empty container
for (std::size_t j = 0; j < n; ++j)
reference.push_back(j);
boost::push_back(test, boost::irange<std::size_t>(0, n));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
template< class Container >
void test_push_back_impl()
{
test_push_back_impl< Container >(0);
test_push_back_impl< Container >(1);
test_push_back_impl< Container >(2);
test_push_back_impl< Container >(100);
}
void test_push_back()
{
test_push_back_impl< std::vector<std::size_t> >();
test_push_back_impl< std::list<std::size_t> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.push_back" );
test->add( BOOST_TEST_CASE( &test_push_back ) );
return test;
}

View File

@@ -0,0 +1,84 @@
// 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/algorithm_ext/push_front.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/irange.hpp>
#include <algorithm>
#include <list>
#include <vector>
namespace
{
struct DoubleValue
{
template< class Value >
Value operator()(Value x)
{
return x * 2;
}
};
template< class Container >
void test_push_front_impl(std::size_t n)
{
Container reference;
for (std::size_t i = 0; i < n; ++i)
reference.push_back(i);
Container test;
boost::push_front(test, boost::irange<std::size_t>(0, n));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
// copy the original reference sequence
Container reference_copy(reference);
std::transform(reference.begin(), reference.end(), reference.begin(), DoubleValue());
// Do it again to push onto non-empty container
reference.insert(reference.end(), reference_copy.begin(), reference_copy.end());
boost::push_front(test, boost::irange<std::size_t>(0, n * 2, 2));
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
}
template< class Container >
void test_push_front_impl()
{
test_push_front_impl< Container >(0);
test_push_front_impl< Container >(1);
test_push_front_impl< Container >(2);
test_push_front_impl< Container >(100);
}
void test_push_front()
{
test_push_front_impl< std::vector<std::size_t> >();
test_push_front_impl< std::list<std::size_t> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm_ext.push_front" );
test->add( BOOST_TEST_CASE( &test_push_front ) );
return test;
}

View File

@@ -0,0 +1,95 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/adjacent_find.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void test_adjacent_find_impl()
{
using namespace boost::assign;
typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator_t;
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator const_iterator_t;
Container cont;
const Container& cref_cont = cont;
std::equal_to<int> pred;
BOOST_CHECK( boost::adjacent_find(cont) == cont.end() );
BOOST_CHECK( boost::adjacent_find(cref_cont) == cref_cont.end() );
BOOST_CHECK( boost::adjacent_find(boost::make_iterator_range(cont)) == cont.end() );
BOOST_CHECK( boost::adjacent_find(cont, pred) == cont.end() );
BOOST_CHECK( boost::adjacent_find(cref_cont, pred) == cref_cont.end() );
BOOST_CHECK( boost::adjacent_find(boost::make_iterator_range(cont), pred) == cont.end() );
cont += 1;
BOOST_CHECK( boost::adjacent_find(cont) == cont.end() );
BOOST_CHECK( boost::adjacent_find(cref_cont) == cref_cont.end() );
BOOST_CHECK( boost::adjacent_find(boost::make_iterator_range(cont)) == cont.end() );
BOOST_CHECK( boost::adjacent_find(cont, pred) == cont.end() );
BOOST_CHECK( boost::adjacent_find(cref_cont, pred) == cref_cont.end() );
BOOST_CHECK( boost::adjacent_find(boost::make_iterator_range(cont), pred) == cont.end() );
cont += 2,3,4,5,5,5,6,7,8,9;
iterator_t it = boost::adjacent_find(cont);
iterator_t it_pred = boost::adjacent_find(cont, pred);
BOOST_CHECK( it == it_pred );
BOOST_CHECK( it != cont.end() );
BOOST_CHECK( it == std::adjacent_find(cont.begin(), cont.end()) );
if (it != cont.end())
{
BOOST_CHECK( *it == 5 );
}
BOOST_CHECK( it == boost::adjacent_find(boost::make_iterator_range(cont)) );
BOOST_CHECK( it_pred == boost::adjacent_find(boost::make_iterator_range(cont), pred) );
const_iterator_t cit = boost::adjacent_find(cref_cont);
const_iterator_t cit_pred = boost::adjacent_find(cref_cont, pred);
BOOST_CHECK( cit == cit_pred );
BOOST_CHECK( cit != cref_cont.end() );
BOOST_CHECK( cit == std::adjacent_find(cref_cont.begin(), cref_cont.end()) );
if (cit != cref_cont.end())
{
BOOST_CHECK( *cit == 5 );
}
}
void test_adjacent_find()
{
test_adjacent_find_impl< std::vector<int> >();
test_adjacent_find_impl< std::list<int> >();
test_adjacent_find_impl< std::multiset<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.adjacent_find" );
test->add( BOOST_TEST_CASE( &boost::test_adjacent_find ) );
return test;
}

View File

@@ -0,0 +1,125 @@
// Copyright Neil Groves 2009. 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/algorithm/binary_search.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template<class Container>
void test(Container& cont)
{
Container reference(cont);
Container test(cont);
bool reference_result
= std::binary_search(reference.begin(), reference.end(), 5);
bool test_result = boost::binary_search(test, 5);
BOOST_CHECK( reference_result == test_result );
BOOST_CHECK( test_result == boost::binary_search(boost::make_iterator_range(test), 5) );
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
}
template<class Container, class BinaryPredicate>
void sort_container(Container& cont, BinaryPredicate pred)
{
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
std::vector<value_t> temp(cont.begin(), cont.end());
std::sort(temp.begin(), temp.end(), pred);
cont.assign(temp.begin(), temp.end());
}
template<class Container, class BinaryPredicate>
void test_pred(Container& cont, BinaryPredicate pred)
{
Container reference(cont);
Container test(cont);
sort_container(reference, pred);
sort_container(test, pred);
bool reference_result
= std::binary_search(reference.begin(), reference.end(), 5,
pred);
bool test_result = boost::binary_search(test, 5, pred);
BOOST_CHECK( test_result == boost::binary_search(boost::make_iterator_range(test), 5, pred) );
BOOST_CHECK( reference_result == test_result );
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
}
template<class Container>
void test_binary_search_impl()
{
using namespace boost::assign;
Container cont;
test(cont);
test_pred(cont, std::less<int>());
test_pred(cont, std::greater<int>());
cont.clear();
cont += 1;
test(cont);
test_pred(cont, std::less<int>());
test_pred(cont, std::greater<int>());
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test(cont);
test_pred(cont, std::less<int>());
test_pred(cont, std::greater<int>());
}
void test_binary_search()
{
test_binary_search_impl< std::vector<int> >();
test_binary_search_impl< std::list<int> >();
test_binary_search_impl< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.binary_search" );
test->add( BOOST_TEST_CASE( &boost::test_binary_search ) );
return test;
}

View File

@@ -0,0 +1,74 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/copy.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/iterator.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void test_copy_impl()
{
Container source;
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
std::vector<value_t> target;
target.resize(source.size());
typedef BOOST_DEDUCED_TYPENAME range_iterator< std::vector<value_t> >::type iterator_t;
iterator_t it = boost::copy(source, target.begin());
BOOST_CHECK( it == target.end() );
BOOST_CHECK_EQUAL_COLLECTIONS(
target.begin(), target.end(),
source.begin(), source.end()
);
it = boost::copy(boost::make_iterator_range(source), target.begin());
BOOST_CHECK( it == target.end() );
BOOST_CHECK_EQUAL_COLLECTIONS(target.begin(), target.end(),
source.begin(), source.end());
}
void test_copy()
{
test_copy_impl< std::vector<int> >();
test_copy_impl< std::list<int> >();
test_copy_impl< std::set<int> >();
test_copy_impl< std::multiset<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.copy" );
test->add( BOOST_TEST_CASE( &boost::test_copy ) );
return test;
}

View File

@@ -0,0 +1,84 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/
//
// Credits:
// awulkiew highlighted that this test was not successfully testing the
// algorithm.
//
#include <boost/range/algorithm/copy_backward.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/iterator.hpp>
#include <algorithm>
#include <list>
#include <vector>
namespace boost_range_test
{
namespace
{
template<typename Container>
void test_copy_backward_impl(std::size_t n)
{
Container source;
typedef typename Container::value_type value_t;
for (std::size_t i = 0; i < n; ++i)
source.push_back(static_cast<value_t>(i));
std::vector<value_t> target(n);
typedef typename boost::range_iterator<
std::vector<value_t>
>::type iterator_t;
iterator_t it = boost::copy_backward(source, target.end());
BOOST_CHECK(it == target.begin());
BOOST_CHECK_EQUAL_COLLECTIONS(target.begin(), target.end(),
source.begin(), source.end());
BOOST_CHECK(it == boost::copy_backward(
boost::make_iterator_range(source), target.end()));
BOOST_CHECK_EQUAL_COLLECTIONS(target.begin(), target.end(),
source.begin(), source.end());
}
template<typename Container>
void test_copy_backward_impl()
{
test_copy_backward_impl<Container>(0u);
test_copy_backward_impl<Container>(1u);
test_copy_backward_impl<Container>(100u);
}
void test_copy_backward()
{
test_copy_backward_impl<std::vector<int> >();
test_copy_backward_impl<std::list<int> >();
}
} // 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("RangeTestSuite.algorithm.copy_backward");
test->add(BOOST_TEST_CASE(&boost_range_test::test_copy_backward));
return test;
}

View File

@@ -0,0 +1,70 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/copy_n.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/iterator.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace
{
template< class Container >
void test_copy_n_impl()
{
Container source;
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
std::vector<value_t> target;
target.resize(source.size());
typedef BOOST_DEDUCED_TYPENAME range_iterator< std::vector<value_t> >::type iterator_t;
iterator_t it = boost::copy(source, target.begin());
BOOST_CHECK( it == target.end() );
BOOST_CHECK_EQUAL_COLLECTIONS(
target.begin(), target.end(),
source.begin(), source.end()
);
it = boost::copy(boost::make_iterator_range(source), target.begin());
BOOST_CHECK( it == target.end() );
BOOST_CHECK_EQUAL_COLLECTIONS(target.begin(), target.end(),
source.begin(), source.end());
}
void test_copy_n()
{
test_copy_n_impl< std::vector<int> >();
test_copy_n_impl< std::list<int> >();
test_copy_n_impl< std::set<int> >();
test_copy_n_impl< std::multiset<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.copy_n" );
test->add( BOOST_TEST_CASE( &::test_copy_n ) );
return test;
}

View File

@@ -0,0 +1,85 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/count.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void test_count_impl()
{
using namespace boost::assign;
Container cont;
const Container& cref_cont = cont;
BOOST_CHECK_EQUAL( 0u, boost::count(cont, 0u) );
BOOST_CHECK_EQUAL( 0u, boost::count(cref_cont, 0u) );
BOOST_CHECK_EQUAL( 0u, boost::count(boost::make_iterator_range(cont), 0u) );
cont += 1;
BOOST_CHECK_EQUAL( 0u, boost::count(cont, 0u) );
BOOST_CHECK_EQUAL( 0u, boost::count(cref_cont, 0u) );
BOOST_CHECK_EQUAL( 0u, boost::count(boost::make_iterator_range(cont), 0u) );
BOOST_CHECK_EQUAL( 1u, boost::count(cont, 1u) );
BOOST_CHECK_EQUAL( 1u, boost::count(cref_cont, 1u) );
BOOST_CHECK_EQUAL( 1u, boost::count(boost::make_iterator_range(cont), 1u) );
cont += 2,3,4,5,6,7,8,9;
BOOST_CHECK_EQUAL( 0u, boost::count(cont, 0u) );
BOOST_CHECK_EQUAL( 0u, boost::count(cref_cont, 0u) );
BOOST_CHECK_EQUAL( 0u, boost::count(boost::make_iterator_range(cont), 0u) );
BOOST_CHECK_EQUAL( 1u, boost::count(cont, 1u) );
BOOST_CHECK_EQUAL( 1u, boost::count(cref_cont, 1u) );
BOOST_CHECK_EQUAL( 1u, boost::count(boost::make_iterator_range(cont), 1u) );
cont += 2;
BOOST_CHECK_EQUAL( 0u, boost::count(cont, 0u) );
BOOST_CHECK_EQUAL( 0u, boost::count(cref_cont, 0u) );
BOOST_CHECK_EQUAL( 0u, boost::count(boost::make_iterator_range(cont), 0u) );
BOOST_CHECK_EQUAL( 1u, boost::count(cont, 1u) );
BOOST_CHECK_EQUAL( 1u, boost::count(cref_cont, 1u) );
BOOST_CHECK_EQUAL( 1u, boost::count(boost::make_iterator_range(cont), 1u) );
BOOST_CHECK_EQUAL( 2u, boost::count(cont, 2u) );
BOOST_CHECK_EQUAL( 2u, boost::count(cref_cont, 2u) );
BOOST_CHECK_EQUAL( 2u, boost::count(boost::make_iterator_range(cont), 2u) );
}
void test_count()
{
test_count_impl< std::vector<int> >();
test_count_impl< std::list<int> >();
test_count_impl< std::multiset<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.count" );
test->add( BOOST_TEST_CASE( &boost::test_count ) );
return test;
}

View File

@@ -0,0 +1,100 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/count_if.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include "../test_function/false_predicate.hpp"
#include "../test_function/true_predicate.hpp"
#include "../test_function/equal_to_x.hpp"
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void test_count_if_impl()
{
using namespace boost::range_test_function;
using namespace boost::assign;
typedef equal_to_x<int> pred_t;
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BOOST_DEDUCED_TYPENAME Container::iterator>::difference_type diff_t;
Container cont;
const Container& cref_cont = cont;
BOOST_CHECK_EQUAL( 0u, boost::count_if(cont, pred_t(0)) );
BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, pred_t(0)) );
BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), pred_t(0)) );
cont += 1;
BOOST_CHECK_EQUAL( 0u, boost::count_if(cont, pred_t(0)) );
BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, pred_t(0)) );
BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), pred_t(0)) );
BOOST_CHECK_EQUAL( 1u, boost::count_if(cont, pred_t(1)) );
BOOST_CHECK_EQUAL( 1u, boost::count_if(cref_cont, pred_t(1)) );
BOOST_CHECK_EQUAL( 1u, boost::count_if(boost::make_iterator_range(cont), pred_t(1)) );
cont += 2,3,4,5,6,7,8,9;
BOOST_CHECK_EQUAL( 0u, boost::count_if(cont, pred_t(0)) );
BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, pred_t(0)) );
BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), pred_t(0)) );
BOOST_CHECK_EQUAL( 1u, boost::count_if(cont, pred_t(1)) );
BOOST_CHECK_EQUAL( 1u, boost::count_if(cref_cont, pred_t(1)) );
BOOST_CHECK_EQUAL( 1u, boost::count_if(boost::make_iterator_range(cont), pred_t(1)) );
cont += 2;
BOOST_CHECK_EQUAL( 0u, boost::count_if(cont, pred_t(0)) );
BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, pred_t(0)) );
BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), pred_t(0)) );
BOOST_CHECK_EQUAL( 1u, boost::count_if(cont, pred_t(1)) );
BOOST_CHECK_EQUAL( 1u, boost::count_if(cref_cont, pred_t(1)) );
BOOST_CHECK_EQUAL( 1u, boost::count_if(boost::make_iterator_range(cont), pred_t(1)) );
BOOST_CHECK_EQUAL( 2u, boost::count_if(cont, pred_t(2)) );
BOOST_CHECK_EQUAL( 2u, boost::count_if(cref_cont, pred_t(2)) );
BOOST_CHECK_EQUAL( 2u, boost::count_if(boost::make_iterator_range(cont), pred_t(2)) );
BOOST_CHECK_EQUAL( 0u, boost::count_if(cont, false_predicate()) );
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( static_cast<diff_t>(cont.size()), boost::count_if(cont, true_predicate()) );
BOOST_CHECK_EQUAL( static_cast<diff_t>(cont.size()), boost::count_if(cref_cont, true_predicate()) );
BOOST_CHECK_EQUAL( static_cast<diff_t>(cont.size()), boost::count_if(boost::make_iterator_range(cont), true_predicate()) );
}
void test_count_if()
{
test_count_if_impl< std::vector<int> >();
test_count_if_impl< std::list<int> >();
test_count_if_impl< std::multiset<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.count_if" );
test->add( BOOST_TEST_CASE( &boost::test_count_if ) );
return test;
}

View File

@@ -0,0 +1,143 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/equal.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
template< class Container1, class Container2 >
void test_equal_impl()
{
using namespace boost::assign;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type container1_t;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type container2_t;
container1_t mcont1;
container2_t mcont2;
Container1& cont1 = mcont1;
Container2& cont2 = mcont2;
BOOST_CHECK( boost::equal(cont1, cont2) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2) );
BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2)) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
BOOST_CHECK( boost::equal(cont1, cont2, std::equal_to<int>()) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2, std::equal_to<int>()) );
BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2), std::equal_to<int>()) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::equal_to<int>()) );
BOOST_CHECK( boost::equal(cont1, cont2, std::not_equal_to<int>()) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2, std::not_equal_to<int>()) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
mcont1 += 1;
BOOST_CHECK( !boost::equal(cont1, cont2) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2) );
BOOST_CHECK( !boost::equal(cont1, boost::make_iterator_range(cont2)) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
BOOST_CHECK( !boost::equal(cont1, cont2, std::equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::equal_to<int>()) );
BOOST_CHECK( !boost::equal(cont1, boost::make_iterator_range(cont2), std::equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::equal_to<int>()) );
BOOST_CHECK( !boost::equal(cont1, cont2, std::not_equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::not_equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
mcont1.clear();
mcont2 += 1;
BOOST_CHECK( !boost::equal(cont1, cont2) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
BOOST_CHECK( !boost::equal(cont1, cont2, std::equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::equal_to<int>()) );
BOOST_CHECK( !boost::equal(cont1, cont2, std::not_equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::not_equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
mcont1 += 1;
BOOST_CHECK( boost::equal(cont1, cont2) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2) );
BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2)) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
BOOST_CHECK( boost::equal(cont1, cont2, std::equal_to<int>()) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2, std::equal_to<int>()) );
BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2), std::equal_to<int>()) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::equal_to<int>()) );
BOOST_CHECK( !boost::equal(cont1, cont2, std::not_equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::not_equal_to<int>()) );
BOOST_CHECK( !boost::equal(cont1, boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
mcont1 += 2,3,4,5,6,7,8,9;
mcont2 += 2,3,4,5,6,7,8,9;
BOOST_CHECK( boost::equal(cont1, cont2) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2) );
BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2)) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
BOOST_CHECK( boost::equal(cont1, cont2, std::equal_to<int>()) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), cont2, std::equal_to<int>()) );
BOOST_CHECK( boost::equal(cont1, boost::make_iterator_range(cont2), std::equal_to<int>()) );
BOOST_CHECK( boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::equal_to<int>()) );
BOOST_CHECK( !boost::equal(cont1, cont2, std::not_equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), cont2, std::not_equal_to<int>()) );
BOOST_CHECK( !boost::equal(cont1, boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
BOOST_CHECK( !boost::equal(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), std::not_equal_to<int>()) );
}
template< class Container1, class Container2 >
void test_driver()
{
typedef Container1 container1_t;
typedef Container2 container2_t;
typedef BOOST_DEDUCED_TYPENAME boost::add_const<Container1>::type const_container1_t;
typedef BOOST_DEDUCED_TYPENAME boost::add_const<Container2>::type const_container2_t;
test_equal_impl< const_container1_t, const_container2_t >();
test_equal_impl< const_container1_t, container2_t >();
test_equal_impl< container1_t, const_container2_t >();
test_equal_impl< container1_t, container2_t >();
}
void test_equal()
{
test_driver< std::list<int>, std::list<int> >();
test_driver< std::vector<int>, std::vector<int> >();
test_driver< std::set<int>, std::set<int> >();
test_driver< std::multiset<int>, std::multiset<int> >();
test_driver< std::list<int>, std::vector<int> >();
test_driver< std::vector<int>, std::list<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.equal" );
test->add( BOOST_TEST_CASE( &boost::test_equal ) );
return test;
}

View File

@@ -0,0 +1,180 @@
// Copyright Neil Groves 2009. 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/algorithm/equal_range.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template<class Container, class Pair>
void check_result(
const Container& reference,
Pair reference_pair,
const Container& test,
Pair test_pair
)
{
typedef BOOST_DEDUCED_TYPENAME range_iterator<const Container>::type
const_iterator_t;
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
BOOST_CHECK_EQUAL(
std::distance<const_iterator_t>(reference.begin(), reference_pair.first),
std::distance<const_iterator_t>(test.begin(), test_pair.first)
);
BOOST_CHECK_EQUAL(
std::distance<const_iterator_t>(reference.begin(), reference_pair.second),
std::distance<const_iterator_t>(test.begin(), test_pair.second)
);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_pair.first, reference_pair.second,
test_pair.first, test_pair.second
);
}
template<class Container>
void test(Container& cont)
{
Container reference(cont);
Container test(cont);
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
typedef std::pair<iterator_t, iterator_t> pair_t;
pair_t reference_result
= std::equal_range(reference.begin(), reference.end(), 5);
pair_t test_result = boost::equal_range(test, 5);
check_result(reference, reference_result, test, test_result);
pair_t test_result2 = boost::equal_range(boost::make_iterator_range(test), 5);
check_result(reference, reference_result, test, test_result2);
}
template<class Container, class BinaryPredicate>
void sort_container(Container& cont, BinaryPredicate pred)
{
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
std::vector<value_t> temp(cont.begin(), cont.end());
std::sort(temp.begin(), temp.end(), pred);
cont.assign(temp.begin(), temp.end());
}
template<class Container, class BinaryPredicate>
void test_pred(Container& cont, BinaryPredicate pred)
{
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type container_t;
container_t reference_temp(cont);
container_t test_temp(cont);
sort_container(reference_temp, pred);
sort_container(test_temp, pred);
Container reference(reference_temp);
Container test(test_temp);
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
typedef std::pair<iterator_t, iterator_t> pair_t;
pair_t reference_result
= std::equal_range(reference.begin(), reference.end(), 5,
BinaryPredicate());
pair_t test_result = boost::equal_range(test, 5, BinaryPredicate());
check_result(reference, reference_result, test, test_result);
pair_t test_result2 = boost::equal_range(boost::make_iterator_range(test), 5, BinaryPredicate());
check_result(reference, reference_result, test, test_result2);
}
template<class Container>
void test_driver(const Container& cont)
{
Container mutable_cont(cont);
test(mutable_cont);
test(cont);
}
template<class Container, class BinaryPredicate>
void test_pred_driver(const Container& cont, BinaryPredicate pred)
{
Container mutable_cont(cont);
test_pred(mutable_cont, pred);
test_pred(cont, pred);
}
template<class Container>
void test_equal_range_impl()
{
using namespace boost::assign;
Container cont;
test_driver(cont);
test_pred_driver(cont, std::less<int>());
test_pred_driver(cont, std::greater<int>());
cont.clear();
cont += 1;
test_driver(cont);
test_pred_driver(cont, std::less<int>());
test_pred_driver(cont, std::greater<int>());
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test_driver(cont);
test_pred_driver(cont, std::less<int>());
test_pred_driver(cont, std::greater<int>());
}
void test_equal_range()
{
test_equal_range_impl< std::vector<int> >();
test_equal_range_impl< std::list<int> >();
test_equal_range_impl< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.equal_range" );
test->add( BOOST_TEST_CASE( &boost::test_equal_range ) );
return test;
}

View File

@@ -0,0 +1,86 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/fill.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template< class Container >
void test_fill_impl(Container& cont)
{
Container reference(cont);
std::fill(reference.begin(), reference.end(), 1);
Container target(cont);
boost::fill(target, 1);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
target.begin(), target.end() );
Container target2(cont);
boost::fill(boost::make_iterator_range(target2), 1);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
target2.begin(), target2.end() );
}
template< class Container >
void test_fill_impl()
{
using namespace boost::assign;
Container cont;
test_fill_impl(cont);
cont.clear();
cont += 2;
test_fill_impl(cont);
cont.clear();
cont += 1,2;
test_fill_impl(cont);
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test_fill_impl(cont);
}
void test_fill()
{
test_fill_impl< std::vector<int> >();
test_fill_impl< std::list<int> >();
test_fill_impl< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.fill" );
test->add( BOOST_TEST_CASE( &boost::test_fill ) );
return test;
}

View File

@@ -0,0 +1,131 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/find.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include "../test_driver/range_return_test_driver.hpp"
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost_range_test_algorithm_find
{
class find_test_policy
{
public:
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::find(cont, 3);
iter_t result2 = boost::find(boost::make_iterator_range(cont), 3);
BOOST_CHECK( result == result2 );
return result;
}
template<boost::range_return_value return_type>
struct test_range
{
template<class Container, class Policy>
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy&, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::find<return_type>(cont, 3);
result_t result2 = boost::find<return_type>(boost::make_iterator_range(cont), 3);
BOOST_CHECK( result == result2 );
return result;
}
};
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::find(cont.begin(), cont.end(), 3);
}
};
template<class Container>
void test_find_container()
{
using namespace boost::assign;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type container_t;
boost::range_test::range_return_test_driver test_driver;
container_t mcont;
Container& cont = mcont;
test_driver(cont, find_test_policy());
mcont.clear();
mcont += 1;
test_driver(cont, find_test_policy());
mcont.clear();
mcont += 1,2,3,4,5,6,7,8,9;
test_driver(cont, find_test_policy());
}
void test_find()
{
test_find_container< std::vector<int> >();
test_find_container< std::list<int> >();
test_find_container< std::deque<int> >();
test_find_container< const std::vector<int> >();
test_find_container< const std::list<int> >();
test_find_container< const std::deque<int> >();
std::vector<int> vi;
const std::vector<int>& cvi = vi;
std::vector<int>::const_iterator it = boost::find(vi, 0);
std::vector<int>::const_iterator it2 = boost::find(cvi, 0);
BOOST_CHECK( it == it2 );
}
// The find algorithm can be used like a "contains" algorithm
// since the returned iterator_range is convertible to bool.
// Therefore if the return value is an empty range it will
// convert to the equivalent to "false" whereas a range that
// is not empty will convert to "true". Therefore one can
// use the syntax boost::find<boost::return_found_end>(rng, x)
// as a contains function.
void test_find_as_contains()
{
std::list<int> l;
for (int i = 0; i < 10; ++i)
l.push_back(i);
BOOST_CHECK(boost::find<boost::return_found_end>(l, 3));
BOOST_CHECK(!boost::find<boost::return_found_end>(l, 10));
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find" );
test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find::test_find ) );
test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find::test_find_as_contains ) );
return test;
}

View File

@@ -0,0 +1,200 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/find_end.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include "../test_driver/range_return_test_driver.hpp"
#include <algorithm>
#include <functional>
#include <vector>
#include <set>
#include <list>
namespace boost_range_test_algorithm_find_end
{
template<class Container2>
class find_end_test_policy
{
typedef Container2 container2_t;
public:
explicit find_end_test_policy(const Container2& cont)
: m_cont(cont)
{
}
container2_t cont() { return m_cont; }
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::find_end(cont, m_cont);
BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), m_cont) );
BOOST_CHECK( result == boost::find_end(cont, boost::make_iterator_range(m_cont)) );
BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont)) );
return result;
}
template<boost::range_return_value return_type>
struct test_range
{
template<class Container, class Policy>
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy& policy, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::find_end<return_type>(cont, policy.cont());
BOOST_CHECK( result == boost::find_end<return_type>(boost::make_iterator_range(cont), policy.cont()) );
BOOST_CHECK( result == boost::find_end<return_type>(cont, boost::make_iterator_range(policy.cont())) );
BOOST_CHECK( result == boost::find_end<return_type>(boost::make_iterator_range(cont),
boost::make_iterator_range(policy.cont())) );
return result;
}
};
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::find_end(cont.begin(), cont.end(),
m_cont.begin(), m_cont.end());
}
private:
Container2 m_cont;
};
template<class Container2, class BinaryPredicate>
class find_end_pred_test_policy
{
typedef Container2 container2_t;
public:
explicit find_end_pred_test_policy(const Container2& cont)
: m_cont(cont)
{
}
container2_t& cont() { return m_cont; }
BinaryPredicate& pred() { return m_pred; }
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t it = boost::find_end(cont, m_cont, m_pred);
BOOST_CHECK( it == boost::find_end(boost::make_iterator_range(cont), m_cont, m_pred) );
BOOST_CHECK( it == boost::find_end(cont, boost::make_iterator_range(m_cont), m_pred) );
BOOST_CHECK( it == boost::find_end(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont), m_pred) );
return it;
}
template<boost::range_return_value return_type>
struct test_range
{
template<class Container, class Policy>
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy& policy, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::find_end<return_type>(cont, policy.cont(), policy.pred());
BOOST_CHECK( result == boost::find_end<return_type>(boost::make_iterator_range(cont), policy.cont(), policy.pred()) );
BOOST_CHECK( result == boost::find_end<return_type>(cont, boost::make_iterator_range(policy.cont()), policy.pred()) );
BOOST_CHECK( result == boost::find_end<return_type>(boost::make_iterator_range(cont),
boost::make_iterator_range(policy.cont()), policy.pred()) );
return boost::find_end<return_type>(cont, policy.cont(), policy.pred());
}
};
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::find_end(cont.begin(), cont.end(),
m_cont.begin(), m_cont.end(),
m_pred);
}
private:
Container2 m_cont;
BinaryPredicate m_pred;
};
template<class Container1, class Container2>
void run_tests(Container1& cont1, Container2& cont2)
{
boost::range_test::range_return_test_driver test_driver;
test_driver(cont1, find_end_test_policy<Container2>(cont2));
test_driver(cont1, find_end_pred_test_policy<Container2, std::less<int> >(cont2));
test_driver(cont2, find_end_pred_test_policy<Container2, std::greater<int> >(cont2));
}
template<class Container1, class Container2>
void test_find_end_impl()
{
using namespace boost::assign;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type container1_t;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type container2_t;
container1_t mcont1;
Container1& cont1 = mcont1;
container2_t mcont2;
Container2& cont2 = mcont2;
run_tests(cont1, cont2);
mcont1 += 1;
run_tests(cont1, cont2);
mcont2 += 1;
run_tests(cont1, cont2);
mcont1 += 2,3,4,5,6,7,8,9;
mcont2 += 2,3,4;
run_tests(cont1, cont2);
mcont2.clear();
mcont2 += 7,8,9;
run_tests(cont1, cont2);
}
void test_find_end()
{
test_find_end_impl< std::vector<int>, std::vector<int> >();
test_find_end_impl< std::list<int>, std::list<int> >();
test_find_end_impl< std::deque<int>, std::deque<int> >();
test_find_end_impl< const std::vector<int>, const std::vector<int> >();
test_find_end_impl< const std::list<int>, const std::list<int> >();
test_find_end_impl< const std::deque<int>, const std::deque<int> >();
test_find_end_impl< const std::vector<int>, const std::list<int> >();
test_find_end_impl< const std::list<int>, const std::vector<int> >();
test_find_end_impl< const std::vector<int>, std::list<int> >();
test_find_end_impl< const std::list<int>, std::vector<int> >();
test_find_end_impl< std::vector<int>, std::list<int> >();
test_find_end_impl< std::list<int>, std::vector<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find_end" );
test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find_end::test_find_end ) );
return test;
}

View File

@@ -0,0 +1,198 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/find_first_of.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include "../test_driver/range_return_test_driver.hpp"
#include <algorithm>
#include <functional>
#include <vector>
#include <set>
#include <list>
namespace boost_range_test_algorithm_find_first_of
{
template<class Container2>
class find_first_of_test_policy
{
typedef Container2 container2_t;
public:
explicit find_first_of_test_policy(const Container2& cont)
: m_cont(cont)
{
}
container2_t& cont() { return m_cont; }
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::find_first_of(cont, m_cont);
BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), m_cont) );
BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(m_cont)) );
BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont)) );
return result;
}
template<boost::range_return_value return_type>
struct test_range
{
template<class Container, class Policy>
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy& policy, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::find_first_of<return_type>(cont, policy.cont());
BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), policy.cont()) );
BOOST_CHECK( result == boost::find_first_of<return_type>(cont, boost::make_iterator_range(policy.cont())) );
BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), boost::make_iterator_range(policy.cont())) );
return result;
}
};
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::find_first_of(cont.begin(), cont.end(),
m_cont.begin(), m_cont.end());
}
private:
Container2 m_cont;
};
template<class Container2, class BinaryPredicate>
class find_first_of_pred_test_policy
{
typedef Container2 container2_t;
public:
explicit find_first_of_pred_test_policy(const Container2& cont)
: m_cont(cont)
{
}
container2_t& cont() { return m_cont; }
BinaryPredicate& pred() { return m_pred; }
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::find_first_of(cont, m_cont, m_pred);
BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), m_cont, m_pred) );
BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(m_cont), m_pred) );
BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont), m_pred) );
return result;
}
template<boost::range_return_value return_type>
struct test_range
{
template<class Container, class Policy>
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy& policy, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::find_first_of<return_type>(cont, policy.cont(), policy.pred());
BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), policy.cont(), policy.pred()) );
BOOST_CHECK( result == boost::find_first_of<return_type>(cont, boost::make_iterator_range(policy.cont()), policy.pred()) );
BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), boost::make_iterator_range(policy.cont()), policy.pred()) );
return result;
}
};
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::find_first_of(cont.begin(), cont.end(),
m_cont.begin(), m_cont.end(),
m_pred);
}
private:
Container2 m_cont;
BinaryPredicate m_pred;
};
template<class Container1, class Container2>
void run_tests(Container1& cont1, Container2& cont2)
{
boost::range_test::range_return_test_driver test_driver;
test_driver(cont1, find_first_of_test_policy<Container2>(cont2));
test_driver(cont1, find_first_of_pred_test_policy<Container2, std::less<int> >(cont2));
test_driver(cont2, find_first_of_pred_test_policy<Container2, std::greater<int> >(cont2));
}
template<class Container1, class Container2>
void test_find_first_of_impl()
{
using namespace boost::assign;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type container1_t;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type container2_t;
container1_t mcont1;
Container1& cont1 = mcont1;
container2_t mcont2;
Container2& cont2 = mcont2;
run_tests(cont1, cont2);
mcont1 += 1;
run_tests(cont1, cont2);
mcont2 += 1;
run_tests(cont1, cont2);
mcont1 += 2,3,4,5,6,7,8,9;
mcont2 += 2,3,4;
run_tests(cont1, cont2);
mcont2.clear();
mcont2 += 7,8,9;
run_tests(cont1, cont2);
}
void test_find_first_of()
{
test_find_first_of_impl< std::vector<int>, std::vector<int> >();
test_find_first_of_impl< std::list<int>, std::list<int> >();
test_find_first_of_impl< std::deque<int>, std::deque<int> >();
test_find_first_of_impl< const std::vector<int>, const std::vector<int> >();
test_find_first_of_impl< const std::list<int>, const std::list<int> >();
test_find_first_of_impl< const std::deque<int>, const std::deque<int> >();
test_find_first_of_impl< const std::vector<int>, const std::list<int> >();
test_find_first_of_impl< const std::list<int>, const std::vector<int> >();
test_find_first_of_impl< const std::vector<int>, std::list<int> >();
test_find_first_of_impl< const std::list<int>, std::vector<int> >();
test_find_first_of_impl< std::vector<int>, std::list<int> >();
test_find_first_of_impl< std::list<int>, std::vector<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find_first_of" );
test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find_first_of::test_find_first_of ) );
return test;
}

View File

@@ -0,0 +1,126 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/find_if.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include "../test_driver/range_return_test_driver.hpp"
#include "../test_function/greater_than_x.hpp"
#include "../test_function/false_predicate.hpp"
#include <algorithm>
#include <functional>
#include <deque>
#include <list>
#include <vector>
namespace boost_range_test_algorithm_find_if
{
template<class UnaryPredicate>
class find_if_test_policy
{
public:
explicit find_if_test_policy(UnaryPredicate pred)
: m_pred(pred) {}
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::find_if(cont, m_pred);
BOOST_CHECK( result == boost::find_if(boost::make_iterator_range(cont), m_pred) );
return result;
}
template<boost::range_return_value return_type>
struct test_range
{
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(find_if_test_policy& policy, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::find_if<return_type>(cont, policy.pred());
BOOST_CHECK( result == boost::find_if<return_type>(boost::make_iterator_range(cont), policy.pred()) );
return result;
}
};
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::find_if(cont.begin(), cont.end(), m_pred);
}
UnaryPredicate& pred() { return m_pred; }
private:
UnaryPredicate m_pred;
};
template<class UnaryPredicate>
find_if_test_policy<UnaryPredicate>
make_policy(UnaryPredicate pred)
{
return find_if_test_policy<UnaryPredicate>(pred);
}
template<class Container>
void test_find_if_container()
{
using namespace boost::assign;
using namespace boost::range_test_function;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type container_t;
boost::range_test::range_return_test_driver test_driver;
container_t mcont;
Container& cont = mcont;
test_driver(cont, make_policy(greater_than_x<int>(5)));
test_driver(cont, make_policy(false_predicate()));
mcont.clear();
mcont += 1;
test_driver(cont, make_policy(greater_than_x<int>(5)));
test_driver(cont, make_policy(false_predicate()));
mcont.clear();
mcont += 1,2,3,4,5,6,7,8,9;
test_driver(cont, make_policy(greater_than_x<int>(5)));
test_driver(cont, make_policy(false_predicate()));
}
void test_find_if()
{
test_find_if_container< std::vector<int> >();
test_find_if_container< std::list<int> >();
test_find_if_container< std::deque<int> >();
test_find_if_container< const std::vector<int> >();
test_find_if_container< const std::list<int> >();
test_find_if_container< const std::deque<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find_if" );
test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find_if::test_find_if ) );
return test;
}

View File

@@ -0,0 +1,95 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/for_each.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/array.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm.hpp>
#include <list>
#include <set>
#include <vector>
#include "../test_function/check_equal_fn.hpp"
namespace boost
{
namespace
{
template< class Range >
unsigned int udistance(Range& rng)
{
return static_cast<unsigned int>(boost::distance(rng));
}
template< class SinglePassRange >
void test_for_each_impl( SinglePassRange rng )
{
using namespace boost::range_test_function;
typedef check_equal_fn< SinglePassRange > fn_t;
// Test the mutable version
fn_t result_fn = boost::for_each(rng, fn_t(rng));
BOOST_CHECK_EQUAL( boost::udistance(rng), result_fn.invocation_count() );
fn_t result_fn2 = boost::for_each(boost::make_iterator_range(rng), fn_t(rng));
BOOST_CHECK_EQUAL( boost::udistance(rng), result_fn2.invocation_count() );
// Test the constant version
const SinglePassRange& cref_rng = rng;
result_fn = boost::for_each(cref_rng, fn_t(cref_rng));
BOOST_CHECK_EQUAL( boost::udistance(cref_rng), result_fn.invocation_count() );
}
template< class Container >
void test_for_each_t()
{
using namespace boost::assign;
// Test empty
Container cont;
test_for_each_impl(cont);
// Test one element
cont += 0;
test_for_each_impl(cont);
// Test many elements
cont += 1,2,3,4,5,6,7,8,9;
test_for_each_impl(cont);
}
void test_for_each()
{
boost::array<int, 10> a = {{ 0,1,2,3,4,5,6,7,8,9 }};
test_for_each_impl(a);
test_for_each_t< std::vector<int> >();
test_for_each_t< std::list<int> >();
test_for_each_t< std::set<int> >();
test_for_each_t< std::multiset<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.for_each" );
test->add( BOOST_TEST_CASE( &boost::test_for_each ) );
return test;
}

View File

@@ -0,0 +1,95 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/generate.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
class generator_fn
{
public:
typedef int result_type;
generator_fn() : m_count(0) {}
int operator()() { return ++m_count; }
private:
int m_count;
};
template< class Container >
void test_generate_impl(Container& cont)
{
Container reference(cont);
std::generate(reference.begin(), reference.end(), generator_fn());
Container test(cont);
boost::generate(test, generator_fn());
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
Container test2(cont);
boost::generate(boost::make_iterator_range(test2), generator_fn());
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test2.begin(), test2.end() );
}
template< class Container >
void test_generate_impl()
{
using namespace boost::assign;
Container cont;
test_generate_impl(cont);
cont.clear();
cont += 9;
test_generate_impl(cont);
cont.clear();
cont += 9,8,7,6,5,4,3,2,1;
test_generate_impl(cont);
}
void test_generate()
{
test_generate_impl< std::vector<int> >();
test_generate_impl< std::list<int> >();
test_generate_impl< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.generate" );
test->add( BOOST_TEST_CASE( &boost::test_generate ) );
return test;
}

View File

@@ -0,0 +1,144 @@
// Copyright Neil Groves 2009. 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/algorithm/heap_algorithm.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template<class Container1, class Container2>
void check_equal(const Container1& cont1, const Container2& cont2)
{
BOOST_CHECK_EQUAL_COLLECTIONS(
cont1.begin(), cont1.end(),
cont2.begin(), cont2.end()
);
}
void test()
{
using namespace boost::assign;
std::vector<int> reference;
reference += 1,2,3,4,5,6,7,8,9;
std::vector<int> test_cont(reference);
std::vector<int> test_cont2(reference);
std::make_heap(reference.begin(), reference.end());
boost::make_heap(test_cont);
check_equal(reference, test_cont);
boost::make_heap(boost::make_iterator_range(test_cont2));
check_equal(reference, test_cont2);
std::push_heap(reference.begin(), reference.end());
boost::push_heap(test_cont);
check_equal(reference, test_cont);
boost::push_heap(boost::make_iterator_range(test_cont2));
check_equal(reference, test_cont2);
std::make_heap(reference.begin(), reference.end());
boost::make_heap(test_cont);
boost::make_heap(boost::make_iterator_range(test_cont2));
std::sort_heap(reference.begin(), reference.end());
boost::sort_heap(test_cont);
check_equal(reference, test_cont);
boost::sort_heap(boost::make_iterator_range(test_cont2));
check_equal(reference, test_cont2);
std::make_heap(reference.begin(), reference.end());
boost::make_heap(test_cont);
boost::make_heap(boost::make_iterator_range(test_cont2));
std::pop_heap(reference.begin(), reference.end());
boost::pop_heap(test_cont);
check_equal(reference, test_cont);
boost::pop_heap(boost::make_iterator_range(test_cont2));
check_equal(reference, test_cont2);
}
template<class BinaryPredicate>
void test_pred(BinaryPredicate pred)
{
using namespace boost::assign;
std::vector<int> reference;
reference += 1,2,3,4,5,6,7,8,9;
std::sort(reference.begin(), reference.end(), pred);
std::vector<int> test_cont(reference);
std::vector<int> test_cont2(reference);
std::make_heap(reference.begin(), reference.end(), pred);
boost::make_heap(test_cont, pred);
check_equal(reference, test_cont);
boost::make_heap(boost::make_iterator_range(test_cont2), pred);
check_equal(reference, test_cont2);
reference.push_back(5);
test_cont.push_back(5);
test_cont2.push_back(5);
std::push_heap(reference.begin(), reference.end(), pred);
boost::push_heap(test_cont, pred);
check_equal(reference, test_cont);
boost::push_heap(boost::make_iterator_range(test_cont2), pred);
check_equal(reference, test_cont2);
std::make_heap(reference.begin(), reference.end(), pred);
boost::make_heap(test_cont, pred);
boost::make_heap(boost::make_iterator_range(test_cont2), pred);
std::sort_heap(reference.begin(), reference.end(), pred);
boost::sort_heap(test_cont, pred);
check_equal(reference, test_cont);
boost::sort_heap(boost::make_iterator_range(test_cont2), pred);
check_equal(reference, test_cont2);
std::make_heap(reference.begin(), reference.end(), pred);
boost::make_heap(test_cont, pred);
boost::make_heap(boost::make_iterator_range(test_cont2), pred);
std::pop_heap(reference.begin(), reference.end(), pred);
boost::pop_heap(test_cont, pred);
check_equal(reference, test_cont);
boost::pop_heap(boost::make_iterator_range(test_cont2), pred);
check_equal(reference, test_cont2);
}
void test_heap()
{
test();
test_pred(std::less<int>());
test_pred(std::greater<int>());
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.heap" );
test->add( BOOST_TEST_CASE( &boost::test_heap ) );
return test;
}

View File

@@ -0,0 +1,164 @@
// Copyright Neil Groves 2009. 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/algorithm/set_algorithm.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template<class Container1, class Container2>
void test(Container1& cont1, Container2& cont2)
{
Container1 old_cont1(cont1);
Container2 old_cont2(cont2);
bool reference_result
= std::includes(cont1.begin(), cont1.end(),
cont2.begin(), cont2.end());
bool test_result = boost::includes(cont1, cont2);
BOOST_CHECK( reference_result == test_result );
BOOST_CHECK_EQUAL_COLLECTIONS(
old_cont1.begin(), old_cont1.end(),
cont1.begin(), cont1.end()
);
BOOST_CHECK_EQUAL_COLLECTIONS(
old_cont2.begin(), old_cont2.end(),
cont2.begin(), cont2.end()
);
BOOST_CHECK( test_result == boost::includes(boost::make_iterator_range(cont1), cont2) );
BOOST_CHECK( test_result == boost::includes(cont1, boost::make_iterator_range(cont2)) );
BOOST_CHECK( test_result == boost::includes(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2)) );
}
template<class Container, class BinaryPredicate>
void sort_container(Container& cont, BinaryPredicate pred)
{
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
std::vector<value_t> temp(cont.begin(), cont.end());
std::sort(temp.begin(), temp.end(), pred);
cont.assign(temp.begin(), temp.end());
}
template<class Container1,
class Container2,
class BinaryPredicate>
void test_pred(Container1 cont1, Container2 cont2,
BinaryPredicate pred)
{
sort_container(cont1, pred);
sort_container(cont2, pred);
Container1 old_cont1(cont1);
Container2 old_cont2(cont2);
bool reference_result
= std::includes(cont1.begin(), cont1.end(),
cont2.begin(), cont2.end(),
pred);
bool test_result = boost::includes(cont1, cont2, pred);
BOOST_CHECK( reference_result == test_result );
BOOST_CHECK_EQUAL_COLLECTIONS(
old_cont1.begin(), old_cont1.end(),
cont1.begin(), cont1.end()
);
BOOST_CHECK_EQUAL_COLLECTIONS(
old_cont2.begin(), old_cont2.end(),
cont2.begin(), cont2.end()
);
BOOST_CHECK( test_result == boost::includes(boost::make_iterator_range(cont1), cont2, pred) );
BOOST_CHECK( test_result == boost::includes(cont1, boost::make_iterator_range(cont2), pred) );
BOOST_CHECK( test_result == boost::includes(boost::make_iterator_range(cont1), boost::make_iterator_range(cont2), pred) );
}
template<class Container1, class Container2>
void test_includes_impl(
Container1& cont1,
Container2& cont2
)
{
test(cont1, cont2);
test_pred(cont1, cont2, std::less<int>());
test_pred(cont1, cont2, std::greater<int>());
}
template<class Container1, class Container2>
void test_includes_impl()
{
using namespace boost::assign;
Container1 cont1;
Container2 cont2;
test_includes_impl(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 1;
test_includes_impl(cont1, cont2);
cont1.clear();
cont2.clear();
cont2 += 1;
test_includes_impl(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 1,2,3,4,5,6,7,8,9;
cont2 += 2,3,4;
test_includes_impl(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 2,3,4;
cont2 += 1,2,3,4,5,6,7,8,9;
test_includes_impl(cont1, cont2);
}
void test_includes()
{
test_includes_impl< std::vector<int>, std::vector<int> >();
test_includes_impl< std::list<int>, std::list<int> >();
test_includes_impl< std::deque<int>, std::deque<int> >();
test_includes_impl< std::vector<int>, std::list<int> >();
test_includes_impl< std::list<int>, std::vector<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.includes" );
test->add( BOOST_TEST_CASE( &boost::test_includes ) );
return test;
}

View File

@@ -0,0 +1,166 @@
// Copyright Neil Groves 2009. 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/algorithm/inplace_merge.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template<class Container1, class Container2>
void test(Container1& cont1, Container2& cont2)
{
typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator
iterator_t BOOST_RANGE_UNUSED;
std::vector<value_t> reference_target(cont1.begin(), cont1.end());
reference_target.insert(reference_target.end(),
cont2.begin(), cont2.end());
std::vector<value_t> test_target(reference_target);
std::vector<value_t> test_target2(reference_target);
std::inplace_merge(reference_target.begin(),
reference_target.begin() + cont1.size(),
reference_target.end());
boost::inplace_merge(test_target,
test_target.begin() + cont1.size());
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target.begin(), test_target.end()
);
boost::inplace_merge(boost::make_iterator_range(test_target2),
test_target2.begin() + cont1.size());
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target2.begin(), test_target2.end()
);
}
template<class Container, class BinaryPredicate>
void sort_container(Container& cont, BinaryPredicate pred)
{
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
std::vector<value_t> temp(cont.begin(), cont.end());
std::sort(temp.begin(), temp.end(), pred);
cont.assign(temp.begin(), temp.end());
}
template<class Container1,
class Container2,
class BinaryPredicate>
void test_pred(Container1 cont1, Container2 cont2, BinaryPredicate pred)
{
typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator
iterator_t BOOST_RANGE_UNUSED;
sort_container(cont1, pred);
sort_container(cont2, pred);
std::vector<value_t> reference_target(cont1.begin(), cont1.end());
reference_target.insert(reference_target.end(),
cont2.begin(), cont2.end());
std::vector<value_t> test_target(reference_target);
std::vector<value_t> test_target2(reference_target);
std::inplace_merge(reference_target.begin(),
reference_target.begin() + cont1.size(),
reference_target.end(), pred);
boost::inplace_merge(test_target,
test_target.begin() + cont1.size(),
pred);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target.begin(), test_target.end()
);
boost::inplace_merge(boost::make_iterator_range(test_target2),
test_target2.begin() + cont1.size(),
pred);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target2.begin(), test_target2.end()
);
}
template<class Container1, class Container2>
void test_inplace_merge_impl(Container1& cont1, Container2& cont2)
{
test(cont1, cont2);
test_pred(cont1, cont2, std::less<int>());
test_pred(cont1, cont2, std::greater<int>());
}
template<class Container1, class Container2>
void test_inplace_merge_impl()
{
using namespace boost::assign;
Container1 cont1;
Container2 cont2;
test_inplace_merge_impl(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 1;
test_inplace_merge_impl(cont1, cont2);
cont1.clear();
cont2.clear();
cont2 += 1;
test_inplace_merge_impl(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 1,3,5,7,9,11,13,15,17,19;
cont2 += 2,4,6,8,10,12,14,16,18,20;
test_inplace_merge_impl(cont1, cont2);
}
void test_inplace_merge()
{
test_inplace_merge_impl< std::vector<int>, std::vector<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.inplace_merge" );
test->add( BOOST_TEST_CASE( &boost::test_inplace_merge ) );
return test;
}

View File

@@ -0,0 +1,157 @@
// Copyright Neil Groves 2009. 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/algorithm/lexicographical_compare.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/value_type.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template<class ForwardRange1, class ForwardRange2>
void test_lexicographical_compare_impl_nopred(ForwardRange1& rng1,
ForwardRange2& rng2)
{
const bool reference = std::lexicographical_compare(
boost::begin(rng1), boost::end(rng1),
boost::begin(rng2), boost::end(rng2));
const bool test = boost::lexicographical_compare(rng1, rng2);
BOOST_CHECK( reference == test );
BOOST_CHECK( test == boost::lexicographical_compare(boost::make_iterator_range(rng1), rng2) );
BOOST_CHECK( test == boost::lexicographical_compare(rng1, boost::make_iterator_range(rng2)) );
BOOST_CHECK( test == boost::lexicographical_compare(boost::make_iterator_range(rng1), boost::make_iterator_range(rng2)) );
}
template<class ForwardRange1, class ForwardRange2,
class BinaryPredicate>
void test_lexicographical_compare_impl_pred(ForwardRange1& rng1,
ForwardRange2& rng2,
BinaryPredicate pred)
{
const bool reference = std::lexicographical_compare(
boost::begin(rng1), boost::end(rng1),
boost::begin(rng2), boost::end(rng2),
pred);
const bool test = boost::lexicographical_compare(rng1, rng2, pred);
BOOST_CHECK( reference == test );
BOOST_CHECK( test == boost::lexicographical_compare(boost::make_iterator_range(rng1), rng2, pred) );
BOOST_CHECK( test == boost::lexicographical_compare(rng1, boost::make_iterator_range(rng2), pred) );
BOOST_CHECK( test == boost::lexicographical_compare(boost::make_iterator_range(rng1), boost::make_iterator_range(rng2), pred) );
}
template<class Container1, class Container2>
void test_lexicographical_compare_impl(Container1& cont1,
Container2& cont2)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_value<Container1>::type value_t;
test_lexicographical_compare_impl_nopred(cont1, cont2);
test_lexicographical_compare_impl_pred(cont1, cont2, std::less<value_t>());
test_lexicographical_compare_impl_pred(cont1, cont2, std::greater<value_t>());
}
template<class Container1, class Container2>
void test_lexicographical_compare_impl()
{
using namespace boost::assign;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type container1_t;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type container2_t;
container1_t cont1;
container2_t cont2;
test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
cont1.clear();
cont2.clear();
cont1.push_back(1);
cont2.push_back(1);
test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 2;
cont2 += 1;
test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 1;
cont2 += 2;
test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 1,2,3,4,5,6,7;
cont2 += 1,2,3,4,5,6,7;
test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 1,2,3,4,5,6,7;
cont2 += 1,2,3,4,5,6;
test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 1,2,3,4,5,6;
cont2 += 1,2,3,4,5,6,7;
test_lexicographical_compare_impl<Container1,Container2>(cont1, cont2);
}
template<class Container1>
void test_lexicographical_compare_rhs()
{
typedef BOOST_DEDUCED_TYPENAME range_value<Container1>::type value_t;
test_lexicographical_compare_impl<Container1, const std::vector<value_t> >();
test_lexicographical_compare_impl<Container1, const std::deque<value_t> >();
test_lexicographical_compare_impl<Container1, const std::list<value_t> >();
test_lexicographical_compare_impl<Container1, std::vector<value_t> >();
test_lexicographical_compare_impl<Container1, std::deque<value_t> >();
test_lexicographical_compare_impl<Container1, std::list<value_t> >();
}
void test_lexicographical_compare()
{
test_lexicographical_compare_rhs< const std::vector<int> >();
test_lexicographical_compare_rhs< const std::deque<int> >();
test_lexicographical_compare_rhs< const std::list<int> >();
test_lexicographical_compare_rhs< std::vector<int> >();
test_lexicographical_compare_rhs< std::deque<int> >();
test_lexicographical_compare_rhs< std::list<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.lexicographical_compare" );
test->add( BOOST_TEST_CASE( &boost::test_lexicographical_compare ) );
return test;
}

View File

@@ -0,0 +1,180 @@
// Copyright Neil Groves 2009. 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/algorithm/lower_bound.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm/lower_bound.hpp>
#include "../test_driver/range_return_test_driver.hpp"
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost_range_test_algorithm_lower_bound
{
class lower_bound_policy
{
public:
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::lower_bound(cont, 5);
BOOST_CHECK( result == boost::lower_bound(boost::make_iterator_range(cont), 5) );
return result;
}
template<boost::range_return_value return_type>
struct test_range
{
template<class Container, class Policy>
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy&, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::lower_bound<return_type>(cont, 5);
BOOST_CHECK( result == boost::lower_bound<return_type>(boost::make_iterator_range(cont), 5) );
return result;
}
};
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::lower_bound(cont.begin(), cont.end(), 5);
}
};
template< class BinaryPredicate >
struct lower_bound_pred_policy
{
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::lower_bound(cont, 5, m_pred);
BOOST_CHECK( result == boost::lower_bound(
boost::make_iterator_range(cont), 5, m_pred) );
return result;
}
template< boost::range_return_value return_type >
struct test_range
{
template<class Container, class Policy>
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy& policy, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::lower_bound<return_type>(cont, 5, policy.pred());
BOOST_CHECK( result == boost::lower_bound<return_type>(
boost::make_iterator_range(cont), 5, policy.pred()) );
return result;
}
};
template<class Container>
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::lower_bound(
cont.begin(), cont.end(), 5, m_pred);
}
BinaryPredicate& pred() { return m_pred; }
private:
BinaryPredicate m_pred;
};
template<class Container,
class TestPolicy,
class BinaryPredicate>
void test_lower_bound_impl(TestPolicy policy, BinaryPredicate pred)
{
using namespace boost::assign;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type container_t;
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
boost::range_test::range_return_test_driver test_driver;
container_t mcont;
Container& cont = mcont;
test_driver(cont, policy);
mcont.clear();
mcont += 1;
std::vector<value_t> temp(mcont.begin(), mcont.end());
std::sort(temp.begin(), temp.end(), pred);
mcont.assign(temp.begin(), temp.end());
test_driver(cont, policy);
mcont.clear();
mcont += 1,2,3,4,5,6,7,8,9;
temp.assign(mcont.begin(), mcont.end());
std::sort(temp.begin(), temp.end(), pred);
mcont.assign(temp.begin(), temp.end());
test_driver(cont, policy);
}
template<class Container>
void test_lower_bound_impl()
{
test_lower_bound_impl<Container>(
lower_bound_policy(),
std::less<int>()
);
test_lower_bound_impl<Container>(
lower_bound_pred_policy<std::less<int> >(),
std::less<int>()
);
test_lower_bound_impl<Container>(
lower_bound_pred_policy<std::greater<int> >(),
std::greater<int>()
);
}
void test_lower_bound()
{
test_lower_bound_impl< std::vector<int> >();
test_lower_bound_impl< std::list<int> >();
test_lower_bound_impl< std::deque<int> >();
test_lower_bound_impl< const std::vector<int> >();
test_lower_bound_impl< const std::list<int> >();
test_lower_bound_impl< const std::deque<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.lower_bound" );
test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_lower_bound::test_lower_bound ) );
return test;
}

View File

@@ -0,0 +1,164 @@
// Copyright Neil Groves 2009. 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/algorithm/max_element.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/iterator.hpp>
#include "../test_driver/range_return_test_driver.hpp"
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost_range_test_algorithm_max_element
{
class max_element_test_policy
{
public:
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::max_element(cont);
BOOST_CHECK( result == boost::max_element(
boost::make_iterator_range(cont)) );
return result;
}
template<boost::range_return_value return_type>
struct test_range
{
template<class Container, class Policy>
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy&, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::max_element<return_type>(cont);
BOOST_CHECK( result == boost::max_element<return_type>(
boost::make_iterator_range(cont)) );
return result;
}
};
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::max_element(cont.begin(), cont.end());
}
};
template<class Pred>
class max_element_pred_test_policy
{
public:
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::max_element(cont, Pred());
BOOST_CHECK( result == boost::max_element(
boost::make_iterator_range(cont), Pred()) );
return result;
}
Pred pred() const { return Pred(); }
template< boost::range_return_value return_type >
struct test_range
{
template< class Container, class Policy >
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy& policy, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::max_element<return_type>(cont, policy.pred());
BOOST_CHECK( result == boost::max_element<return_type>(
boost::make_iterator_range(cont), policy.pred()) );
return result;
}
};
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::max_element(cont.begin(), cont.end(), Pred());
}
};
template<class Container, class TestPolicy>
void test_max_element_impl(TestPolicy policy)
{
using namespace boost::assign;
typedef BOOST_DEDUCED_TYPENAME Container::value_type
value_t BOOST_RANGE_UNUSED;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type
container_t;
boost::range_test::range_return_test_driver test_driver;
container_t cont;
test_driver(cont, policy);
cont.clear();
cont += 1;
test_driver(cont, policy);
cont.clear();
cont += 1,2,2,2,3,4,5,6,7,8,9;
test_driver(cont, policy);
}
template<class Container>
void test_max_element_impl()
{
test_max_element_impl<Container>(max_element_test_policy());
test_max_element_impl<Container>(
max_element_pred_test_policy<std::less<int> >());
test_max_element_impl<Container>(
max_element_pred_test_policy<std::greater<int> >());
}
void test_max_element()
{
test_max_element_impl< const std::vector<int> >();
test_max_element_impl< const std::deque<int> >();
test_max_element_impl< const std::list<int> >();
test_max_element_impl< std::vector<int> >();
test_max_element_impl< std::deque<int> >();
test_max_element_impl< std::list<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.max_element" );
test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_max_element::test_max_element ) );
return test;
}

View File

@@ -0,0 +1,236 @@
// Copyright Neil Groves 2009. 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/algorithm/merge.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template<class Container1, class Container2>
void test(Container1& cont1, Container2& cont2)
{
typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
std::vector<value_t> reference_target( cont1.size() + cont2.size() );
iterator_t reference_it
= std::merge(cont1.begin(), cont1.end(),
cont2.begin(), cont2.end(),
reference_target.begin());
std::vector<value_t> test_target( cont1.size() + cont2.size() );
iterator_t test_it
= boost::merge(cont1, cont2, test_target.begin());
BOOST_CHECK_EQUAL(
std::distance<iterator_t>(reference_target.begin(), reference_it),
std::distance<iterator_t>(test_target.begin(), test_it)
);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target.begin(), test_target.end()
);
test_it = boost::merge(boost::make_iterator_range(cont1),
cont2, test_target.begin());
BOOST_CHECK_EQUAL(
std::distance<iterator_t>(reference_target.begin(), reference_it),
std::distance<iterator_t>(test_target.begin(), test_it)
);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target.begin(), test_target.end()
);
test_it = boost::merge(cont1, boost::make_iterator_range(cont2),
test_target.begin());
BOOST_CHECK_EQUAL(
std::distance<iterator_t>(reference_target.begin(), reference_it),
std::distance<iterator_t>(test_target.begin(), test_it)
);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target.begin(), test_target.end()
);
test_it = boost::merge(boost::make_iterator_range(cont1),
boost::make_iterator_range(cont2),
test_target.begin());
BOOST_CHECK_EQUAL(
std::distance<iterator_t>(reference_target.begin(), reference_it),
std::distance<iterator_t>(test_target.begin(), test_it)
);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target.begin(), test_target.end()
);
}
template<class Container, class BinaryPredicate>
void sort_container(Container& cont, BinaryPredicate pred)
{
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
std::vector<value_t> temp(cont.begin(), cont.end());
std::sort(temp.begin(), temp.end(), pred);
cont.assign(temp.begin(), temp.end());
}
template<class Container1,
class Container2,
class BinaryPredicate>
void test_pred(Container1 cont1, Container2 cont2, BinaryPredicate pred)
{
typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;
sort_container(cont1, pred);
sort_container(cont2, pred);
std::vector<value_t> reference_target( cont1.size() + cont2.size() );
iterator_t reference_it
= std::merge(cont1.begin(), cont1.end(),
cont2.begin(), cont2.end(),
reference_target.begin(), pred);
std::vector<value_t> test_target( cont1.size() + cont2.size() );
iterator_t test_it
= boost::merge(cont1, cont2, test_target.begin(), pred);
BOOST_CHECK_EQUAL(
std::distance(reference_target.begin(), reference_it),
std::distance(test_target.begin(), test_it)
);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target.begin(), test_target.end()
);
test_it = boost::merge(boost::make_iterator_range(cont1), cont2,
test_target.begin(), pred);
BOOST_CHECK_EQUAL(
std::distance(reference_target.begin(), reference_it),
std::distance(test_target.begin(), test_it)
);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target.begin(), test_target.end()
);
test_it = boost::merge(cont1, boost::make_iterator_range(cont2),
test_target.begin(), pred);
BOOST_CHECK_EQUAL(
std::distance(reference_target.begin(), reference_it),
std::distance(test_target.begin(), test_it)
);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target.begin(), test_target.end()
);
test_it = boost::merge(boost::make_iterator_range(cont1),
boost::make_iterator_range(cont2),
test_target.begin(), pred);
BOOST_CHECK_EQUAL(
std::distance(reference_target.begin(), reference_it),
std::distance(test_target.begin(), test_it)
);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference_target.begin(), reference_target.end(),
test_target.begin(), test_target.end()
);
}
template<class Container1, class Container2>
void test_merge_impl(Container1& cont1, Container2& cont2)
{
test(cont1, cont2);
test_pred(cont1, cont2, std::less<int>());
test_pred(cont1, cont2, std::greater<int>());
}
template<class Container1, class Container2>
void test_merge_impl()
{
using namespace boost::assign;
Container1 cont1;
Container2 cont2;
test_merge_impl(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 1;
test_merge_impl(cont1, cont2);
cont1.clear();
cont2.clear();
cont2 += 1;
test_merge_impl(cont1, cont2);
cont1.clear();
cont2.clear();
cont1 += 1,3,5,7,9,11,13,15,17,19;
cont2 += 2,4,6,8,10,12,14,16,18,20;
test_merge_impl(cont1, cont2);
}
void test_merge()
{
test_merge_impl< std::vector<int>, std::vector<int> >();
test_merge_impl< std::list<int>, std::list<int> >();
test_merge_impl< std::deque<int>, std::deque<int> >();
test_merge_impl< std::list<int>, std::vector<int> >();
test_merge_impl< std::vector<int>, std::list<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.merge" );
test->add( BOOST_TEST_CASE( &boost::test_merge ) );
return test;
}

View File

@@ -0,0 +1,162 @@
// Copyright Neil Groves 2009. 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/algorithm/min_element.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/range/iterator.hpp>
#include "../test_driver/range_return_test_driver.hpp"
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost_range_test_algorithm_min_element
{
class min_element_test_policy
{
public:
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::min_element(cont);
BOOST_CHECK( result == boost::min_element(boost::make_iterator_range(cont)) );
return result;
}
template< boost::range_return_value return_type >
struct test_range
{
template< class Container, class Policy >
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy&, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::min_element<return_type>(cont);
BOOST_CHECK( result == boost::min_element<return_type>(boost::make_iterator_range(cont)) );
return result;
}
};
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::min_element(cont.begin(), cont.end());
}
};
template<class Pred>
class min_element_pred_test_policy
{
public:
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
iter_t result = boost::min_element(cont, Pred());
BOOST_CHECK( result == boost::min_element(
boost::make_iterator_range(cont), Pred()) );
return result;
}
Pred pred() const { return Pred(); }
template< boost::range_return_value return_type >
struct test_range
{
template< class Container, class Policy >
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy& policy, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
result_t result = boost::min_element<return_type>(cont, policy.pred());
BOOST_CHECK( result == boost::min_element<return_type>(
boost::make_iterator_range(cont), policy.pred()) );
return result;
}
};
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::min_element(cont.begin(), cont.end(), Pred());
}
};
template<class Container, class TestPolicy>
void test_min_element_impl(TestPolicy policy)
{
using namespace boost::assign;
typedef BOOST_DEDUCED_TYPENAME Container::value_type
value_t BOOST_RANGE_UNUSED;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type
container_t;
boost::range_test::range_return_test_driver test_driver;
container_t cont;
test_driver(cont, policy);
cont.clear();
cont += 1;
test_driver(cont, policy);
cont.clear();
cont += 1,2,2,2,3,4,5,6,7,8,9;
test_driver(cont, policy);
}
template<class Container>
void test_min_element_impl()
{
test_min_element_impl<Container>(min_element_test_policy());
test_min_element_impl<Container>(
min_element_pred_test_policy<std::less<int> >());
test_min_element_impl<Container>(
min_element_pred_test_policy<std::greater<int> >());
}
void test_min_element()
{
test_min_element_impl< const std::vector<int> >();
test_min_element_impl< const std::deque<int> >();
test_min_element_impl< const std::list<int> >();
test_min_element_impl< std::vector<int> >();
test_min_element_impl< std::deque<int> >();
test_min_element_impl< std::list<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.min_element" );
test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_min_element::test_min_element ) );
return test;
}

View File

@@ -0,0 +1,242 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/mismatch.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <list>
#include <set>
#include <vector>
namespace boost
{
namespace
{
template< class Container1, class Container2 >
void eval_mismatch(Container1& cont1,
Container2& cont2,
BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type ref_it1,
BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type ref_it2
)
{
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type iter1_t;
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type iter2_t;
typedef std::pair<iter1_t, iter2_t> result_pair_t;
result_pair_t result = boost::mismatch(cont1, cont2);
BOOST_CHECK( result.first == ref_it1 );
BOOST_CHECK( result.second == ref_it2 );
result = boost::mismatch(boost::make_iterator_range(cont1),
cont2);
BOOST_CHECK( result.first == ref_it1 );
BOOST_CHECK( result.second == ref_it2 );
result = boost::mismatch(cont1,
boost::make_iterator_range(cont2));
BOOST_CHECK( result.first == ref_it1 );
BOOST_CHECK( result.second == ref_it2 );
result = boost::mismatch(boost::make_iterator_range(cont1),
boost::make_iterator_range(cont2));
BOOST_CHECK( result.first == ref_it1 );
BOOST_CHECK( result.second == ref_it2 );
}
template< class Container1, class Container2, class Pred >
void eval_mismatch(Container1& cont1,
Container2& cont2,
Pred pred,
BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type ref_it1,
BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type ref_it2
)
{
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type iter1_t;
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type iter2_t;
typedef std::pair<iter1_t, iter2_t> result_pair_t;
result_pair_t result = boost::mismatch(cont1, cont2, pred);
BOOST_CHECK( result.first == ref_it1 );
BOOST_CHECK( result.second == ref_it2 );
result = boost::mismatch(boost::make_iterator_range(cont1),
cont2, pred);
BOOST_CHECK( result.first == ref_it1 );
BOOST_CHECK( result.second == ref_it2 );
result = boost::mismatch(cont1,
boost::make_iterator_range(cont2), pred);
BOOST_CHECK( result.first == ref_it1 );
BOOST_CHECK( result.second == ref_it2 );
result = boost::mismatch(boost::make_iterator_range(cont1),
boost::make_iterator_range(cont2),
pred);
BOOST_CHECK( result.first == ref_it1 );
BOOST_CHECK( result.second == ref_it2 );
}
template< class Container1, class Container2 >
void eval_mismatch(Container1& cont1,
Container2& cont2,
const int ref1,
const int ref2)
{
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type iter1_t;
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type iter2_t;
typedef std::pair<iter1_t, iter2_t> result_pair_t;
result_pair_t result = boost::mismatch(cont1, cont2);
BOOST_CHECK_EQUAL( ref1, *result.first );
BOOST_CHECK_EQUAL( ref2, *result.second );
result = boost::mismatch(boost::make_iterator_range(cont1), cont2);
BOOST_CHECK_EQUAL( ref1, *result.first );
BOOST_CHECK_EQUAL( ref2, *result.second );
result = boost::mismatch(cont1, boost::make_iterator_range(cont2));
BOOST_CHECK_EQUAL( ref1, *result.first );
BOOST_CHECK_EQUAL( ref2, *result.second );
result = boost::mismatch(boost::make_iterator_range(cont1),
boost::make_iterator_range(cont2));
BOOST_CHECK_EQUAL( ref1, *result.first );
BOOST_CHECK_EQUAL( ref2, *result.second );
}
template< class Container1, class Container2, class Pred >
void eval_mismatch(Container1& cont1,
Container2& cont2,
Pred pred,
const int ref1,
const int ref2)
{
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container1>::type iter1_t;
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container2>::type iter2_t;
typedef std::pair<iter1_t, iter2_t> result_pair_t;
result_pair_t result = boost::mismatch(cont1, cont2, pred);
BOOST_CHECK_EQUAL( ref1, *result.first );
BOOST_CHECK_EQUAL( ref2, *result.second );
result = boost::mismatch(boost::make_iterator_range(cont1),
cont2, pred);
BOOST_CHECK_EQUAL( ref1, *result.first );
BOOST_CHECK_EQUAL( ref2, *result.second );
result = boost::mismatch(cont1, boost::make_iterator_range(cont2),
pred);
BOOST_CHECK_EQUAL( ref1, *result.first );
BOOST_CHECK_EQUAL( ref2, *result.second );
result = boost::mismatch(boost::make_iterator_range(cont1),
boost::make_iterator_range(cont2),
pred);
BOOST_CHECK_EQUAL( ref1, *result.first );
BOOST_CHECK_EQUAL( ref2, *result.second );
}
template< class Container1, class Container2 >
void test_mismatch_impl()
{
using namespace boost::assign;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type MutableContainer1;
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type MutableContainer2;
MutableContainer1 cont1;
const Container1& cref_cont1 = cont1;
MutableContainer2 cont2;
const Container2& cref_cont2 = cont2;
typedef BOOST_DEDUCED_TYPENAME Container1::iterator
iterator1_t BOOST_RANGE_UNUSED;
typedef BOOST_DEDUCED_TYPENAME Container1::const_iterator
const_iterator1_t BOOST_RANGE_UNUSED;
typedef BOOST_DEDUCED_TYPENAME Container2::iterator
iterator2_t BOOST_RANGE_UNUSED;
typedef BOOST_DEDUCED_TYPENAME Container2::const_iterator
const_iterator2_t BOOST_RANGE_UNUSED;
eval_mismatch(cont1, cont2, cont1.end(), cont2.end());
eval_mismatch(cont1, cont2, std::equal_to<int>(), cont1.end(), cont2.end());
eval_mismatch(cref_cont1, cont2, cref_cont1.end(), cont2.end());
eval_mismatch(cref_cont1, cont2, std::equal_to<int>(), cref_cont1.end(), cont2.end());
eval_mismatch(cont1, cref_cont2, cont1.end(), cref_cont2.end());
eval_mismatch(cont1, cref_cont2, std::equal_to<int>(), cont1.end(), cref_cont2.end());
eval_mismatch(cref_cont1, cref_cont2, cref_cont1.end(), cref_cont2.end());
eval_mismatch(cref_cont1, cref_cont2, std::equal_to<int>(), cref_cont1.end(), cref_cont2.end());
cont1 += 1,2,3,4;
cont2 += 1,2,3,4;
eval_mismatch(cont1, cont2, cont1.end(), cont2.end());
eval_mismatch(cont1, cont2, std::equal_to<int>(), cont1.end(), cont2.end());
eval_mismatch(cref_cont1, cont2, cref_cont1.end(), cont2.end());
eval_mismatch(cref_cont1, cont2, std::equal_to<int>(), cref_cont1.end(), cont2.end());
eval_mismatch(cont1, cref_cont2, cont1.end(), cref_cont2.end());
eval_mismatch(cont1, cref_cont2, std::equal_to<int>(), cont1.end(), cref_cont2.end());
eval_mismatch(cref_cont1, cref_cont2, cref_cont1.end(), cref_cont2.end());
eval_mismatch(cref_cont1, cref_cont2, std::equal_to<int>(), cref_cont1.end(), cref_cont2.end());
cont1.clear();
cont2.clear();
cont1 += 1,2,3,4;
cont2 += 1,2,5,4;
eval_mismatch(cont1, cont2, 3, 5);
eval_mismatch(cont1, cont2, std::equal_to<int>(), 3, 5);
eval_mismatch(cont1, cont2, std::not_equal_to<int>(), cont1.begin(), cont2.begin());
eval_mismatch(cref_cont1, cont2, 3, 5);
eval_mismatch(cref_cont1, cont2, std::equal_to<int>(), 3, 5);
eval_mismatch(cref_cont1, cont2, std::not_equal_to<int>(), cref_cont1.begin(), cont2.begin());
eval_mismatch(cont1, cref_cont2, 3, 5);
eval_mismatch(cont1, cref_cont2, std::equal_to<int>(), 3, 5);
eval_mismatch(cont1, cref_cont2, std::not_equal_to<int>(), cont1.begin(), cref_cont2.begin());
eval_mismatch(cref_cont1, cref_cont2, 3, 5);
eval_mismatch(cref_cont1, cref_cont2, std::equal_to<int>(), 3, 5);
eval_mismatch(cref_cont1, cref_cont2, std::not_equal_to<int>(), cref_cont1.begin(), cref_cont2.begin());
}
void test_mismatch()
{
test_mismatch_impl< std::list<int>, std::list<int> >();
test_mismatch_impl< const std::list<int>, std::list<int> >();
test_mismatch_impl< std::list<int>, const std::list<int> >();
test_mismatch_impl< const std::list<int>, const std::list<int> >();
test_mismatch_impl< std::vector<int>, std::list<int> >();
test_mismatch_impl< const std::vector<int>, std::list<int> >();
test_mismatch_impl< std::vector<int>, const std::list<int> >();
test_mismatch_impl< const std::vector<int>, const std::list<int> >();
test_mismatch_impl< std::list<int>, std::vector<int> >();
test_mismatch_impl< const std::list<int>, std::vector<int> >();
test_mismatch_impl< std::list<int>, const std::vector<int> >();
test_mismatch_impl< const std::list<int>, const std::vector<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.mismatch" );
test->add( BOOST_TEST_CASE( &boost::test_mismatch ) );
return test;
}

View File

@@ -0,0 +1,125 @@
// Copyright Neil Groves 2009. 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/assign.hpp>
#include <boost/range/algorithm/permutation.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <algorithm>
#include <deque>
#include <functional>
#include <list>
#include <vector>
namespace boost
{
namespace
{
template<class Container>
void test_next_permutation_impl(const Container& cont)
{
Container reference(cont);
Container test(cont);
const bool reference_ret
= std::next_permutation(reference.begin(), reference.end());
const bool test_ret = boost::next_permutation(test);
BOOST_CHECK( reference_ret == test_ret );
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
test = cont;
BOOST_CHECK( test_ret == boost::next_permutation(boost::make_iterator_range(test)) );
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
}
template<class Container, class BinaryPredicate>
void test_next_permutation_pred_impl(const Container& cont,
BinaryPredicate pred)
{
Container reference(cont);
Container test(cont);
const bool reference_ret
= std::next_permutation(reference.begin(), reference.end(),
pred);
const bool test_ret
= boost::next_permutation(test, pred);
BOOST_CHECK( reference_ret == test_ret );
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
test = cont;
BOOST_CHECK( test_ret == boost::next_permutation(boost::make_iterator_range(test), pred) );
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
}
template<class Container>
void test_next_permutation_(const Container& cont)
{
test_next_permutation_impl(cont);
test_next_permutation_pred_impl(cont, std::less<int>());
test_next_permutation_pred_impl(cont, std::greater<int>());
}
template<class Container>
void run_tests()
{
using namespace boost::assign;
Container cont;
test_next_permutation_(cont);
cont.clear();
cont += 1;
test_next_permutation_(cont);
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test_next_permutation_(cont);
}
void test_next_permutation()
{
run_tests< std::vector<int> >();
run_tests< std::list<int> >();
run_tests< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.next_permutation" );
test->add( BOOST_TEST_CASE( &boost::test_next_permutation ) );
return test;
}

View File

@@ -0,0 +1,174 @@
// Copyright Neil Groves 2009. 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/algorithm/nth_element.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
struct nth_element_policy
{
template<class Container, class Iterator>
void test_nth_element(Container& cont, Iterator mid)
{
const Container old_cont(cont);
boost::nth_element(cont, mid);
// Test the same operation on the container, for the
// case where a temporary is passed as the first
// argument.
Container cont2(old_cont);
const std::size_t index = std::distance(cont.begin(), mid);
Iterator mid2(cont2.begin());
std::advance(mid2, index);
boost::nth_element(boost::make_iterator_range(cont2), mid2);
BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
cont2.begin(), cont2.end() );
}
template<class Container, class Iterator>
void reference_nth_element(Container& cont, Iterator mid)
{
std::nth_element(cont.begin(), mid, cont.end());
}
};
template<class BinaryPredicate>
struct nth_element_pred_policy
{
template<class Container, class Iterator>
void test_nth_element(Container& cont, Iterator mid)
{
const Container old_cont(cont);
boost::nth_element(cont, mid, BinaryPredicate());
Container cont2(old_cont);
const std::size_t index = std::distance(cont.begin(), mid);
Iterator mid2(cont2.begin());
std::advance(mid2, index);
boost::nth_element(boost::make_iterator_range(cont2), mid2,
BinaryPredicate());
BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
cont2.begin(), cont2.end() );
}
template<class Container, class Iterator>
void reference_nth_element(Container& cont, Iterator mid)
{
std::nth_element(cont.begin(), mid, cont.end(), BinaryPredicate());
}
};
template<class Container, class TestPolicy>
void test_nth_element_tp_impl(Container& cont, TestPolicy policy)
{
Container reference(cont);
Container test(cont);
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
BOOST_CHECK_EQUAL( reference.size(), test.size() );
if (reference.size() != test.size())
return;
iterator_t reference_mid = reference.begin();
iterator_t test_mid = test.begin();
bool complete = false;
while (!complete)
{
if (reference_mid == reference.end())
complete = true;
policy.test_nth_element(test, test_mid);
policy.reference_nth_element(reference, reference_mid);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
if (reference_mid != reference.end())
{
++reference_mid;
++test_mid;
}
}
}
template<class Container>
void test_nth_element_impl(Container& cont)
{
test_nth_element_tp_impl(cont, nth_element_policy());
}
template<class Container, class BinaryPredicate>
void test_nth_element_impl(Container& cont, BinaryPredicate pred)
{
test_nth_element_tp_impl(cont, nth_element_pred_policy<BinaryPredicate>());
}
template<class Container>
void run_tests(Container& cont)
{
test_nth_element_impl(cont);
test_nth_element_impl(cont, std::less<int>());
test_nth_element_impl(cont, std::greater<int>());
}
template<class Container>
void test_nth_element_impl()
{
using namespace boost::assign;
Container cont;
run_tests(cont);
cont.clear();
cont += 1;
run_tests(cont);
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
run_tests(cont);
}
void test_nth_element()
{
test_nth_element_impl< std::vector<int> >();
test_nth_element_impl< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.nth_element" );
test->add( BOOST_TEST_CASE( &boost::test_nth_element ) );
return test;
}

View File

@@ -0,0 +1,170 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/partial_sort.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
struct partial_sort_policy
{
template<class Container, class Iterator>
void test_partial_sort(Container& cont, Iterator mid)
{
const Container old_cont(cont);
boost::partial_sort(cont, mid);
const std::size_t index = std::distance(cont.begin(), mid);
Container cont2(old_cont);
Iterator mid2(cont2.begin());
std::advance(mid2, index);
boost::partial_sort(cont2, mid2);
BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
cont2.begin(), cont2.end() );
}
template<class Container, class Iterator>
void reference_partial_sort(Container& cont, Iterator mid)
{
std::partial_sort(cont.begin(), mid, cont.end());
}
};
template<class BinaryPredicate>
struct partial_sort_pred_policy
{
template<class Container, class Iterator>
void test_partial_sort(Container& cont, Iterator mid)
{
const Container old_cont(cont);
boost::partial_sort(cont, mid, BinaryPredicate());
const std::size_t index = std::distance(cont.begin(), mid);
Container cont2(old_cont);
Iterator mid2(cont2.begin());
std::advance(mid2, index);
boost::partial_sort(cont2, mid2, BinaryPredicate());
BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
cont2.begin(), cont2.end() );
}
template<class Container, class Iterator>
void reference_partial_sort(Container& cont, Iterator mid)
{
std::partial_sort(cont.begin(), mid, cont.end(), BinaryPredicate());
}
};
template<class Container, class TestPolicy>
void test_partial_sort_tp_impl(Container& cont, TestPolicy policy)
{
Container reference(cont);
Container test(cont);
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
BOOST_CHECK_EQUAL( reference.size(), test.size() );
if (reference.size() != test.size())
return;
iterator_t reference_mid = reference.begin();
iterator_t test_mid = test.begin();
bool complete = false;
while (!complete)
{
if (reference_mid == reference.end())
complete = true;
policy.test_partial_sort(test, test_mid);
policy.reference_partial_sort(reference, reference_mid);
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
if (reference_mid != reference.end())
{
++reference_mid;
++test_mid;
}
}
}
template<class Container>
void test_partial_sort_impl(Container& cont)
{
test_partial_sort_tp_impl(cont, partial_sort_policy());
}
template<class Container, class BinaryPredicate>
void test_partial_sort_impl(Container& cont, BinaryPredicate pred)
{
test_partial_sort_tp_impl(cont, partial_sort_pred_policy<BinaryPredicate>());
}
template<class Container>
void test_partial_sort_impl()
{
using namespace boost::assign;
Container cont;
test_partial_sort_impl(cont);
test_partial_sort_impl(cont, std::less<int>());
test_partial_sort_impl(cont, std::greater<int>());
cont.clear();
cont += 1;
test_partial_sort_impl(cont);
test_partial_sort_impl(cont, std::less<int>());
test_partial_sort_impl(cont, std::greater<int>());
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test_partial_sort_impl(cont);
test_partial_sort_impl(cont, std::less<int>());
test_partial_sort_impl(cont, std::greater<int>());
}
void test_partial_sort()
{
test_partial_sort_impl< std::vector<int> >();
test_partial_sort_impl< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.partial_sort" );
test->add( BOOST_TEST_CASE( &boost::test_partial_sort ) );
return test;
}

View File

@@ -0,0 +1,135 @@
// Copyright Neil Groves 2009. 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/algorithm/partition.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include "../test_driver/range_return_test_driver.hpp"
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost_range_test_algorithm_partition
{
struct equal_to_5
{
typedef bool result_type;
typedef int argument_type;
bool operator()(int x) const { return x == 5; }
};
// test the 'partition' algorithm
template<class UnaryPredicate>
class partition_test_policy
{
public:
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
const Container old_cont(cont);
Container cont2(old_cont);
iter_t result = boost::partition(cont, UnaryPredicate());
boost::partition(cont2, UnaryPredicate());
cont2 = old_cont;
boost::partition(
boost::make_iterator_range(cont2), UnaryPredicate());
BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
cont2.begin(), cont2.end() );
return result;
}
UnaryPredicate pred() const { return UnaryPredicate(); }
template< boost::range_return_value return_type >
struct test_range
{
template< class Container, class Policy >
BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator()(Policy& policy, Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
const Container old_cont(cont);
Container cont2(old_cont);
result_t result = boost::partition<return_type>(cont, policy.pred());
// Test that operation a temporary created by using
// make_iterator_range.
boost::partition<return_type>(
boost::make_iterator_range(cont2), policy.pred());
BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
cont2.begin(), cont2.end() );
return result;
}
};
template< class Container >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container& cont)
{
return std::partition(cont.begin(), cont.end(), UnaryPredicate());
}
};
template<class Container>
void test_partition_impl()
{
using namespace boost::assign;
boost::range_test::range_return_test_driver test_driver;
partition_test_policy< equal_to_5 > policy;
Container cont;
test_driver(cont, policy);
cont.clear();
cont += 1;
test_driver(cont, policy);
cont.clear();
cont += 1,2,2,2,2,2,3,4,5,6,7,8,9;
test_driver(cont, policy);
cont.clear();
cont += 1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,5,6,7,8,9;
test_driver(cont, policy);
}
void test_partition()
{
test_partition_impl< std::vector<int> >();
test_partition_impl< std::list<int> >();
test_partition_impl< std::deque<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.partition" );
test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_partition::test_partition ) );
return test;
}

View File

@@ -0,0 +1,124 @@
// Copyright Neil Groves 2009. 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/assign.hpp>
#include <boost/range/algorithm/permutation.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <algorithm>
#include <deque>
#include <functional>
#include <list>
#include <vector>
namespace boost
{
namespace
{
template<class Container>
void test_prev_permutation_impl(const Container& cont)
{
Container reference(cont);
Container test(cont);
Container test2(cont);
const bool reference_ret
= std::prev_permutation(reference.begin(), reference.end());
const bool test_ret = boost::prev_permutation(test);
BOOST_CHECK( reference_ret == test_ret );
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
BOOST_CHECK( test_ret == boost::prev_permutation(
boost::make_iterator_range(test2)) );
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test2.begin(), test2.end()
);
}
template<class Container, class BinaryPredicate>
void test_prev_permutation_pred_impl(const Container& cont,
BinaryPredicate pred)
{
Container reference(cont);
Container test(cont);
Container test2(cont);
const bool reference_ret
= std::prev_permutation(reference.begin(), reference.end(),
pred);
const bool test_ret = boost::prev_permutation(test, pred);
BOOST_CHECK( reference_ret == test_ret );
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test.begin(), test.end()
);
BOOST_CHECK( test_ret == boost::prev_permutation(
boost::make_iterator_range(test2), pred) );
BOOST_CHECK_EQUAL_COLLECTIONS(
reference.begin(), reference.end(),
test2.begin(), test2.end()
);
}
template<class Container>
void test_prev_permutation_(const Container& cont)
{
test_prev_permutation_impl(cont);
test_prev_permutation_pred_impl(cont, std::less<int>());
test_prev_permutation_pred_impl(cont, std::greater<int>());
}
template<class Container>
void run_tests()
{
using namespace boost::assign;
Container cont;
test_prev_permutation_(cont);
cont.clear();
cont += 1;
test_prev_permutation_(cont);
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test_prev_permutation_(cont);
}
void test_prev_permutation()
{
run_tests< std::vector<int> >();
run_tests< std::list<int> >();
run_tests< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.prev_permutation" );
test->add( BOOST_TEST_CASE( &boost::test_prev_permutation ) );
return test;
}

View File

@@ -0,0 +1,197 @@
// Copyright Neil Groves 2009. 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/algorithm/random_shuffle.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include "../test_function/counted_function.hpp"
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template<class Int>
class counted_generator
: private range_test_function::counted_function
{
public:
typedef Int result_type;
typedef Int argument_type;
using range_test_function::counted_function::invocation_count;
result_type operator()(argument_type modulo_value)
{
invoked();
return static_cast<result_type>(std::rand() % modulo_value);
}
};
template<class Container>
bool test_shuffle_result(
const Container& old_cont,
const Container& new_cont
)
{
typedef BOOST_DEDUCED_TYPENAME range_iterator<const Container>::type iterator_t;
// The size must remain equal
BOOST_CHECK_EQUAL( old_cont.size(), new_cont.size() );
if (old_cont.size() != new_cont.size())
return false;
if (new_cont.size() < 2)
{
BOOST_CHECK_EQUAL_COLLECTIONS(
old_cont.begin(), old_cont.end(),
new_cont.begin(), new_cont.end()
);
return std::equal(old_cont.begin(), old_cont.end(),
new_cont.begin());
}
// Elements must only be moved around. This is tested by
// ensuring the count of each element remains the
// same.
bool failed = false;
iterator_t last = old_cont.end();
for (iterator_t it = old_cont.begin(); !failed && (it != last); ++it)
{
const std::size_t old_count
= std::count(old_cont.begin(), old_cont.end(), *it);
const std::size_t new_count
= std::count(new_cont.begin(), new_cont.end(), *it);
BOOST_CHECK_EQUAL( old_count, new_count );
failed = (old_count != new_count);
}
return !failed;
}
template<class Container>
void test_random_shuffle_nogen_impl(Container& cont)
{
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type
iterator_t BOOST_RANGE_UNUSED;
const int MAX_RETRIES = 10000;
bool shuffled = false;
for (int attempt = 0; !shuffled && (attempt < MAX_RETRIES); ++attempt)
{
Container test(cont);
boost::random_shuffle(test);
bool ok = test_shuffle_result(cont, test);
if (!ok)
break;
// Since the counts are equal, then if they are
// not equal the contents must have been shuffled
if (cont.size() == test.size()
&& !std::equal(cont.begin(), cont.end(), test.begin()))
{
shuffled = true;
}
// Verify that the shuffle can be performed on a
// temporary range
Container test2(cont);
boost::random_shuffle(boost::make_iterator_range(test2));
ok = test_shuffle_result(cont, test2);
if (!ok)
break;
}
}
template<class RandomGenerator, class Container>
void test_random_shuffle_gen_impl(Container& cont)
{
RandomGenerator gen;
Container old_cont(cont);
boost::random_shuffle(cont, gen);
test_shuffle_result(cont, old_cont);
if (cont.size() > 2)
{
BOOST_CHECK( gen.invocation_count() > 0 );
}
// Test that random shuffle works when
// passed a temporary range
RandomGenerator gen2;
Container cont2(old_cont);
boost::random_shuffle(boost::make_iterator_range(cont2), gen2);
test_shuffle_result(cont2, old_cont);
if (cont2.size() > 2)
{
BOOST_CHECK( gen2.invocation_count() > 0 );
}
}
template<class Container>
void test_random_shuffle_impl(Container& cont)
{
Container old_cont(cont);
boost::random_shuffle(cont);
test_shuffle_result(cont, old_cont);
}
template<class Container>
void test_random_shuffle_impl()
{
using namespace boost::assign;
typedef counted_generator<
BOOST_DEDUCED_TYPENAME range_difference<Container>::type > generator_t;
Container cont;
test_random_shuffle_nogen_impl(cont);
test_random_shuffle_gen_impl<generator_t>(cont);
cont.clear();
cont += 1;
test_random_shuffle_nogen_impl(cont);
test_random_shuffle_gen_impl<generator_t>(cont);
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test_random_shuffle_nogen_impl(cont);
test_random_shuffle_gen_impl<generator_t>(cont);
}
void test_random_shuffle()
{
test_random_shuffle_impl< std::vector<int> >();
test_random_shuffle_impl< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.random_shuffle" );
test->add( BOOST_TEST_CASE( &boost::test_random_shuffle ) );
return test;
}

View File

@@ -0,0 +1,100 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/remove.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template< class Container, class Value >
void test_remove_impl( const Container& c, Value to_remove )
{
Container reference(c);
typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator_t;
iterator_t reference_it
= std::remove(reference.begin(), reference.end(), to_remove);
Container test(c);
iterator_t test_it = boost::remove(test, to_remove);
BOOST_CHECK_EQUAL( std::distance(test.begin(), test_it),
std::distance(reference.begin(), reference_it) );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
Container test2(c);
iterator_t test_it2 = boost::remove(test2, to_remove);
BOOST_CHECK_EQUAL( std::distance(test2.begin(), test_it2),
std::distance(reference.begin(), reference_it) );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test2.begin(), test2.end() );
}
template< class Container >
void test_remove_impl()
{
using namespace boost::assign;
Container cont;
test_remove_impl(cont, 0);
cont.clear();
cont += 1;
test_remove_impl(cont, 0);
test_remove_impl(cont, 1);
cont.clear();
cont += 1,1,1,1,1;
test_remove_impl(cont, 0);
test_remove_impl(cont, 1);
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test_remove_impl(cont, 1);
test_remove_impl(cont, 9);
test_remove_impl(cont, 4);
}
void test_remove()
{
test_remove_impl< std::vector<int> >();
test_remove_impl< std::list<int> >();
test_remove_impl< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.remove" );
test->add( BOOST_TEST_CASE( &boost::test_remove ) );
return test;
}

View File

@@ -0,0 +1,107 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/remove_copy.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace
{
template<typename Iterator, typename Value>
void test_append(Iterator target, Value value)
{
*target++ = value;
}
template< class Container, class Value >
void test_remove_copy_impl( const Container& c, Value to_remove )
{
typedef typename boost::range_value<Container>::type value_type;
std::vector<value_type> reference;
typedef BOOST_DEDUCED_TYPENAME std::vector<value_type>::iterator
iterator_t BOOST_RANGE_UNUSED;
test_append(
std::remove_copy(c.begin(), c.end(),
std::back_inserter(reference), to_remove),
to_remove);
std::vector<value_type> test;
test_append(
boost::remove_copy(c, std::back_inserter(test), to_remove),
to_remove);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
std::vector<value_type> test2;
test_append(
boost::remove_copy(boost::make_iterator_range(c),
std::back_inserter(test2), to_remove),
to_remove);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test2.begin(), test2.end() );
}
template< class Container >
void test_remove_copy_impl()
{
using namespace boost::assign;
Container cont;
test_remove_copy_impl(cont, 0);
cont.clear();
cont += 1;
test_remove_copy_impl(cont, 0);
test_remove_copy_impl(cont, 1);
cont.clear();
cont += 1,1,1,1,1;
test_remove_copy_impl(cont, 0);
test_remove_copy_impl(cont, 1);
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test_remove_copy_impl(cont, 1);
test_remove_copy_impl(cont, 9);
test_remove_copy_impl(cont, 4);
}
void test_remove_copy()
{
test_remove_copy_impl< std::vector<int> >();
test_remove_copy_impl< std::list<int> >();
test_remove_copy_impl< std::deque<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.remove_copy" );
test->add( BOOST_TEST_CASE( &test_remove_copy ) );
return test;
}

View File

@@ -0,0 +1,115 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/remove_copy_if.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/bind/bind.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace
{
template< class Iterator, class Value >
void test_append(Iterator target, Value value)
{
*target++ = value;
}
template< class Container, class UnaryPredicate >
void test_remove_copy_if_impl( const Container& c, UnaryPredicate pred )
{
typedef BOOST_DEDUCED_TYPENAME boost::range_value<const Container>::type value_type;
std::vector<value_type> reference;
test_append(
std::remove_copy_if(c.begin(), c.end(), std::back_inserter(reference), pred),
value_type()
);
std::vector<value_type> test;
test_append(
boost::remove_copy_if(c, std::back_inserter(test), pred),
value_type()
);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
std::vector<value_type> test2;
test_append(
boost::remove_copy_if(boost::make_iterator_range(c),
std::back_inserter(test2), pred),
value_type()
);
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test2.begin(), test2.end() );
}
template< class Container >
void test_remove_copy_if_( const Container& c, int to_remove )
{
using namespace boost::placeholders;
test_remove_copy_if_impl(c, boost::bind(std::equal_to<int>(), _1, to_remove));
test_remove_copy_if_impl(c, boost::bind(std::not_equal_to<int>(), _1, to_remove));
}
template< class Container >
void test_remove_copy_if_impl()
{
using namespace boost::assign;
Container cont;
test_remove_copy_if_(cont, 0);
cont.clear();
cont += 1;
test_remove_copy_if_(cont, 0);
test_remove_copy_if_(cont, 1);
cont.clear();
cont += 1,1,1,1,1;
test_remove_copy_if_(cont, 0);
test_remove_copy_if_(cont, 1);
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test_remove_copy_if_(cont, 1);
test_remove_copy_if_(cont, 9);
test_remove_copy_if_(cont, 4);
}
inline void test_remove_copy_if()
{
test_remove_copy_if_impl< std::vector<int> >();
test_remove_copy_if_impl< std::list<int> >();
test_remove_copy_if_impl< std::deque<int> >();
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.remove_copy_if" );
test->add( BOOST_TEST_CASE( &test_remove_copy_if ) );
return test;
}

View File

@@ -0,0 +1,111 @@
// Boost.Range library
//
// Copyright Neil Groves 2009. 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/algorithm/remove_if.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/bind/bind.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>
namespace boost
{
namespace
{
template< class Container, class UnaryPredicate >
void test_remove_if_impl( const Container& c, UnaryPredicate pred )
{
Container reference(c);
typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator_t;
iterator_t reference_it
= std::remove_if(reference.begin(), reference.end(), pred);
Container test(c);
iterator_t test_it = boost::remove_if(test, pred);
BOOST_CHECK_EQUAL( std::distance(test.begin(), test_it),
std::distance(reference.begin(), reference_it) );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test.begin(), test.end() );
Container test2(c);
iterator_t test_it2 = boost::remove_if(
boost::make_iterator_range(test2), pred);
BOOST_CHECK_EQUAL( std::distance(test2.begin(), test_it2),
std::distance(reference.begin(), reference_it) );
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
test2.begin(), test2.end() );
}
template< class Container >
void test_remove_if_( const Container& c, int to_remove )
{
using namespace boost::placeholders;
test_remove_if_impl(c, boost::bind(std::equal_to<int>(), _1, to_remove));
test_remove_if_impl(c, boost::bind(std::not_equal_to<int>(), _1, to_remove));
}
template< class Container >
void test_remove_if_impl()
{
using namespace boost::assign;
Container cont;
test_remove_if_(cont, 0);
cont.clear();
cont += 1;
test_remove_if_(cont, 0);
test_remove_if_(cont, 1);
cont.clear();
cont += 1,1,1,1,1;
test_remove_if_(cont, 0);
test_remove_if_(cont, 1);
cont.clear();
cont += 1,2,3,4,5,6,7,8,9;
test_remove_if_(cont, 1);
test_remove_if_(cont, 9);
test_remove_if_(cont, 4);
}
inline void test_remove_if()
{
test_remove_if_impl< std::vector<int> >();
test_remove_if_impl< std::list<int> >();
test_remove_if_impl< std::deque<int> >();
}
}
}
boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
boost::unit_test::test_suite* test
= BOOST_TEST_SUITE( "RangeTestSuite.algorithm.remove_if" );
test->add( BOOST_TEST_CASE( &boost::test_remove_if ) );
return test;
}

Some files were not shown because too many files have changed in this diff Show More