diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/range | |
parent | Initial commit. (diff) | |
download | ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/range')
206 files changed, 22602 insertions, 0 deletions
diff --git a/src/boost/libs/range/index.html b/src/boost/libs/range/index.html new file mode 100644 index 00000000..29b7f42c --- /dev/null +++ b/src/boost/libs/range/index.html @@ -0,0 +1,16 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> +<head> + <title>Boost.Range Documentation</title> + <meta http-equiv="Content-Type" content="test/html; charset=us-ascii" /> + <meta http-equiv="refresh" content="0; URL=doc/html/index.html" /> +</head> + +<body> + Automatic redirection failed, please go to <a href="doc/html/index.html">doc/html/index.html</a> +</body> +</html> +<!-- Copyright Neil Groves 2010. Distributed under 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) --> diff --git a/src/boost/libs/range/meta/libraries.json b/src/boost/libs/range/meta/libraries.json new file mode 100644 index 00000000..9e2be209 --- /dev/null +++ b/src/boost/libs/range/meta/libraries.json @@ -0,0 +1,16 @@ +{ + "key": "range", + "name": "Range", + "authors": [ + "Niel Groves", + "Thorsten Ottosen" + ], + "description": "A new infrastructure for generic algorithms that builds on top of the new iterator concepts.", + "category": [ + "Algorithms" + ], + "maintainers": [ + "Neil Groves <neilgroves -at- googlemail.com>", + "Nathan Ridge <zeratul976 -at- hotmail.com>" + ] +} diff --git a/src/boost/libs/range/test/Jamfile.v2 b/src/boost/libs/range/test/Jamfile.v2 new file mode 100644 index 00000000..b1959269 --- /dev/null +++ b/src/boost/libs/range/test/Jamfile.v2 @@ -0,0 +1,225 @@ +# 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/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 ; diff --git a/src/boost/libs/range/test/adaptor_test/adjacent_filtered.cpp b/src/boost/libs/range/test/adaptor_test/adjacent_filtered.cpp new file mode 100644 index 00000000..48025abf --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/adjacent_filtered.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/adjacent_filtered_example.cpp b/src/boost/libs/range/test/adaptor_test/adjacent_filtered_example.cpp new file mode 100644 index 00000000..83f7a8ac --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/adjacent_filtered_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/chained.cpp b/src/boost/libs/range/test/adaptor_test/chained.cpp new file mode 100644 index 00000000..1b756c9c --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/chained.cpp @@ -0,0 +1,117 @@ +// 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.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; + + 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; +} diff --git a/src/boost/libs/range/test/adaptor_test/copied.cpp b/src/boost/libs/range/test/adaptor_test/copied.cpp new file mode 100644 index 00000000..93f1cb79 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/copied.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/copied_example.cpp b/src/boost/libs/range/test/adaptor_test/copied_example.cpp new file mode 100644 index 00000000..c1d0e31d --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/copied_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/filtered.cpp b/src/boost/libs/range/test/adaptor_test/filtered.cpp new file mode 100644 index 00000000..be348726 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/filtered.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/filtered_example.cpp b/src/boost/libs/range/test/adaptor_test/filtered_example.cpp new file mode 100644 index 00000000..e16d0af6 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/filtered_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/formatted.cpp b/src/boost/libs/range/test/adaptor_test/formatted.cpp new file mode 100644 index 00000000..b6c1783c --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/formatted.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/formatted_example.cpp b/src/boost/libs/range/test/adaptor_test/formatted_example.cpp new file mode 100644 index 00000000..838a6712 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/formatted_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/indexed.cpp b/src/boost/libs/range/test/adaptor_test/indexed.cpp new file mode 100644 index 00000000..f4085be0 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/indexed.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/indexed_example.cpp b/src/boost/libs/range/test/adaptor_test/indexed_example.cpp new file mode 100644 index 00000000..c65e62e1 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/indexed_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/indirected.cpp b/src/boost/libs/range/test/adaptor_test/indirected.cpp new file mode 100644 index 00000000..fe3ebdfa --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/indirected.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/indirected_example.cpp b/src/boost/libs/range/test/adaptor_test/indirected_example.cpp new file mode 100644 index 00000000..8b538b5a --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/indirected_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/map.cpp b/src/boost/libs/range/test/adaptor_test/map.cpp new file mode 100644 index 00000000..615b4677 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/map.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/map_keys_example.cpp b/src/boost/libs/range/test/adaptor_test/map_keys_example.cpp new file mode 100644 index 00000000..99f8505c --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/map_keys_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/map_values_example.cpp b/src/boost/libs/range/test/adaptor_test/map_values_example.cpp new file mode 100644 index 00000000..bfa533fd --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/map_values_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/ref_unwrapped.cpp b/src/boost/libs/range/test/adaptor_test/ref_unwrapped.cpp new file mode 100644 index 00000000..c476b741 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/ref_unwrapped.cpp @@ -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 diff --git a/src/boost/libs/range/test/adaptor_test/ref_unwrapped_example.cpp b/src/boost/libs/range/test/adaptor_test/ref_unwrapped_example.cpp new file mode 100644 index 00000000..ab3e4016 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/ref_unwrapped_example.cpp @@ -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 +//-> +} +//] diff --git a/src/boost/libs/range/test/adaptor_test/replaced.cpp b/src/boost/libs/range/test/adaptor_test/replaced.cpp new file mode 100644 index 00000000..d3eac813 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/replaced.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/replaced_example.cpp b/src/boost/libs/range/test/adaptor_test/replaced_example.cpp new file mode 100644 index 00000000..8e1f1145 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/replaced_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/replaced_if.cpp b/src/boost/libs/range/test/adaptor_test/replaced_if.cpp new file mode 100644 index 00000000..0bf227f3 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/replaced_if.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/replaced_if_example.cpp b/src/boost/libs/range/test/adaptor_test/replaced_if_example.cpp new file mode 100644 index 00000000..05b5e780 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/replaced_if_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/reversed.cpp b/src/boost/libs/range/test/adaptor_test/reversed.cpp new file mode 100644 index 00000000..6663b368 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/reversed.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/reversed_example.cpp b/src/boost/libs/range/test/adaptor_test/reversed_example.cpp new file mode 100644 index 00000000..585108fc --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/reversed_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/sliced.cpp b/src/boost/libs/range/test/adaptor_test/sliced.cpp new file mode 100644 index 00000000..f2221f66 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/sliced.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/sliced_example.cpp b/src/boost/libs/range/test/adaptor_test/sliced_example.cpp new file mode 100644 index 00000000..2b156910 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/sliced_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/strided.cpp b/src/boost/libs/range/test/adaptor_test/strided.cpp new file mode 100644 index 00000000..46c16fa9 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/strided.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/strided2.cpp b/src/boost/libs/range/test/adaptor_test/strided2.cpp new file mode 100644 index 00000000..4ac91f50 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/strided2.cpp @@ -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(×_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; +} diff --git a/src/boost/libs/range/test/adaptor_test/strided_example.cpp b/src/boost/libs/range/test/adaptor_test/strided_example.cpp new file mode 100644 index 00000000..b1f8b424 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/strided_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/ticket_6742_transformed_c4789_warning.cpp b/src/boost/libs/range/test/adaptor_test/ticket_6742_transformed_c4789_warning.cpp new file mode 100644 index 00000000..fdd71180 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/ticket_6742_transformed_c4789_warning.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/ticket_8676_sliced_transformed.cpp b/src/boost/libs/range/test/adaptor_test/ticket_8676_sliced_transformed.cpp new file mode 100644 index 00000000..da0125ec --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/ticket_8676_sliced_transformed.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/ticket_9519_strided_reversed.cpp b/src/boost/libs/range/test/adaptor_test/ticket_9519_strided_reversed.cpp new file mode 100644 index 00000000..0c915981 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/ticket_9519_strided_reversed.cpp @@ -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; +} + diff --git a/src/boost/libs/range/test/adaptor_test/tokenized.cpp b/src/boost/libs/range/test/adaptor_test/tokenized.cpp new file mode 100644 index 00000000..8180747c --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/tokenized.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/tokenized_example.cpp b/src/boost/libs/range/test/adaptor_test/tokenized_example.cpp new file mode 100644 index 00000000..5f59bb16 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/tokenized_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/transformed.cpp b/src/boost/libs/range/test/adaptor_test/transformed.cpp new file mode 100644 index 00000000..10f6a0cd --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/transformed.cpp @@ -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/adaptor/transformed.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/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; + + 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; +} diff --git a/src/boost/libs/range/test/adaptor_test/transformed_example.cpp b/src/boost/libs/range/test/adaptor_test/transformed_example.cpp new file mode 100644 index 00000000..ff4a689a --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/transformed_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/type_erased.cpp b/src/boost/libs/range/test/adaptor_test/type_erased.cpp new file mode 100644 index 00000000..edea1c46 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased.cpp @@ -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; +} + diff --git a/src/boost/libs/range/test/adaptor_test/type_erased_abstract.cpp b/src/boost/libs/range/test/adaptor_test/type_erased_abstract.cpp new file mode 100644 index 00000000..dd548905 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased_abstract.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/type_erased_bidirectional.cpp b/src/boost/libs/range/test/adaptor_test/type_erased_bidirectional.cpp new file mode 100644 index 00000000..3dc86fea --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased_bidirectional.cpp @@ -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; +} + diff --git a/src/boost/libs/range/test/adaptor_test/type_erased_brackets.cpp b/src/boost/libs/range/test/adaptor_test/type_erased_brackets.cpp new file mode 100644 index 00000000..9d5c7dda --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased_brackets.cpp @@ -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; +} + diff --git a/src/boost/libs/range/test/adaptor_test/type_erased_example.cpp b/src/boost/libs/range/test/adaptor_test/type_erased_example.cpp new file mode 100644 index 00000000..f8416ae0 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/type_erased_forward.cpp b/src/boost/libs/range/test/adaptor_test/type_erased_forward.cpp new file mode 100644 index 00000000..7f6540f7 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased_forward.cpp @@ -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; +} + diff --git a/src/boost/libs/range/test/adaptor_test/type_erased_mix_values.cpp b/src/boost/libs/range/test/adaptor_test/type_erased_mix_values.cpp new file mode 100644 index 00000000..e91644ce --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased_mix_values.cpp @@ -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; +} + diff --git a/src/boost/libs/range/test/adaptor_test/type_erased_random_access.cpp b/src/boost/libs/range/test/adaptor_test/type_erased_random_access.cpp new file mode 100644 index 00000000..39cf1c6e --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased_random_access.cpp @@ -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; +} + diff --git a/src/boost/libs/range/test/adaptor_test/type_erased_single_pass.cpp b/src/boost/libs/range/test/adaptor_test/type_erased_single_pass.cpp new file mode 100644 index 00000000..ad0c4ae1 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased_single_pass.cpp @@ -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; +} + diff --git a/src/boost/libs/range/test/adaptor_test/type_erased_test.hpp b/src/boost/libs/range/test/adaptor_test/type_erased_test.hpp new file mode 100644 index 00000000..9a42e81d --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased_test.hpp @@ -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 diff --git a/src/boost/libs/range/test/adaptor_test/type_erased_tparam_conv.cpp b/src/boost/libs/range/test/adaptor_test/type_erased_tparam_conv.cpp new file mode 100644 index 00000000..e235ab30 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/type_erased_tparam_conv.cpp @@ -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; +} + diff --git a/src/boost/libs/range/test/adaptor_test/uniqued.cpp b/src/boost/libs/range/test/adaptor_test/uniqued.cpp new file mode 100644 index 00000000..fdf5454a --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/uniqued.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptor_test/uniqued_example.cpp b/src/boost/libs/range/test/adaptor_test/uniqued_example.cpp new file mode 100644 index 00000000..cf1407a7 --- /dev/null +++ b/src/boost/libs/range/test/adaptor_test/uniqued_example.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/adaptors.cpp b/src/boost/libs/range/test/adaptors.cpp new file mode 100644 index 00000000..ea0f5036 --- /dev/null +++ b/src/boost/libs/range/test/adaptors.cpp @@ -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; +} + + diff --git a/src/boost/libs/range/test/adl_conformance.cpp b/src/boost/libs/range/test/adl_conformance.cpp new file mode 100644 index 00000000..8bae491b --- /dev/null +++ b/src/boost/libs/range/test/adl_conformance.cpp @@ -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(__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; +} + + diff --git a/src/boost/libs/range/test/adl_conformance_no_using.cpp b/src/boost/libs/range/test/adl_conformance_no_using.cpp new file mode 100644 index 00000000..82c1cd2e --- /dev/null +++ b/src/boost/libs/range/test/adl_conformance_no_using.cpp @@ -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 ); +} diff --git a/src/boost/libs/range/test/algorithm.cpp b/src/boost/libs/range/test/algorithm.cpp new file mode 100644 index 00000000..e945d421 --- /dev/null +++ b/src/boost/libs/range/test/algorithm.cpp @@ -0,0 +1,479 @@ +// 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/bind.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; +} + diff --git a/src/boost/libs/range/test/algorithm_example.cpp b/src/boost/libs/range/test/algorithm_example.cpp new file mode 100644 index 00000000..80c78754 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_example.cpp @@ -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(__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; +} + + + diff --git a/src/boost/libs/range/test/algorithm_ext_test/copy_n.cpp b/src/boost/libs/range/test/algorithm_ext_test/copy_n.cpp new file mode 100644 index 00000000..854962fe --- /dev/null +++ b/src/boost/libs/range/test/algorithm_ext_test/copy_n.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_ext_test/erase.cpp b/src/boost/libs/range/test/algorithm_ext_test/erase.cpp new file mode 100644 index 00000000..3bdf2dab --- /dev/null +++ b/src/boost/libs/range/test/algorithm_ext_test/erase.cpp @@ -0,0 +1,128 @@ +// 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> >(); + } + +} + +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 ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_ext_test/for_each_ext.cpp b/src/boost/libs/range/test/algorithm_ext_test/for_each_ext.cpp new file mode 100644 index 00000000..9df16c59 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_ext_test/for_each_ext.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_ext_test/insert.cpp b/src/boost/libs/range/test/algorithm_ext_test/insert.cpp new file mode 100644 index 00000000..ff1f706a --- /dev/null +++ b/src/boost/libs/range/test/algorithm_ext_test/insert.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_ext_test/iota.cpp b/src/boost/libs/range/test/algorithm_ext_test/iota.cpp new file mode 100644 index 00000000..64d9b0e7 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_ext_test/iota.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_ext_test/is_sorted.cpp b/src/boost/libs/range/test/algorithm_ext_test/is_sorted.cpp new file mode 100644 index 00000000..bddc5f89 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_ext_test/is_sorted.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_ext_test/overwrite.cpp b/src/boost/libs/range/test/algorithm_ext_test/overwrite.cpp new file mode 100644 index 00000000..0d8604a3 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_ext_test/overwrite.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_ext_test/push_back.cpp b/src/boost/libs/range/test/algorithm_ext_test/push_back.cpp new file mode 100644 index 00000000..7e9d539f --- /dev/null +++ b/src/boost/libs/range/test/algorithm_ext_test/push_back.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_ext_test/push_front.cpp b/src/boost/libs/range/test/algorithm_ext_test/push_front.cpp new file mode 100644 index 00000000..071a7cec --- /dev/null +++ b/src/boost/libs/range/test/algorithm_ext_test/push_front.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/adjacent_find.cpp b/src/boost/libs/range/test/algorithm_test/adjacent_find.cpp new file mode 100644 index 00000000..63b65e81 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/adjacent_find.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/binary_search.cpp b/src/boost/libs/range/test/algorithm_test/binary_search.cpp new file mode 100644 index 00000000..2646c2e2 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/binary_search.cpp @@ -0,0 +1,126 @@ +// 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 <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/copy.cpp b/src/boost/libs/range/test/algorithm_test/copy.cpp new file mode 100644 index 00000000..4b9fcc2f --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/copy.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/copy_backward.cpp b/src/boost/libs/range/test/algorithm_test/copy_backward.cpp new file mode 100644 index 00000000..4879c287 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/copy_backward.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/copy_n.cpp b/src/boost/libs/range/test/algorithm_test/copy_n.cpp new file mode 100644 index 00000000..230eb032 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/copy_n.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/count.cpp b/src/boost/libs/range/test/algorithm_test/count.cpp new file mode 100644 index 00000000..90b20903 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/count.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/count_if.cpp b/src/boost/libs/range/test/algorithm_test/count_if.cpp new file mode 100644 index 00000000..e028741c --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/count_if.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/equal.cpp b/src/boost/libs/range/test/algorithm_test/equal.cpp new file mode 100644 index 00000000..243f0645 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/equal.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/equal_range.cpp b/src/boost/libs/range/test/algorithm_test/equal_range.cpp new file mode 100644 index 00000000..612f1a47 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/equal_range.cpp @@ -0,0 +1,181 @@ +// 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 <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/fill.cpp b/src/boost/libs/range/test/algorithm_test/fill.cpp new file mode 100644 index 00000000..2f975c4c --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/fill.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/find.cpp b/src/boost/libs/range/test/algorithm_test/find.cpp new file mode 100644 index 00000000..02c9f717 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/find.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/find_end.cpp b/src/boost/libs/range/test/algorithm_test/find_end.cpp new file mode 100644 index 00000000..b4d77a08 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/find_end.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/find_first_of.cpp b/src/boost/libs/range/test/algorithm_test/find_first_of.cpp new file mode 100644 index 00000000..296b8fce --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/find_first_of.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/find_if.cpp b/src/boost/libs/range/test/algorithm_test/find_if.cpp new file mode 100644 index 00000000..3ab22c93 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/find_if.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/for_each.cpp b/src/boost/libs/range/test/algorithm_test/for_each.cpp new file mode 100644 index 00000000..701d676c --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/for_each.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/generate.cpp b/src/boost/libs/range/test/algorithm_test/generate.cpp new file mode 100644 index 00000000..d8fc0e6a --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/generate.cpp @@ -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/algorithm/generate.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/heap.cpp b/src/boost/libs/range/test/algorithm_test/heap.cpp new file mode 100644 index 00000000..74b7fa34 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/heap.cpp @@ -0,0 +1,145 @@ +// 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 <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/includes.cpp b/src/boost/libs/range/test/algorithm_test/includes.cpp new file mode 100644 index 00000000..89775329 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/includes.cpp @@ -0,0 +1,165 @@ +// 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 <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/inplace_merge.cpp b/src/boost/libs/range/test/algorithm_test/inplace_merge.cpp new file mode 100644 index 00000000..948e95ef --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/inplace_merge.cpp @@ -0,0 +1,167 @@ +// 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 <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/lexicographical_compare.cpp b/src/boost/libs/range/test/algorithm_test/lexicographical_compare.cpp new file mode 100644 index 00000000..f724bd1e --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/lexicographical_compare.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/lower_bound.cpp b/src/boost/libs/range/test/algorithm_test/lower_bound.cpp new file mode 100644 index 00000000..2a120a48 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/lower_bound.cpp @@ -0,0 +1,181 @@ +// 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/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/max_element.cpp b/src/boost/libs/range/test/algorithm_test/max_element.cpp new file mode 100644 index 00000000..d4e87d5e --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/max_element.cpp @@ -0,0 +1,165 @@ +// 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/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/merge.cpp b/src/boost/libs/range/test/algorithm_test/merge.cpp new file mode 100644 index 00000000..50387821 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/merge.cpp @@ -0,0 +1,237 @@ +// 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 <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/min_element.cpp b/src/boost/libs/range/test/algorithm_test/min_element.cpp new file mode 100644 index 00000000..bb92d2c1 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/min_element.cpp @@ -0,0 +1,163 @@ +// 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/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/mismatch.cpp b/src/boost/libs/range/test/algorithm_test/mismatch.cpp new file mode 100644 index 00000000..407b5fcb --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/mismatch.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/next_permutation.cpp b/src/boost/libs/range/test/algorithm_test/next_permutation.cpp new file mode 100644 index 00000000..ee1c3716 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/next_permutation.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/nth_element.cpp b/src/boost/libs/range/test/algorithm_test/nth_element.cpp new file mode 100644 index 00000000..df241e9b --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/nth_element.cpp @@ -0,0 +1,175 @@ +// 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 <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/partial_sort.cpp b/src/boost/libs/range/test/algorithm_test/partial_sort.cpp new file mode 100644 index 00000000..c13f7f1a --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/partial_sort.cpp @@ -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/algorithm/partial_sort.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/partition.cpp b/src/boost/libs/range/test/algorithm_test/partition.cpp new file mode 100644 index 00000000..22aefd68 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/partition.cpp @@ -0,0 +1,136 @@ +// 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 <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/prev_permutation.cpp b/src/boost/libs/range/test/algorithm_test/prev_permutation.cpp new file mode 100644 index 00000000..a4adc7b3 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/prev_permutation.cpp @@ -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; +} diff --git a/src/boost/libs/range/test/algorithm_test/random_shuffle.cpp b/src/boost/libs/range/test/algorithm_test/random_shuffle.cpp new file mode 100644 index 00000000..71915ee8 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/random_shuffle.cpp @@ -0,0 +1,198 @@ +// 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 <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/remove.cpp b/src/boost/libs/range/test/algorithm_test/remove.cpp new file mode 100644 index 00000000..3e4ab16b --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/remove.cpp @@ -0,0 +1,101 @@ +// 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 <boost/bind.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; +} diff --git a/src/boost/libs/range/test/algorithm_test/remove_copy.cpp b/src/boost/libs/range/test/algorithm_test/remove_copy.cpp new file mode 100644 index 00000000..b3eb8e22 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/remove_copy.cpp @@ -0,0 +1,108 @@ +// 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 <boost/bind.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; +} + diff --git a/src/boost/libs/range/test/algorithm_test/remove_copy_if.cpp b/src/boost/libs/range/test/algorithm_test/remove_copy_if.cpp new file mode 100644 index 00000000..c269c2a6 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/remove_copy_if.cpp @@ -0,0 +1,113 @@ +// 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.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 ) + { + 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; +} diff --git a/src/boost/libs/range/test/algorithm_test/remove_if.cpp b/src/boost/libs/range/test/algorithm_test/remove_if.cpp new file mode 100644 index 00000000..58fc07f2 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/remove_if.cpp @@ -0,0 +1,109 @@ +// 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.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 ) + { + 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; +} diff --git a/src/boost/libs/range/test/algorithm_test/replace.cpp b/src/boost/libs/range/test/algorithm_test/replace.cpp new file mode 100644 index 00000000..356024ff --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/replace.cpp @@ -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/replace.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <algorithm> +#include <list> +#include <deque> +#include <vector> + +namespace boost +{ + namespace + { + template< class Container > + void test_replace_impl(Container& cont) + { + const int what = 2; + const int with_what = 5; + + std::vector<int> reference(cont.begin(), cont.end()); + std::replace(reference.begin(), reference.end(), what, with_what); + + std::vector<int> target(cont.begin(), cont.end()); + boost::replace(target, what, with_what); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + + std::vector<int> target2(cont.begin(), cont.end()); + boost::replace(boost::make_iterator_range(target2), what, + with_what); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target2.begin(), target2.end() ); + + } + + template< class Container > + void test_replace_impl() + { + using namespace boost::assign; + + Container cont; + test_replace_impl(cont); + + cont.clear(); + cont += 1; + test_replace_impl(cont); + + cont.clear(); + cont += 1,2,3,4,5,6,7,8,9; + test_replace_impl(cont); + } + + void test_replace() + { + test_replace_impl< std::vector<int> >(); + test_replace_impl< std::list<int> >(); + test_replace_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.replace" ); + + test->add( BOOST_TEST_CASE( &boost::test_replace ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/replace_copy.cpp b/src/boost/libs/range/test/algorithm_test/replace_copy.cpp new file mode 100644 index 00000000..56298569 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/replace_copy.cpp @@ -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/replace_copy.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.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_replace_copy_impl( const Container& c, Value to_replace ) + { + const Value replace_with = to_replace * 2; + + 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::replace_copy(c.begin(), c.end(), + std::back_inserter(reference), to_replace, replace_with), + to_replace); + + std::vector<value_type> test; + test_append( + boost::replace_copy(c, std::back_inserter(test), to_replace, replace_with), + to_replace); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + std::vector<value_type> test2; + test_append( + boost::replace_copy(boost::make_iterator_range(c), + std::back_inserter(test2), to_replace, + replace_with), + to_replace); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test2.begin(), test2.end() ); + } + + template< class Container > + void test_replace_copy_impl() + { + using namespace boost::assign; + + Container cont; + test_replace_copy_impl(cont, 0); + + cont.clear(); + cont += 1; + test_replace_copy_impl(cont, 0); + test_replace_copy_impl(cont, 1); + + cont.clear(); + cont += 1,1,1,1,1; + test_replace_copy_impl(cont, 0); + test_replace_copy_impl(cont, 1); + + cont.clear(); + cont += 1,2,3,4,5,6,7,8,9; + test_replace_copy_impl(cont, 1); + test_replace_copy_impl(cont, 9); + test_replace_copy_impl(cont, 4); + } + + void test_replace_copy() + { + test_replace_copy_impl< std::vector<int> >(); + test_replace_copy_impl< std::list<int> >(); + test_replace_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.replace_copy" ); + + test->add( BOOST_TEST_CASE( &test_replace_copy ) ); + + return test; +} + diff --git a/src/boost/libs/range/test/algorithm_test/replace_copy_if.cpp b/src/boost/libs/range/test/algorithm_test/replace_copy_if.cpp new file mode 100644 index 00000000..68735477 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/replace_copy_if.cpp @@ -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/replace_copy_if.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/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_replace_copy_if_impl( const Container& c, UnaryPredicate pred ) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_value<const Container>::type value_type; + const value_type replace_with = value_type(); + std::vector<value_type> reference; + + test_append( + std::replace_copy_if(c.begin(), c.end(), std::back_inserter(reference), pred, replace_with), + value_type() + ); + + std::vector<value_type> test; + test_append( + boost::replace_copy_if(c, std::back_inserter(test), pred, replace_with), + value_type() + ); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + std::vector<value_type> test2; + test_append( + boost::replace_copy_if(boost::make_iterator_range(c), + std::back_inserter(test2), pred, + replace_with), + value_type() + ); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test2.begin(), test2.end() ); + } + + template< class Container > + void test_replace_copy_if_( const Container& c, int to_replace ) + { + test_replace_copy_if_impl(c, boost::bind(std::equal_to<int>(), _1, to_replace)); + test_replace_copy_if_impl(c, boost::bind(std::not_equal_to<int>(), _1, to_replace)); + } + + template< class Container > + void test_replace_copy_if_impl() + { + using namespace boost::assign; + + Container cont; + test_replace_copy_if_(cont, 0); + + cont.clear(); + cont += 1; + test_replace_copy_if_(cont, 0); + test_replace_copy_if_(cont, 1); + + cont.clear(); + cont += 1,1,1,1,1; + test_replace_copy_if_(cont, 0); + test_replace_copy_if_(cont, 1); + + cont.clear(); + cont += 1,2,3,4,5,6,7,8,9; + test_replace_copy_if_(cont, 1); + test_replace_copy_if_(cont, 9); + test_replace_copy_if_(cont, 4); + } + + inline void test_replace_copy_if() + { + test_replace_copy_if_impl< std::vector<int> >(); + test_replace_copy_if_impl< std::list<int> >(); + test_replace_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.replace_copy_if" ); + + test->add( BOOST_TEST_CASE( &test_replace_copy_if ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/replace_if.cpp b/src/boost/libs/range/test/algorithm_test/replace_if.cpp new file mode 100644 index 00000000..12d72934 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/replace_if.cpp @@ -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/algorithm/replace_if.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace boost +{ + namespace + { + template< class Container, class UnaryPredicate > + void test_replace_if_impl(Container& cont, UnaryPredicate pred) + { + const int what = 2; + const int with_what = 5; + + std::vector<int> reference(cont.begin(), cont.end()); + std::replace_if(reference.begin(), reference.end(), + boost::bind(pred, _1, what), with_what); + + std::vector<int> target(cont.begin(), cont.end()); + boost::replace_if(target, boost::bind(pred, _1, what), with_what); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + + std::vector<int> target2(cont.begin(), cont.end()); + boost::replace_if(boost::make_iterator_range(target2), + boost::bind(pred, _1, what), with_what); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target2.begin(), target2.end() ); + } + + template< class Container > + void test_replace_if_impl(Container& cont) + { + test_replace_if_impl(cont, std::equal_to<int>()); + test_replace_if_impl(cont, std::not_equal_to<int>()); + } + + template< class Container > + void test_replace_if_impl() + { + using namespace boost::assign; + + Container cont; + test_replace_if_impl(cont); + + cont.clear(); + cont += 1; + test_replace_if_impl(cont); + + cont.clear(); + cont += 1,2,3,4,5,6,7,8,9; + test_replace_if_impl(cont); + } + + void test_replace_if() + { + test_replace_if_impl< std::vector<int> >(); + test_replace_if_impl< std::list<int> >(); + test_replace_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.replace_if" ); + + test->add( BOOST_TEST_CASE( &boost::test_replace_if ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/reverse.cpp b/src/boost/libs/range/test/algorithm_test/reverse.cpp new file mode 100644 index 00000000..3ad63cb0 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/reverse.cpp @@ -0,0 +1,80 @@ +// 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/reverse.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace boost +{ + namespace + { + template<class Container> + void test_reverse_impl(Container& cont) + { + Container reference(cont); + Container test(cont); + Container test2(cont); + + boost::reverse(test); + std::reverse(reference.begin(), reference.end()); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + boost::reverse(boost::make_iterator_range(test2)); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test2.begin(), test2.end() ); + } + + template<class Container> + void test_reverse_impl() + { + using namespace boost::assign; + + Container cont; + test_reverse_impl(cont); + + cont.clear(); + cont += 1; + test_reverse_impl(cont); + + cont.clear(); + cont += 1,2,3,4,5,6,7,8,9; + test_reverse_impl(cont); + } + + void test_reverse() + { + test_reverse_impl< std::vector<int> >(); + test_reverse_impl< std::list<int> >(); + test_reverse_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.reverse" ); + + test->add( BOOST_TEST_CASE( &boost::test_reverse ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/reverse_copy.cpp b/src/boost/libs/range/test/algorithm_test/reverse_copy.cpp new file mode 100644 index 00000000..92ef4855 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/reverse_copy.cpp @@ -0,0 +1,97 @@ +// 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/reverse_copy.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace +{ + template<class OutputIterator, class Value> + void test_append(OutputIterator out, Value value) + { + *out++ = value; + } + + template<class Container> + void test_reverse_copy_impl(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_value<Container>::type value_type; + std::vector<value_type> reference; + std::vector<value_type> test; + + test_append( + std::reverse_copy(cont.begin(), cont.end(), std::back_inserter(reference)), + value_type() + ); + + test_append( + boost::reverse_copy(cont, std::back_inserter(test)), + value_type() + ); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + test.clear(); + + test_append( + boost::reverse_copy(boost::make_iterator_range(cont), + std::back_inserter(test)), + value_type() + ); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + } + + template<class Container> + void test_reverse_copy_impl() + { + using namespace boost::assign; + + Container cont; + test_reverse_copy_impl(cont); + + cont.clear(); + cont += 1; + test_reverse_copy_impl(cont); + + cont.clear(); + cont += 1,2,3,4,5,6,7,8,9; + test_reverse_copy_impl(cont); + } + + void test_reverse_copy() + { + test_reverse_copy_impl< std::vector<int> >(); + test_reverse_copy_impl< std::list<int> >(); + test_reverse_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.reverse_copy" ); + + test->add( BOOST_TEST_CASE( &::test_reverse_copy ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/rotate.cpp b/src/boost/libs/range/test/algorithm_test/rotate.cpp new file mode 100644 index 00000000..b6b7af27 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/rotate.cpp @@ -0,0 +1,107 @@ +// 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/rotate.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace boost +{ + namespace + { + template<class Container, class Iterator> + void test_rotate_impl(Container& cont, Iterator where_it) + { + Container reference(cont); + Container test(cont); + + Iterator reference_where_it = reference.begin(); + std::advance(reference_where_it, + std::distance(cont.begin(), where_it)); + + std::rotate(reference.begin(), reference_where_it, reference.end()); + + Iterator test_where_it = test.begin(); + std::advance(test_where_it, + std::distance(cont.begin(), where_it)); + + boost::rotate(test, test_where_it); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + test = cont; + test_where_it = test.begin(); + std::advance(test_where_it, + std::distance(cont.begin(), where_it)); + + boost::rotate(boost::make_iterator_range(test), test_where_it); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + } + + template<class Container> + void test_rotate_impl(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t; + + iterator_t last = cont.end(); + for (iterator_t it = cont.begin(); it != last; ++it) + { + test_rotate_impl(cont, it); + } + } + + template<class Container> + void test_rotate_impl() + { + using namespace boost::assign; + + Container cont; + test_rotate_impl(cont); + + cont.clear(); + cont += 1; + test_rotate_impl(cont); + + cont.clear(); + cont += 1,2,3,4,5,6,7,8,9; + test_rotate_impl(cont); + } + + void test_rotate() + { + test_rotate_impl< std::vector<int> >(); + test_rotate_impl< std::list<int> >(); + test_rotate_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.rotate" ); + + test->add( BOOST_TEST_CASE( &boost::test_rotate ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/rotate_copy.cpp b/src/boost/libs/range/test/algorithm_test/rotate_copy.cpp new file mode 100644 index 00000000..05aa4d25 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/rotate_copy.cpp @@ -0,0 +1,115 @@ +// 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/rotate_copy.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace +{ + template<class OutputIterator, class Value> + void test_append(OutputIterator target, Value value) + { + *target++ = value; + } + + template<class Container, class Iterator> + void test_rotate_copy_impl(Container& cont, Iterator where_it) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_value<Container>::type + value_type; + + std::vector<value_type> reference; + std::vector<value_type> test; + + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type + iterator_t BOOST_RANGE_UNUSED; + + test_append( + std::rotate_copy(cont.begin(), where_it, cont.end(), + std::back_inserter(reference)), + value_type() + ); + + test_append( + boost::rotate_copy(cont, where_it, std::back_inserter(test)), + value_type() + ); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + test.clear(); + + test_append( + boost::rotate_copy(boost::make_iterator_range(cont), where_it, + std::back_inserter(test)), + value_type() + ); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + } + + template<class Container> + void test_rotate_copy_impl(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iterator_t; + + iterator_t last = cont.end(); + for (iterator_t it = cont.begin(); it != last; ++it) + { + test_rotate_copy_impl(cont, it); + } + } + + template<class Container> + void test_rotate_copy_impl() + { + using namespace boost::assign; + + Container cont; + test_rotate_copy_impl(cont); + + cont.clear(); + cont += 1; + test_rotate_copy_impl(cont); + + cont.clear(); + cont += 1,2,3,4,5,6,7,8,9; + test_rotate_copy_impl(cont); + } + + void test_rotate_copy() + { + test_rotate_copy_impl< std::vector<int> >(); + test_rotate_copy_impl< std::list<int> >(); + test_rotate_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.rotate_copy" ); + + test->add( BOOST_TEST_CASE( &test_rotate_copy ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/search.cpp b/src/boost/libs/range/test/algorithm_test/search.cpp new file mode 100644 index 00000000..91f19bd6 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/search.cpp @@ -0,0 +1,113 @@ +// 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/search.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_search_impl(Container1& cont1, Container2& cont2) + { + typedef BOOST_DEDUCED_TYPENAME Container1::const_iterator const_iterator1_t; + typedef BOOST_DEDUCED_TYPENAME Container1::iterator iterator1_t; + + const Container1& ccont1 = cont1; + const Container2& ccont2 = cont2; + + iterator1_t it = boost::search(cont1, cont2); + BOOST_CHECK( it == boost::search(boost::make_iterator_range(cont1), cont2) ); + BOOST_CHECK( it == boost::search(cont1, boost::make_iterator_range(cont2)) ); + BOOST_CHECK( it == boost::search(boost::make_iterator_range(cont1), + boost::make_iterator_range(cont2)) ); + iterator1_t it2 = boost::search(cont1, ccont2); + BOOST_CHECK( it2 == boost::search(boost::make_iterator_range(cont1), ccont2) ); + BOOST_CHECK( it2 == boost::search(cont1, boost::make_iterator_range(ccont2)) ); + BOOST_CHECK( it2 == boost::search(boost::make_iterator_range(cont1), + boost::make_iterator_range(ccont2)) ); + const_iterator1_t cit = boost::search(ccont1, cont2); + BOOST_CHECK( cit == boost::search(boost::make_iterator_range(ccont1), cont2) ); + BOOST_CHECK( cit == boost::search(ccont1, boost::make_iterator_range(cont2)) ); + BOOST_CHECK( cit == boost::search(boost::make_iterator_range(ccont1), + boost::make_iterator_range(cont2)) ); + const_iterator1_t cit2 = boost::search(ccont1, ccont2); + BOOST_CHECK( cit2 == boost::search(boost::make_iterator_range(ccont1), ccont2) ); + BOOST_CHECK( cit2 == boost::search(ccont1, boost::make_iterator_range(ccont2)) ); + BOOST_CHECK( cit2 == boost::search(boost::make_iterator_range(ccont1), + boost::make_iterator_range(ccont2)) ); + + BOOST_CHECK( it == std::search(cont1.begin(), cont1.end(), cont2.begin(), cont2.end()) ); + BOOST_CHECK( it2 == std::search(cont1.begin(), cont1.end(), ccont2.begin(), ccont2.end()) ); + BOOST_CHECK( cit == std::search(ccont1.begin(), ccont1.end(), cont2.begin(), cont2.end()) ); + BOOST_CHECK( cit2 == std::search(ccont1.begin(), ccont1.end(), ccont2.begin(), ccont2.end()) ); + } + + template< class Container1, class Container2 > + void test_search_impl() + { + using namespace boost::assign; + + Container1 cont1; + Container2 cont2; + + test_search_impl(cont1, cont2); + + cont1 += 1; + test_search_impl(cont1, cont2); + + cont1.clear(); + cont2 += 1; + test_search_impl(cont1, cont2); + + cont1 += 1; + test_search_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 1,2,3,4,5,6,7,8,9; + cont2 += 10,11,12; + test_search_impl(cont1, cont2); + + cont2.clear(); + cont2 += 4,5,6; + test_search_impl(cont1, cont2); + } + + void test_search() + { + test_search_impl< std::list<int>, std::list<int> >(); + test_search_impl< std::vector<int>, std::vector<int> >(); + test_search_impl< std::set<int>, std::set<int> >(); + test_search_impl< std::list<int>, std::vector<int> >(); + test_search_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.search" ); + + test->add( BOOST_TEST_CASE( &boost::test_search ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/search_n.cpp b/src/boost/libs/range/test/algorithm_test/search_n.cpp new file mode 100644 index 00000000..76f5b784 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/search_n.cpp @@ -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/search_n.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 +{ + template<typename ForwardIterator, typename Integer, typename Value> + inline ForwardIterator + reference_search_n(ForwardIterator first, ForwardIterator last, + Integer count, const Value& value) + { + if (count <= 0) + return first; + else if (count == 1) + return std::find(first, last, value); + else + { + first = std::find(first, last, value); + while (first != last) + { + typename std::iterator_traits<ForwardIterator>::difference_type n = count; + ForwardIterator i = first; + ++i; + while (i != last && n != 1 && *i==value) + { + ++i; + --n; + } + if (n == 1) + return first; + if (i == last) + return last; + first = std::find(++i, last, value); + } + } + return last; + } + + template<typename ForwardIterator, typename Integer, typename Value, + typename BinaryPredicate> + inline ForwardIterator + reference_search_n(ForwardIterator first, ForwardIterator last, + Integer count, const Value& value, + BinaryPredicate pred) + { + typedef typename std::iterator_traits< + ForwardIterator + >::iterator_category cat_t BOOST_RANGE_UNUSED; + + if (count <= 0) + return first; + if (count == 1) + { + while (first != last && !static_cast<bool>(pred(*first, value))) + ++first; + return first; + } + else + { + typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_t; + + while (first != last && !static_cast<bool>(pred(*first, value))) + ++first; + + while (first != last) + { + difference_t n = count; + ForwardIterator i = first; + ++i; + while (i != last && n != 1 && static_cast<bool>(pred(*i, value))) + { + ++i; + --n; + } + if (n == 1) + return first; + if (i == last) + return last; + first = ++i; + while (first != last && !static_cast<bool>(pred(*first, value))) + ++first; + } + } + return last; + } + + template< class Container1, class Value, class Pred > + void test_search_n_pred_impl(Container1& cont1, Value value, Pred pred) + { + typedef BOOST_DEDUCED_TYPENAME Container1::const_iterator const_iterator1_t; + typedef BOOST_DEDUCED_TYPENAME Container1::iterator iterator1_t; + + const Container1& ccont1 = cont1; + + for (std::size_t n = 0; n < cont1.size(); ++n) + { + iterator1_t it = boost::search_n(cont1, n, value, pred); + BOOST_CHECK( it == boost::search_n(boost::make_iterator_range(cont1), n, value, pred) ); + BOOST_CHECK( it == reference_search_n(cont1.begin(), cont1.end(), n, value, pred) ); + + const_iterator1_t cit = boost::search_n(ccont1, n, value, pred); + BOOST_CHECK( cit == boost::search_n(boost::make_iterator_range(ccont1), n, value, pred) ); + BOOST_CHECK( cit == reference_search_n(ccont1.begin(), ccont1.end(), n, value, pred) ); + } + } + + template< class Container1, class Value > + void test_search_n_impl(Container1& cont1, Value value) + { + typedef BOOST_DEDUCED_TYPENAME Container1::const_iterator const_iterator1_t; + typedef BOOST_DEDUCED_TYPENAME Container1::iterator iterator1_t; + + const Container1& ccont1 = cont1; + + for (std::size_t n = 0; n < cont1.size(); ++n) + { + iterator1_t it = boost::search_n(cont1, n, value); + BOOST_CHECK( it == boost::search_n(boost::make_iterator_range(cont1), n, value) ); + BOOST_CHECK( it == reference_search_n(cont1.begin(), cont1.end(), n, value) ); + + const_iterator1_t cit = boost::search_n(ccont1, n, value); + BOOST_CHECK( cit == boost::search_n(boost::make_iterator_range(ccont1), n, value) ); + BOOST_CHECK( cit == reference_search_n(ccont1.begin(), ccont1.end(), n, value) ); + } + + test_search_n_pred_impl(cont1, value, std::less<int>()); + test_search_n_pred_impl(cont1, value, std::greater<int>()); + test_search_n_pred_impl(cont1, value, std::equal_to<int>()); + test_search_n_pred_impl(cont1, value, std::not_equal_to<int>()); + } + + template< class Container1, class Container2 > + void test_search_n_impl() + { + using namespace boost::assign; + + Container1 cont1; + + test_search_n_impl(cont1, 1); + + cont1 += 1; + test_search_n_impl(cont1, 1); + test_search_n_impl(cont1, 0); + + cont1.clear(); + cont1 += 1,1; + test_search_n_impl(cont1, 1); + test_search_n_impl(cont1, 0); + + cont1 += 1,1,1; + test_search_n_impl(cont1, 1); + test_search_n_impl(cont1, 0); + + cont1.clear(); + cont1 += 1,2,3,4,5,6,7,8,9; + test_search_n_impl(cont1, 1); + test_search_n_impl(cont1, 2); + test_search_n_impl(cont1, 5); + test_search_n_impl(cont1, 9); + } + + void test_search_n() + { + test_search_n_impl< std::list<int>, std::list<int> >(); + test_search_n_impl< std::vector<int>, std::vector<int> >(); + test_search_n_impl< std::set<int>, std::set<int> >(); + test_search_n_impl< std::list<int>, std::vector<int> >(); + test_search_n_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.search_n" ); + + test->add( BOOST_TEST_CASE( &test_search_n ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/set_difference.cpp b/src/boost/libs/range/test/algorithm_test/set_difference.cpp new file mode 100644 index 00000000..84dc62c9 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/set_difference.cpp @@ -0,0 +1,214 @@ +// 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 <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace boost +{ + namespace + { + template<class Container1, class Iterator, class Container2> + void check_result( + Container1& reference, + Iterator reference_result, + Container2& test_cont, + Iterator test_result + ) + { + BOOST_CHECK_EQUAL( + std::distance<Iterator>(reference.begin(), reference_result), + std::distance<Iterator>(test_cont.begin(), test_result) + ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test_cont.begin(), test_cont.end() + ); + } + + 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(cont1.size() + cont2.size()); + std::vector<value_t> test_cont(reference); + + iterator_t reference_result + = std::set_difference(cont1.begin(), cont1.end(), + cont2.begin(), cont2.end(), + reference.begin()); + + iterator_t test_result + = boost::set_difference(cont1, cont2, test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_difference( + boost::make_iterator_range(cont1), cont2, + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_difference( + cont1, boost::make_iterator_range(cont2), + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_difference( + boost::make_iterator_range(cont1), + boost::make_iterator_range(cont2), + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + } + + 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(cont1.size() + cont2.size()); + std::vector<value_t> test_cont(reference); + + iterator_t reference_result + = std::set_difference(cont1.begin(), cont1.end(), + cont2.begin(), cont2.end(), + reference.begin(), + pred); + + iterator_t test_result + = boost::set_difference(cont1, cont2, test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_difference( + boost::make_iterator_range(cont1), cont2, + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_difference( + cont1, boost::make_iterator_range(cont2), + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_difference( + boost::make_iterator_range(cont1), + boost::make_iterator_range(cont2), + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + } + + template<class Container1, class Container2> + void test_set_difference_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_set_difference_impl() + { + using namespace boost::assign; + + Container1 cont1; + Container2 cont2; + + test_set_difference_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 1; + test_set_difference_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont2 += 1; + test_set_difference_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 1,2,3,4,5,6,7,8,9; + cont2 += 2,3,4; + test_set_difference_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 2,3,4; + cont2 += 1,2,3,4,5,6,7,8,9; + test_set_difference_impl(cont1, cont2); + } + + void test_set_difference() + { + test_set_difference_impl< std::vector<int>, std::vector<int> >(); + test_set_difference_impl< std::list<int>, std::list<int> >(); + test_set_difference_impl< std::deque<int>, std::deque<int> >(); + test_set_difference_impl< std::vector<int>, std::list<int> >(); + test_set_difference_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.set_difference" ); + + test->add( BOOST_TEST_CASE( &boost::test_set_difference ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/set_intersection.cpp b/src/boost/libs/range/test/algorithm_test/set_intersection.cpp new file mode 100644 index 00000000..213bbdf7 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/set_intersection.cpp @@ -0,0 +1,214 @@ +// 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 <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace boost +{ + namespace + { + template<class Container1, class Iterator, class Container2> + void check_result( + Container1& reference, + Iterator reference_result, + Container2& test_cont, + Iterator test_result + ) + { + BOOST_CHECK_EQUAL( + std::distance<Iterator>(reference.begin(), reference_result), + std::distance<Iterator>(test_cont.begin(), test_result) + ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test_cont.begin(), test_cont.end() + ); + } + + 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(cont1.size() + cont2.size()); + std::vector<value_t> test_cont(reference); + + iterator_t reference_result + = std::set_intersection(cont1.begin(), cont1.end(), + cont2.begin(), cont2.end(), + reference.begin()); + + iterator_t test_result + = boost::set_intersection(cont1, cont2, test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_intersection( + boost::make_iterator_range(cont1), cont2, + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_intersection( + cont1, boost::make_iterator_range(cont2), + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_intersection( + boost::make_iterator_range(cont1), + boost::make_iterator_range(cont2), + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + } + + 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(cont1.size() + cont2.size()); + std::vector<value_t> test_cont(reference); + + iterator_t reference_result + = std::set_intersection(cont1.begin(), cont1.end(), + cont2.begin(), cont2.end(), + reference.begin(), + pred); + + iterator_t test_result + = boost::set_intersection(cont1, cont2, test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_intersection( + boost::make_iterator_range(cont1), cont2, + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_intersection( + cont1, boost::make_iterator_range(cont2), + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_intersection( + boost::make_iterator_range(cont1), + boost::make_iterator_range(cont2), + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + } + + template<class Container1, class Container2> + void test_set_intersection_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_set_intersection_impl() + { + using namespace boost::assign; + + Container1 cont1; + Container2 cont2; + + test_set_intersection_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 1; + test_set_intersection_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont2 += 1; + test_set_intersection_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 1,2,3,4,5,6,7,8,9; + cont2 += 2,3,4; + test_set_intersection_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 2,3,4; + cont2 += 1,2,3,4,5,6,7,8,9; + test_set_intersection_impl(cont1, cont2); + } + + void test_set_intersection() + { + test_set_intersection_impl< std::vector<int>, std::vector<int> >(); + test_set_intersection_impl< std::list<int>, std::list<int> >(); + test_set_intersection_impl< std::deque<int>, std::deque<int> >(); + test_set_intersection_impl< std::vector<int>, std::list<int> >(); + test_set_intersection_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.set_intersection" ); + + test->add( BOOST_TEST_CASE( &boost::test_set_intersection ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/set_symmetric_difference.cpp b/src/boost/libs/range/test/algorithm_test/set_symmetric_difference.cpp new file mode 100644 index 00000000..b792fd87 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/set_symmetric_difference.cpp @@ -0,0 +1,216 @@ +// 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 <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace boost +{ + namespace + { + template<class Container1, class Iterator, class Container2> + void check_result( + Container1& reference, + Iterator reference_result, + Container2& test_cont, + Iterator test_result + ) + { + BOOST_CHECK_EQUAL( + std::distance<Iterator>(reference.begin(), reference_result), + std::distance<Iterator>(test_cont.begin(), test_result) + ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test_cont.begin(), test_cont.end() + ); + } + + 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(cont1.size() + cont2.size()); + std::vector<value_t> test_cont(reference); + + iterator_t reference_result + = std::set_symmetric_difference(cont1.begin(), cont1.end(), + cont2.begin(), cont2.end(), + reference.begin()); + + iterator_t test_result + = boost::set_symmetric_difference(cont1, cont2, + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_symmetric_difference( + boost::make_iterator_range(cont1), cont2, + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_symmetric_difference( + cont1, boost::make_iterator_range(cont2), + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_symmetric_difference( + boost::make_iterator_range(cont1), + boost::make_iterator_range(cont2), + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + } + + 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(cont1.size() + cont2.size()); + std::vector<value_t> test_cont(reference); + + iterator_t reference_result + = std::set_symmetric_difference(cont1.begin(), cont1.end(), + cont2.begin(), cont2.end(), + reference.begin(), + pred); + + iterator_t test_result + = boost::set_symmetric_difference(cont1, cont2, + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_symmetric_difference( + boost::make_iterator_range(cont1), cont2, + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_symmetric_difference( + cont1, boost::make_iterator_range(cont2), + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_symmetric_difference( + boost::make_iterator_range(cont1), + boost::make_iterator_range(cont2), + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + } + + template<class Container1, class Container2> + void test_set_symmetric_difference_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_set_symmetric_difference_impl() + { + using namespace boost::assign; + + Container1 cont1; + Container2 cont2; + + test_set_symmetric_difference_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 1; + test_set_symmetric_difference_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont2 += 1; + test_set_symmetric_difference_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 1,2,3,4,5,6,7,8,9; + cont2 += 2,3,4; + test_set_symmetric_difference_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 2,3,4; + cont2 += 1,2,3,4,5,6,7,8,9; + test_set_symmetric_difference_impl(cont1, cont2); + } + + void test_set_symmetric_difference() + { + test_set_symmetric_difference_impl< std::vector<int>, std::vector<int> >(); + test_set_symmetric_difference_impl< std::list<int>, std::list<int> >(); + test_set_symmetric_difference_impl< std::deque<int>, std::deque<int> >(); + test_set_symmetric_difference_impl< std::vector<int>, std::list<int> >(); + test_set_symmetric_difference_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.set_symmetric_difference" ); + + test->add( BOOST_TEST_CASE( &boost::test_set_symmetric_difference ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/set_union.cpp b/src/boost/libs/range/test/algorithm_test/set_union.cpp new file mode 100644 index 00000000..7f9f10a1 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/set_union.cpp @@ -0,0 +1,210 @@ +// 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 <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace boost +{ + namespace + { + template<class Container1, class Iterator, class Container2> + void check_result( + Container1& reference, + Iterator reference_result, + Container2& test_cont, + Iterator test_result + ) + { + BOOST_CHECK_EQUAL( + std::distance<Iterator>(reference.begin(), reference_result), + std::distance<Iterator>(test_cont.begin(), test_result) + ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test_cont.begin(), test_cont.end() + ); + } + + 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(cont1.size() + cont2.size()); + std::vector<value_t> test_cont(reference); + + iterator_t reference_result + = std::set_union(cont1.begin(), cont1.end(), + cont2.begin(), cont2.end(), + reference.begin()); + + iterator_t test_result + = boost::set_union(cont1, cont2, test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_union(boost::make_iterator_range(cont1), + cont2, test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_union(cont1, + boost::make_iterator_range(cont2), + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_union(boost::make_iterator_range(cont1), + boost::make_iterator_range(cont2), + test_cont.begin()); + + check_result(reference, reference_result, + test_cont, test_result); + } + + 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(cont1.size() + cont2.size()); + std::vector<value_t> test_cont(reference); + + iterator_t reference_result + = std::set_union(cont1.begin(), cont1.end(), + cont2.begin(), cont2.end(), + reference.begin(), + pred); + + iterator_t test_result + = boost::set_union(cont1, cont2, test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_union(boost::make_iterator_range(cont1), + cont2, test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_union(cont1, + boost::make_iterator_range(cont2), + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + + test_result = boost::set_union(boost::make_iterator_range(cont1), + boost::make_iterator_range(cont2), + test_cont.begin(), pred); + + check_result(reference, reference_result, + test_cont, test_result); + } + + template<class Container1, class Container2> + void test_set_union_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_set_union_impl() + { + using namespace boost::assign; + + Container1 cont1; + Container2 cont2; + + test_set_union_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 1; + test_set_union_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont2 += 1; + test_set_union_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 1,2,3,4,5,6,7,8,9; + cont2 += 2,3,4; + test_set_union_impl(cont1, cont2); + + cont1.clear(); + cont2.clear(); + cont1 += 2,3,4; + cont2 += 1,2,3,4,5,6,7,8,9; + test_set_union_impl(cont1, cont2); + } + + void test_set_union() + { + test_set_union_impl< std::vector<int>, std::vector<int> >(); + test_set_union_impl< std::list<int>, std::list<int> >(); + test_set_union_impl< std::deque<int>, std::deque<int> >(); + test_set_union_impl< std::vector<int>, std::list<int> >(); + test_set_union_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.set_union" ); + + test->add( BOOST_TEST_CASE( &boost::test_set_union ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/sort.cpp b/src/boost/libs/range/test/algorithm_test/sort.cpp new file mode 100644 index 00000000..c6611f7c --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/sort.cpp @@ -0,0 +1,105 @@ +// 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/sort.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace boost +{ + namespace + { + template<class Container> + void test_sort_impl(Container& cont) + { + Container reference(cont); + Container test(cont); + + boost::sort(test); + std::sort(reference.begin(), reference.end()); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + Container test2(cont); + boost::sort(boost::make_iterator_range(test2)); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test2.begin(), test2.end() ); + } + + template<class Container, class BinaryPredicate> + void test_sort_impl(Container& cont, BinaryPredicate pred) + { + Container reference(cont); + Container test(cont); + + boost::sort(test, pred); + std::sort(reference.begin(), reference.end(), pred); + + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test.begin(), test.end() + ); + + Container test2(cont); + boost::sort(boost::make_iterator_range(test2), pred); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test2.begin(), test2.end() ); + } + + template<class Container> + void test_sort_impl() + { + using namespace boost::assign; + + Container cont; + test_sort_impl(cont); + test_sort_impl(cont, std::less<int>()); + test_sort_impl(cont, std::greater<int>()); + + cont.clear(); + cont += 1; + test_sort_impl(cont); + test_sort_impl(cont, std::less<int>()); + test_sort_impl(cont, std::greater<int>()); + + cont.clear(); + cont += 1,2,3,4,5,6,7,8,9; + test_sort_impl(cont); + test_sort_impl(cont, std::less<int>()); + test_sort_impl(cont, std::greater<int>()); + } + + void test_sort() + { + test_sort_impl< std::vector<int> >(); + test_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.sort" ); + + test->add( BOOST_TEST_CASE( &boost::test_sort ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/stable_partition.cpp b/src/boost/libs/range/test/algorithm_test/stable_partition.cpp new file mode 100644 index 00000000..b39161f5 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/stable_partition.cpp @@ -0,0 +1,134 @@ +// 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/stable_partition.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.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_stable_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 stable_partition_test_policy + { + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type + test_iter(Container& cont) + { + Container cont2(cont); + + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t; + iter_t result = boost::stable_partition(cont, UnaryPredicate()); + + iter_t temp_result = boost::stable_partition( + boost::make_iterator_range(cont2), UnaryPredicate()); + + BOOST_CHECK_EQUAL( std::distance(cont.begin(), result), + std::distance(cont2.begin(), temp_result) ); + + 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; + Container cont2(cont); + result_t result = boost::stable_partition<return_type>(cont, policy.pred()); + + result_t result2 = boost::stable_partition<return_type>( + boost::make_iterator_range(cont2), policy.pred()); + + boost::ignore_unused_variable_warning(result2); + + BOOST_CHECK_EQUAL_COLLECTIONS( cont2.begin(), cont2.end(), + cont.begin(), cont.end() ); + + return result; + } + }; + + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type + reference(Container& cont) + { + return std::stable_partition(cont.begin(), cont.end(), UnaryPredicate()); + } + }; + + template<class Container> + void test_stable_partition_impl() + { + using namespace boost::assign; + + boost::range_test::range_return_test_driver test_driver; + + stable_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_stable_partition() + { + test_stable_partition_impl< std::vector<int> >(); + test_stable_partition_impl< std::list<int> >(); + test_stable_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.stable_partition" ); + + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_stable_partition::test_stable_partition ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/stable_sort.cpp b/src/boost/libs/range/test/algorithm_test/stable_sort.cpp new file mode 100644 index 00000000..8372bd6e --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/stable_sort.cpp @@ -0,0 +1,103 @@ +// 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/stable_sort.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace boost +{ + namespace + { + template<class Container> + void test_stable_sort_impl(Container& cont) + { + Container reference(cont); + Container test(cont); + + boost::stable_sort(test); + std::stable_sort(reference.begin(), reference.end()); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + test = cont; + boost::stable_sort(boost::make_iterator_range(test)); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + } + + template<class Container, class BinaryPredicate> + void test_stable_sort_impl(Container& cont, BinaryPredicate pred) + { + Container reference(cont); + Container test(cont); + + boost::stable_sort(test, pred); + std::stable_sort(reference.begin(), reference.end(), pred); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + test = cont; + boost::stable_sort(boost::make_iterator_range(test), pred); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + } + + template<class Container> + void test_stable_sort_impl() + { + using namespace boost::assign; + + Container cont; + test_stable_sort_impl(cont); + test_stable_sort_impl(cont, std::less<int>()); + test_stable_sort_impl(cont, std::greater<int>()); + + cont.clear(); + cont += 1; + test_stable_sort_impl(cont); + test_stable_sort_impl(cont, std::less<int>()); + test_stable_sort_impl(cont, std::greater<int>()); + + cont.clear(); + cont += 1,2,3,4,5,6,7,8,9; + test_stable_sort_impl(cont); + test_stable_sort_impl(cont, std::less<int>()); + test_stable_sort_impl(cont, std::greater<int>()); + } + + void test_stable_sort() + { + test_stable_sort_impl< std::vector<int> >(); + test_stable_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.stable_sort" ); + + test->add( BOOST_TEST_CASE( &boost::test_stable_sort ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/swap_ranges.cpp b/src/boost/libs/range/test/algorithm_test/swap_ranges.cpp new file mode 100644 index 00000000..a96bface --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/swap_ranges.cpp @@ -0,0 +1,116 @@ +// 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/swap_ranges.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace +{ + template<class Container1, class Container2> + void test_swap_ranges_impl(const Container1& source1, const Container2& source2) + { + Container1 reference1(source1); + Container2 reference2(source2); + std::swap_ranges(reference1.begin(), reference1.end(), reference2.begin()); + + Container1 test1(source1); + Container2 test2(source2); + boost::swap_ranges(test1, test2); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference1.begin(), reference1.end(), + test1.begin(), test1.end() ); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference2.begin(), reference2.end(), + test2.begin(), test2.end() ); + + test1 = source1; + test2 = source2; + boost::swap_ranges(boost::make_iterator_range(test1), test2); + BOOST_CHECK_EQUAL_COLLECTIONS( reference1.begin(), reference1.end(), + test1.begin(), test1.end() ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference2.begin(), reference2.end(), + test2.begin(), test2.end() ); + + test1 = source1; + test2 = source2; + boost::swap_ranges(test1, boost::make_iterator_range(test2)); + BOOST_CHECK_EQUAL_COLLECTIONS( reference1.begin(), reference1.end(), + test1.begin(), test1.end() ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference2.begin(), reference2.end(), + test2.begin(), test2.end() ); + + test1 = source1; + test2 = source2; + boost::swap_ranges(boost::make_iterator_range(test1), + boost::make_iterator_range(test2)); + BOOST_CHECK_EQUAL_COLLECTIONS( reference1.begin(), reference1.end(), + test1.begin(), test1.end() ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference2.begin(), reference2.end(), + test2.begin(), test2.end() ); + } + + template<class Container1, class Container2> + void test_swap_ranges_impl() + { + using namespace boost::assign; + + Container1 c1; + Container2 c2; + + test_swap_ranges_impl(c1, c2); + + c1.clear(); + c1 += 1; + c2.clear(); + c2 += 2; + test_swap_ranges_impl(c1, c2); + + c1.clear(); + c1 += 1,2,3,4,5,6,7,8,9,10; + c2.clear(); + c2 += 10,9,8,7,6,5,4,3,2,1; + test_swap_ranges_impl(c1, c2); + } + + inline void test_swap_ranges() + { + test_swap_ranges_impl< std::vector<int>, std::vector<int> >(); + test_swap_ranges_impl< std::vector<int>, std::list<int> >(); + test_swap_ranges_impl< std::vector<int>, std::deque<int> >(); + test_swap_ranges_impl< std::list<int>, std::vector<int> >(); + test_swap_ranges_impl< std::list<int>, std::list<int> >(); + test_swap_ranges_impl< std::list<int>, std::deque<int> >(); + test_swap_ranges_impl< std::deque<int>, std::vector<int> >(); + test_swap_ranges_impl< std::deque<int>, std::list<int> >(); + test_swap_ranges_impl< std::deque<int>, 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.swap_ranges" ); + + test->add( BOOST_TEST_CASE( &test_swap_ranges ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/transform.cpp b/src/boost/libs/range/test/algorithm_test/transform.cpp new file mode 100644 index 00000000..11ac5f0f --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/transform.cpp @@ -0,0 +1,184 @@ +// 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/transform.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include "../test_function/multiply_by_x.hpp" +#include <algorithm> +#include <list> +#include <set> +#include <vector> + +namespace boost +{ + namespace + { + template< class Container > + void test_transform_impl1(Container& cont) + { + using namespace boost::range_test_function; + + const Container& ccont = cont; + + typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; + + std::vector<value_t> target(cont.size()); + std::vector<value_t> reference(cont.size()); + typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t; + + multiply_by_x<int> fn(2); + + iterator_t reference_it + = std::transform(cont.begin(), cont.end(), reference.begin(), fn); + + boost::ignore_unused_variable_warning(reference_it); + + iterator_t test_it + = boost::transform(cont, target.begin(), fn); + + BOOST_CHECK( test_it == target.end() ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + + BOOST_CHECK( test_it == boost::transform(boost::make_iterator_range(cont), target.begin(), fn) ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + + target.clear(); + target.resize(ccont.size()); + + test_it = boost::transform(ccont, target.begin(), fn); + + BOOST_CHECK( test_it == target.end() ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + BOOST_CHECK( test_it == boost::transform(boost::make_iterator_range(ccont), target.begin(), fn) ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + } + + template< class Container > + void test_transform_impl1() + { + using namespace boost::assign; + + Container cont; + + test_transform_impl1(cont); + + cont += 1; + test_transform_impl1(cont); + + cont += 2,3,4,5,6,7; + test_transform_impl1(cont); + } + + template< class Container1, class Container2 > + void test_transform_impl2(Container1& cont1, Container2& cont2) + { + const Container1& ccont1 = cont1; + const Container2& ccont2 = cont2; + + BOOST_CHECK_EQUAL( cont1.size(), cont2.size() ); + + typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t; + + std::vector<value_t> target(cont1.size()); + std::vector<value_t> reference(cont1.size()); + typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t; + + std::multiplies<int> fn; + + iterator_t reference_it + = std::transform(cont1.begin(), cont1.end(), + cont2.begin(), reference.begin(), fn); + + boost::ignore_unused_variable_warning(reference_it); + + iterator_t test_it + = boost::transform(cont1, cont2, target.begin(), fn); + + BOOST_CHECK( test_it == target.end() ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + + BOOST_CHECK( test_it == boost::transform(boost::make_iterator_range(cont1), cont2, target.begin(), fn) ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + + BOOST_CHECK( test_it == boost::transform(cont1, boost::make_iterator_range(cont2), target.begin(), fn) ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + + BOOST_CHECK( test_it == boost::transform(boost::make_iterator_range(cont1), + boost::make_iterator_range(cont2), + target.begin(), fn) ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + + + target.clear(); + target.resize(ccont1.size()); + + test_it = boost::transform(ccont1, ccont2, target.begin(), fn); + + BOOST_CHECK( test_it == target.end() ); + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + } + + template< class Container1, class Container2 > + void test_transform_impl2() + { + using namespace boost::assign; + + Container1 cont1; + Container2 cont2; + + test_transform_impl2(cont1, cont2); + + cont1 += 1; + cont2 += 2; + test_transform_impl2(cont1, cont2); + + cont1 += 2,3,4,5,6,7; + cont2 += 4,6,8,10,12,14; + test_transform_impl2(cont1, cont2); + } + + void test_transform() + { + test_transform_impl1< std::vector<int> >(); + test_transform_impl1< std::list<int> >(); + test_transform_impl1< std::set<int> >(); + test_transform_impl1< std::multiset<int> >(); + + test_transform_impl2< std::vector<int>, std::list<int> >(); + test_transform_impl2< std::list<int>, std::vector<int> >(); + test_transform_impl2< std::set<int>, std::set<int> >(); + test_transform_impl2< std::multiset<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.transform" ); + + test->add( BOOST_TEST_CASE( &boost::test_transform ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/unique.cpp b/src/boost/libs/range/test/algorithm_test/unique.cpp new file mode 100644 index 00000000..d8eb7846 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/unique.cpp @@ -0,0 +1,263 @@ +// 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/unique.hpp> +#include <boost/range/detail/range_return.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> +#include <boost/config.hpp> +#include "../test_driver/range_overload_test_driver.hpp" +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace boost_range_test_algorithm_unique +{ + // test the 'unique' algorithm without a predicate + class unique_test_policy + { + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type + test_iter(Container& cont) + { + // There isn't an iterator return version of boost::unique, so just + // perform the standard algorithm + return std::unique(cont.begin(), cont.end()); + } + + 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; + + Container cont2(cont); + + result_t result = boost::unique<return_type>(cont); + + boost::unique<return_type>(boost::make_iterator_range(cont2)); + + BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), + cont2.begin(), cont2.end() ); + + return result; + } + }; + + template<typename Container> + struct test_range_overload + { + BOOST_STATIC_CONSTANT( + ::boost::range_return_value, + result_type = ::boost::return_begin_found); + + template<typename Policy> + BOOST_DEDUCED_TYPENAME boost::range_return< + Container, result_type + >::type + operator()(Policy& policy, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return< + Container,result_type>::type result_t; + + Container cont2(cont); + + result_t result = boost::unique(cont); + + boost::unique(boost::make_iterator_range(cont2)); + + 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::unique(cont.begin(), cont.end()); + } + }; + + // test the 'unique' algorithm with a predicate + template<class Pred> + class unique_pred_test_policy + { + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type + test_iter(Container& cont) + { + // There isn't an iterator return version of boost::unique, so just + // perform the standard algorithm + return std::unique(cont.begin(), cont.end(), Pred()); + } + + 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; + + Container cont2(cont); + + result_t result = boost::unique<return_type>(cont, policy.pred()); + + boost::unique<return_type>(boost::make_iterator_range(cont2), policy.pred()); + + BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), + cont2.begin(), cont2.end() ); + + return result; + } + }; + + template<typename Container> + struct test_range_overload + { + BOOST_STATIC_CONSTANT( + ::boost::range_return_value, + result_type = ::boost::return_begin_found); + + template<typename Policy> + BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type + operator()(Policy& policy, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return< + Container,result_type>::type result_t; + + Container cont2(cont); + + result_t result = boost::unique(cont, policy.pred()); + + boost::unique(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::unique(cont.begin(), cont.end(), Pred()); + } + }; + + template<class Container, class TestPolicy, class Pred> + void test_unique_impl(TestPolicy policy, Pred pred) + { + using namespace boost::assign; + + typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; + + boost::range_test::range_overload_test_driver test_driver; + + Container cont; + + test_driver(cont, policy); + + cont.clear(); + cont += 1; + + std::vector<value_t> temp(cont.begin(), cont.end()); + std::sort(temp.begin(), temp.end(), pred); + cont.assign(temp.begin(), temp.end()); + + test_driver(cont, policy); + + cont.clear(); + cont += 1,2,2,2,2,3,4,5,6,7,8,9; + + temp.assign(cont.begin(), cont.end()); + std::sort(temp.begin(), temp.end(), pred); + cont.assign(temp.begin(), temp.end()); + + test_driver(cont, policy); + } + + template<typename T> + struct equal_div_2 + { + typedef bool result_type; + typedef const T& first_argument_type; + typedef const T& second_argument_type; + + bool operator()(const T& left, const T& right) const + { + return left / 2 == right / 2; + } + }; + + template<class Container> + void test_unique_impl() + { + test_unique_impl<Container>( + unique_test_policy(), + std::less<int>() + ); + + test_unique_impl<Container>( + unique_pred_test_policy<std::equal_to<int> >(), + std::less<int>() + ); + + test_unique_impl<Container>( + unique_pred_test_policy<std::equal_to<int> >(), + std::greater<int>() + ); + + test_unique_impl<Container>( + unique_pred_test_policy<equal_div_2<int> >(), + std::less<int>() + ); + } + + void test_unique() + { + test_unique_impl< std::vector<int> >(); + test_unique_impl< std::list<int> >(); + test_unique_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.unique" ); + + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_unique::test_unique ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/unique_copy.cpp b/src/boost/libs/range/test/algorithm_test/unique_copy.cpp new file mode 100644 index 00000000..21f107a8 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/unique_copy.cpp @@ -0,0 +1,158 @@ +// 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/unique_copy.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <functional> +#include <list> +#include <numeric> +#include <deque> +#include <vector> + +namespace +{ + template<class OutputIterator, class Value> + void test_append(OutputIterator target, Value value) + { + *target++ = value; + } + + template<class Container> + void test_unique_copy_impl(Container& c) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_value<Container>::type value_type; + std::vector<value_type> reference; + std::vector<value_type> test; + + test_append( + std::unique_copy(c.begin(), c.end(), std::back_inserter(reference)), + value_type() + ); + + test_append( + boost::unique_copy(c, std::back_inserter(test)), + value_type() + ); + + BOOST_CHECK_EQUAL_COLLECTIONS(reference.begin(), reference.end(), + test.begin(), test.end()); + + test.clear(); + + test_append( + boost::unique_copy(boost::make_iterator_range(c), + std::back_inserter(test)), + value_type() + ); + + BOOST_CHECK_EQUAL_COLLECTIONS(reference.begin(), reference.end(), + test.begin(), test.end()); + } + + template<class Container, class Pred> + void test_unique_copy_impl(Container& c, Pred pred) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_value<Container>::type value_type; + std::vector<value_type> reference; + std::vector<value_type> test; + + test_append( + std::unique_copy(c.begin(), c.end(), std::back_inserter(reference), pred), + value_type() + ); + + test_append( + boost::unique_copy(c, std::back_inserter(test), pred), + value_type() + ); + + BOOST_CHECK_EQUAL_COLLECTIONS(reference.begin(), reference.end(), + test.begin(), test.end()); + + test.clear(); + + test_append( + boost::unique_copy(boost::make_iterator_range(c), + std::back_inserter(test), pred), + value_type() + ); + + BOOST_CHECK_EQUAL_COLLECTIONS(reference.begin(), reference.end(), + test.begin(), test.end()); + } + + template<class Container, class Pred> + void test_unique_copy_driver(Pred pred) + { + using namespace boost::assign; + + typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; + + Container cont; + + test_unique_copy_impl(cont); + test_unique_copy_impl(cont, pred); + + cont.clear(); + cont += 1; + + std::vector<value_t> temp(cont.begin(), cont.end()); + std::sort(temp.begin(), temp.end()); + cont.assign(temp.begin(), temp.end()); + test_unique_copy_impl(cont); + + std::sort(temp.begin(), temp.end(), pred); + cont.assign(temp.begin(), temp.end()); + test_unique_copy_impl(cont, pred); + + cont.clear(); + cont += 1,2,2,2,2,3,4,5,6,7,8,9; + + temp.assign(cont.begin(), cont.end()); + std::sort(temp.begin(), temp.end()); + cont.assign(temp.begin(), temp.end()); + test_unique_copy_impl(cont); + + std::sort(temp.begin(), temp.end(), pred); + cont.assign(temp.begin(), temp.end()); + test_unique_copy_impl(cont, pred); + } + + template<class Container> + void test_unique_copy_impl() + { + test_unique_copy_driver<Container>(std::less<int>()); + test_unique_copy_driver<Container>(std::greater<int>()); + } + + void test_unique_copy() + { + test_unique_copy_impl< std::vector<int> >(); + test_unique_copy_impl< std::list<int> >(); + test_unique_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.unique_copy" ); + + test->add( BOOST_TEST_CASE( &test_unique_copy ) ); + + return test; +} diff --git a/src/boost/libs/range/test/algorithm_test/upper_bound.cpp b/src/boost/libs/range/test/algorithm_test/upper_bound.cpp new file mode 100644 index 00000000..daae7644 --- /dev/null +++ b/src/boost/libs/range/test/algorithm_test/upper_bound.cpp @@ -0,0 +1,182 @@ +// 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/upper_bound.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/bind.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_upper_bound +{ + class upper_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::upper_bound(cont, 5); + BOOST_CHECK( result == boost::upper_bound(boost::make_iterator_range(cont), 5) ); + return result; + } + + template<boost::range_return_value result_type> + struct test_range + { + template<class Container, class Policy> + BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type + operator()(Policy&, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type result_t; + result_t result = boost::upper_bound<result_type>(cont, 5); + BOOST_CHECK( result == boost::upper_bound<result_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::upper_bound(cont.begin(), cont.end(), 5); + } + }; + + template< class BinaryPredicate > + struct upper_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::upper_bound(cont, 5, BinaryPredicate()); + BOOST_CHECK( result == boost::upper_bound(boost::make_iterator_range(cont), 5, BinaryPredicate()) ); + return result; + } + + template< boost::range_return_value result_type> + struct test_range + { + template< class Container, class Policy > + BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type + operator()(Policy& policy, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type result_t; + + result_t result = boost::upper_bound<result_type>(cont, 5, policy.pred()); + + BOOST_CHECK( result == boost::upper_bound<result_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::upper_bound( + cont.begin(), cont.end(), 5, BinaryPredicate()); + } + + BinaryPredicate& pred() { return m_pred; } + + private: + BinaryPredicate m_pred; + }; + + template<class Container, + class TestPolicy, + class BinaryPredicate> + void test_upper_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_upper_bound_impl() + { + test_upper_bound_impl<Container>( + upper_bound_policy(), + std::less<int>() + ); + + test_upper_bound_impl<Container>( + upper_bound_pred_policy<std::less<int> >(), + std::less<int>() + ); + + test_upper_bound_impl<Container>( + upper_bound_pred_policy<std::greater<int> >(), + std::greater<int>() + ); + } + + void test_upper_bound() + { + test_upper_bound_impl< std::vector<int> >(); + test_upper_bound_impl< std::list<int> >(); + test_upper_bound_impl< std::deque<int> >(); + + test_upper_bound_impl< const std::vector<int> >(); + test_upper_bound_impl< const std::list<int> >(); + test_upper_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.upper_bound" ); + + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_upper_bound::test_upper_bound ) ); + + return test; +} diff --git a/src/boost/libs/range/test/array.cpp b/src/boost/libs/range/test/array.cpp new file mode 100644 index 00000000..b913fdef --- /dev/null +++ b/src/boost/libs/range/test/array.cpp @@ -0,0 +1,83 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // suppress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#include <boost/range.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <iostream> + +using namespace boost; +using namespace std; + +void check_array() +{ + const int sz = 9; + typedef int array_t[sz]; + int my_array[sz] = { 1,2,3,4,5,6,7,8,9 }; + const array_t ca = { 1,2,3,4,5,6,7,8,10 }; + + +// BOOST_RANGE_NO_STATIC_ASSERT +#if !defined( __BORLANDC__ ) +#else + BOOST_STATIC_ASSERT(( is_same< range_value<array_t>::type, int >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<array_t>::type, int* >::value )); + BOOST_STATIC_ASSERT(( is_same< range_const_iterator<array_t>::type, const int* >::value )); + BOOST_STATIC_ASSERT(( is_same< range_difference<array_t>::type, std::ptrdiff_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_size<array_t>::type, std::size_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<array_t>::type, int* >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value )); + + BOOST_STATIC_ASSERT(( is_same< range_value<const array_t>::type, const int >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value )); + BOOST_STATIC_ASSERT(( is_same< range_const_iterator<const array_t>::type, const int* >::value )); + BOOST_STATIC_ASSERT(( is_same< range_difference<const array_t>::type, std::ptrdiff_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_size<const array_t>::type, std::size_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value )); +#endif + + BOOST_CHECK_EQUAL( begin( my_array ), my_array ); + BOOST_CHECK_EQUAL( end( my_array ), my_array + size( my_array ) ); + BOOST_CHECK_EQUAL( empty( my_array ), false ); + + BOOST_CHECK_EQUAL( begin( ca ), ca ); + BOOST_CHECK_EQUAL( end( ca ), ca + size( ca ) ); + BOOST_CHECK_EQUAL( empty( ca ),false ); + + const char A[] = "\0A"; + BOOST_CHECK_EQUAL( boost::size(A), 3 ); +} + +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_array ) ); + + return test; +} + + + + + diff --git a/src/boost/libs/range/test/atl.cpp b/src/boost/libs/range/test/atl.cpp new file mode 100644 index 00000000..50905b16 --- /dev/null +++ b/src/boost/libs/range/test/atl.cpp @@ -0,0 +1,623 @@ + + +// Boost.Range ATL Extension +// +// Copyright Shunsuke Sogame 2005-2006. +// Distributed under 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 <pstade/vodka/drink.hpp> + +#include <boost/test/test_tools.hpp> +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS +#define _ATL_NO_AUTOMATIC_NAMESPACE + +#define BOOST_LIB_NAME boost_test_exec_monitor +#include <boost/config/auto_link.hpp> + +#define BOOST_RANGE_DETAIL_MICROSOFT_TEST +#include <boost/range/atl.hpp> // can be placed first + + +#include <map> +#include <string> +#include <boost/concept_check.hpp> +#include <boost/mpl/if.hpp> +#include <boost/range/begin.hpp> +#include <boost/range/distance.hpp> +#include <boost/range/iterator_range.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + + +#include <boost/foreach.hpp> + + +#include <atlbase.h> // for ATL3 CSimpleArray/CSimpleValArray +#if !(_ATL_VER < 0x0700) + #include <atlcoll.h> + #include <cstringt.h> + #include <atlsimpstr.h> + #include <atlstr.h> +#endif + + +namespace brdm = boost::range_detail_microsoft; + + +#if !(_ATL_VER < 0x0700) + + +template< class ArrayT, class SampleRange > +bool test_init_auto_ptr_array(ArrayT& arr, SampleRange& sample) +{ + typedef typename boost::range_iterator<SampleRange>::type iter_t; + + for (iter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) { + arr.Add(*it); // moves ownership + } + + return boost::distance(arr) == boost::distance(sample); +} + + +template< class ListT, class SampleRange > +bool test_init_auto_ptr_list(ListT& lst, SampleRange& sample) +{ + typedef typename boost::range_iterator<SampleRange>::type iter_t; + typedef typename boost::range_value<SampleRange>::type val_t; + + for (iter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) { + lst.AddTail(*it); // moves ownership + } + + return boost::distance(lst) == boost::distance(sample); +} + + +// Workaround: +// CRBTree provides no easy access function, but yes, it is the range! +// +template< class AtlMapT, class KeyT, class MappedT > +bool test_atl_map_has(AtlMapT& map, const KeyT& k, const MappedT m) +{ + typedef typename boost::range_iterator<AtlMapT>::type iter_t; + + for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) { + if (it->m_key == k && it->m_value == m) + return true; + } + + return false; +} + + +template< class AtlMapT, class MapT > +bool test_atl_map(AtlMapT& map, const MapT& sample) +{ + typedef typename boost::range_iterator<AtlMapT>::type iter_t; + typedef typename boost::range_const_iterator<MapT>::type siter_t; + + bool result = true; + + result = result && (boost::distance(map) == boost::distance(sample)); + if (!result) + return false; + + { + for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) { + result = result && brdm::test_find_key_and_mapped(sample, std::make_pair(it->m_key, it->m_value)); + } + } + + { + for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) { + result = result && (test_atl_map_has)(map, it->first, it->second); + } + } + + return result; +} + + +template< class MapT, class SampleMap > +bool test_init_atl_multimap(MapT& map, const SampleMap& sample) +{ + typedef typename boost::range_const_iterator<SampleMap>::type iter_t; + + for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) { + map.Insert(it->first, it->second); + } + + return boost::distance(map) == boost::distance(sample); +} + + +// arrays +// + +template< class Range > +void test_CAtlArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ATL::CAtlArray<val_t> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class ValT, class Range > +void test_CAutoPtrArray(Range& sample) +{ + typedef ValT val_t; + + typedef ATL::CAutoPtrArray<val_t> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, boost::indirect_iterator< ATL::CAutoPtr<val_t> *> >::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, boost::indirect_iterator< ATL::CAutoPtr<val_t> const*> >::value )); + + rng_t rng; + BOOST_CHECK( ::test_init_auto_ptr_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class I, class Range > +void test_CInterfaceArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ATL::CInterfaceArray<I> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, ATL::CComQIPtr<I> * >::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, ATL::CComQIPtr<I> const* >::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +// lists +// + +template< class Range > +void test_CAtlList(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ATL::CAtlList<val_t> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, val_t> >::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, val_t const> >::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_list(rng, sample) ); + BOOST_CHECK( brdm::test_bidirectional(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class ValT, class Range > +void test_CAutoPtrList(Range& sample) +{ + typedef ValT val_t; + + typedef ATL::CAutoPtrList<val_t> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t, ATL::CAutoPtr<val_t> > > >::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t const, ATL::CAutoPtr<val_t> const> > >::value )); + + rng_t rng; + BOOST_CHECK( ::test_init_auto_ptr_list(rng, sample) ); + BOOST_CHECK( brdm::test_bidirectional(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class ValT, class Range > +void test_CHeapPtrList(const Range& sample) +{ + typedef ValT val_t; + + typedef ATL::CHeapPtrList<val_t> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t, ATL::CHeapPtr<val_t> > > >::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t const, ATL::CHeapPtr<val_t> const> > >::value )); + + rng_t rng; + BOOST_CHECK( ::test_init_auto_ptr_list(rng, sample) ); + BOOST_CHECK( brdm::test_bidirectional(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class I, class Range > +void test_CInterfaceList(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ATL::CInterfaceList<I> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, ATL::CComQIPtr<I> > >::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ATL::CComQIPtr<I> const> >::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_list(rng, sample) ); + BOOST_CHECK( brdm::test_bidirectional(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +// strings +// + +template< class Range > +void test_CSimpleStringT(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef typename boost::mpl::if_< boost::is_same<val_t, char>, + ATL::CAtlStringA, + ATL::CAtlStringW + >::type derived_t; + + typedef ATL::CSimpleStringT<val_t> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, typename rng_t::PCXSTR>::value )); + + derived_t drng; + rng_t& rng = drng; + BOOST_CHECK( brdm::test_init_string(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + // BOOST_CHECK( brdm::test_emptiness(rng) ); no default constructible +} + + +template< int n, class Range > +void test_CFixedStringT(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef typename boost::mpl::if_< boost::is_same<val_t, char>, + ATL::CAtlStringA, + ATL::CAtlStringW + >::type base_t; + + typedef ATL::CFixedStringT<base_t, n> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, typename rng_t::PCXSTR>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_string(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CStringT(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef typename boost::mpl::if_< boost::is_same<val_t, char>, + ATL::CAtlStringA, // == CStringT<char, X> + ATL::CAtlStringW // == CStringT<wchar_t, X> + >::type rng_t; + + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, typename rng_t::PCXSTR>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_string(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CStaticString(const Range& sample) +{ +#if !defined(BOOST_RANGE_ATL_NO_TEST_UNDOCUMENTED_RANGE) + { + typedef ATL::CStaticString<char, 20> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, char const *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, char const *>::value )); + + rng_t rng("hello static string"); + BOOST_CHECK( *(boost::begin(rng)+4) == 'o' ); + BOOST_CHECK( *(boost::end(rng)-3) == 'i' ); + } + + { + typedef ATL::CStaticString<wchar_t, 40> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, wchar_t const *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, wchar_t const *>::value )); + + rng_t rng(L"hello static string"); + BOOST_CHECK( *(boost::begin(rng)+4) == L'o' ); + BOOST_CHECK( *(boost::end(rng)-3) == L'i' ); + } +#endif + + (void)sample; // unused +} + + +#endif // !(_ATL_VER < 0x0700) + + +template< class Range > +void test_CComBSTR(const Range& sample) +{ + typedef ATL::CComBSTR rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, OLECHAR *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, OLECHAR const*>::value )); + + rng_t rng(OLESTR("hello CComBSTR range!")); + BOOST_CHECK( brdm::test_equals(rng, std::string("hello CComBSTR range!")) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); + + (void)sample; // unused +} + + +// simples +// + +template< class Range > +void test_CSimpleArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ATL::CSimpleArray<val_t> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CSimpleMap(const Range& sample) +{ +#if !defined(BOOST_RANGE_ATL_NO_TEST_UNDOCUMENTED_RANGE) + + typedef ATL::CSimpleMap<int, double> rng_t; + + rng_t rng; + rng.Add(3, 3.0); + rng.Add(4, 2.0); + + BOOST_CHECK( boost::begin(rng)->get<0>() == 3.0 ); + BOOST_CHECK( (boost::end(rng)-1)->get<1>() == 2.0 ); + +#endif + + (void)sample; // unused +} + + +template< class Range > +void test_CSimpleValArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ATL::CSimpleArray<val_t> rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +// maps +// + +template< class MapT > +void test_CAtlMap(const MapT& sample) +{ + typedef typename MapT::key_type k_t; + typedef typename MapT::mapped_type m_t; + + typedef ATL::CAtlMap<k_t, m_t> rng_t; + + rng_t rng; + boost::function_requires< boost::ForwardRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(rng, sample) ); + BOOST_CHECK( ::test_atl_map(rng, sample) ); +} + + +template< class MapT > +void test_CRBTree(const MapT& sample) +{ + typedef typename MapT::key_type k_t; + typedef typename MapT::mapped_type m_t; + + typedef ATL::CRBMap<k_t, m_t> derived_t; + typedef ATL::CRBTree<k_t, m_t> rng_t; + + derived_t drng; + rng_t& rng = drng; + + boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(drng, sample) ); + BOOST_CHECK( ::test_atl_map(rng, sample) ); +} + + +template< class MapT > +void test_CRBMap(const MapT& sample) +{ + typedef typename MapT::key_type k_t; + typedef typename MapT::mapped_type m_t; + + typedef ATL::CRBMap<k_t, m_t> rng_t; + + rng_t rng; + boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(rng, sample) ); + BOOST_CHECK( ::test_atl_map(rng, sample) ); +} + + +template< class MapT > +void test_CRBMultiMap(const MapT& sample) +{ + typedef typename MapT::key_type k_t; + typedef typename MapT::mapped_type m_t; + + typedef ATL::CRBMultiMap<k_t, m_t> rng_t; + + rng_t rng; + boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >(); + BOOST_CHECK( ::test_init_atl_multimap(rng, sample) ); + BOOST_CHECK( ::test_atl_map(rng, sample) ); +} + + +// main test +// + +void test_atl() +{ + + // ordinary ranges + // + { + std::string sample("rebecca judy and mary whiteberry chat monchy"); +#if !(_ATL_VER < 0x0700) + ::test_CAtlArray(sample); + ::test_CAtlList(sample); + ::test_CSimpleStringT(sample); + ::test_CFixedStringT<44>(sample); + ::test_CStringT(sample); + ::test_CStaticString(sample); +#endif + ::test_CComBSTR(sample); + ::test_CSimpleArray(sample); + ::test_CSimpleMap(sample); + ::test_CSimpleValArray(sample); + } + + + { + std::wstring sample(L"rebecca judy and mary whiteberry chat monchy"); +#if !(_ATL_VER < 0x0700) + ::test_CAtlArray(sample); + ::test_CAtlList(sample); + ::test_CSimpleStringT(sample); + ::test_CFixedStringT<44>(sample); + ::test_CStringT(sample); + ::test_CStaticString(sample); +#endif + ::test_CComBSTR(sample); + ::test_CSimpleArray(sample); + ::test_CSimpleMap(sample); + ::test_CSimpleValArray(sample); + } + + // pointer ranges + // +#if !(_ATL_VER < 0x0700) + { + typedef ATL::CAutoPtr<int> ptr_t; + ptr_t + ptr0(new int(3)), ptr1(new int(4)), ptr2(new int(5)), ptr3(new int(4)), + ptr4(new int(1)), ptr5(new int(2)), ptr6(new int(4)), ptr7(new int(0)); + + ptr_t ptrs[8] = { + ptr0, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7 + }; + + boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8); + ::test_CAutoPtrArray<int>(workaround); + } + + { + typedef ATL::CAutoPtr<int> ptr_t; + ptr_t + ptr0(new int(3)), ptr1(new int(4)), ptr2(new int(5)), ptr3(new int(4)), + ptr4(new int(1)), ptr5(new int(2)), ptr6(new int(4)), ptr7(new int(0)); + + ptr_t ptrs[8] = { + ptr0, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7 + }; + + boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8); + ::test_CAutoPtrList<int>(workaround); + } + + { + typedef ATL::CHeapPtr<int> ptr_t; + ptr_t ptrs[5]; { + ptrs[0].AllocateBytes(sizeof(int)); + ptrs[1].AllocateBytes(sizeof(int)); + ptrs[2].AllocateBytes(sizeof(int)); + ptrs[3].AllocateBytes(sizeof(int)); + ptrs[4].AllocateBytes(sizeof(int)); + } + + boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+5); + ::test_CHeapPtrList<int>(workaround); + } + + + { + typedef ATL::CComQIPtr<IDispatch> ptr_t; + ptr_t ptrs[8]; + + boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8); + ::test_CInterfaceArray<IDispatch>(workaround); + ::test_CInterfaceList<IDispatch>(workaround); + } +#endif + + // maps + // + { +#if !(_ATL_VER < 0x0700) + std::map<int, std::string> sample; { + sample[0] = "hello"; + sample[1] = "range"; + sample[2] = "atl"; + sample[3] = "mfc"; + sample[4] = "collections"; + } + + ::test_CAtlMap(sample); + ::test_CRBTree(sample); + ::test_CRBMap(sample); + ::test_CRBMultiMap(sample); +#endif + } + + +} // test_atl + + +#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("ATL Range Test Suite"); + test->add(BOOST_TEST_CASE(&test_atl)); + + (void)argc, (void)argv; // unused + return test; +} diff --git a/src/boost/libs/range/test/begin.cpp b/src/boost/libs/range/test/begin.cpp new file mode 100644 index 00000000..f0145351 --- /dev/null +++ b/src/boost/libs/range/test/begin.cpp @@ -0,0 +1,119 @@ +// 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/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__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/begin.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/included/unit_test.hpp> + +namespace mock_std +{ + template<class SinglePassRange> + inline BOOST_DEDUCED_TYPENAME boost::range_iterator<SinglePassRange>::type + begin(SinglePassRange& rng) + { + return rng.begin(); + } + + template<class SinglePassRange> + inline BOOST_DEDUCED_TYPENAME boost::range_iterator<const SinglePassRange>::type + begin(const SinglePassRange& rng) + { + return rng.begin(); + } + + template<class SinglePassRange> + void mock_algorithm_using_begin(const SinglePassRange& rng) + { + BOOST_CHECK( begin(rng) == rng.begin() ); + } + + template<class SinglePassRange> + void mock_algorithm_using_begin(SinglePassRange& rng) + { + BOOST_CHECK( begin(rng) == rng.begin() ); + } +} + +namespace boost +{ +#ifdef BOOST_RANGE_SIMULATE_BEGIN_WITHOUT_ADL_NAMESPACE_BARRIER + template<class SinglePassRange> + inline BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type + begin(SinglePassRange& rng) + { + return rng.begin(); + } + + template<class SinglePassRange> + inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type + begin(const SinglePassRange& rng) + { + return rng.begin(); + } +#endif + + class MockTestBeginCollection + { + public: + typedef char value_type; + typedef const char* const_pointer; + typedef char* pointer; + typedef const_pointer const_iterator; + typedef pointer iterator; + + MockTestBeginCollection() + : m_first() + , m_last() + { + } + + const_iterator begin() const { return m_first; } + iterator begin() { return m_first; } + const_iterator end() const { return m_last; } + iterator end() { return m_last; } + + private: + iterator m_first; + iterator m_last; + }; +} + +namespace +{ + void test_range_begin() + { + boost::MockTestBeginCollection c; + const boost::MockTestBeginCollection& const_c = c; + mock_std::mock_algorithm_using_begin(const_c); + mock_std::mock_algorithm_using_begin(c); + } +} + +using boost::unit_test::test_suite; + +boost::unit_test::test_suite* +init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - begin() ADL namespace barrier" ); + + test->add( BOOST_TEST_CASE( &test_range_begin ) ); + + return test; +} + + diff --git a/src/boost/libs/range/test/category.cpp b/src/boost/libs/range/test/category.cpp new file mode 100644 index 00000000..154c411e --- /dev/null +++ b/src/boost/libs/range/test/category.cpp @@ -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/ +// + +#include <boost/range/category.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_category() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::iterator_category<cont::const_iterator>::type, + boost::range_category<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::iterator_category<cont::const_iterator>::type, + boost::range_category<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::iterator_category<cont::const_iterator>::type, + boost::range_category<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_category meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_category)); + + return test; +} diff --git a/src/boost/libs/range/test/combine.cpp b/src/boost/libs/range/test/combine.cpp new file mode 100644 index 00000000..11f674b5 --- /dev/null +++ b/src/boost/libs/range/test/combine.cpp @@ -0,0 +1,160 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014 +// +// 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/combine.hpp> + +#include <boost/range/algorithm_ext/push_back.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/foreach.hpp> +#include <vector> + +namespace boost_range_test +{ + namespace + { + +template<typename ContRef1, typename ContRef2> +void test_combine2() +{ + std::vector<int> v; + std::list<int> l; + + for (int i = 0; i < 10; ++i) + { + v.push_back(i); + l.push_back(i * 2); + } + + ContRef1& in1 = v; + ContRef2& in2 = l; + + std::vector<boost::tuple<int,int> > output; + boost::push_back(output, boost::combine(in1, in2)); + + int index = 0; + int i1, i2; + BOOST_FOREACH(boost::tie(i1,i2), output) + { + BOOST_CHECK_EQUAL(i1, index); + BOOST_CHECK_EQUAL(i2, index * 2); + ++index; + } +} + +template<typename ContRef1, typename ContRef2, typename ContRef3> +void test_combine3() +{ + std::vector<int> v1; + std::vector<int> v2; + std::vector<int> v3; + + for (int i = 0; i < 10; ++i) + { + v1.push_back(i); + v2.push_back(i * 2); + v3.push_back(i * 3); + } + + ContRef1& in1 = v1; + ContRef2& in2 = v2; + ContRef3& in3 = v3; + + std::vector<boost::tuple<int,int,int> > output; + boost::push_back(output, boost::combine(in1, in2, in3)); + + int index = 0; + int i1, i2, i3; + + BOOST_FOREACH(boost::tie(i1,i2,i3), output) + { + BOOST_CHECK_EQUAL(i1, index); + BOOST_CHECK_EQUAL(i2, index * 2); + BOOST_CHECK_EQUAL(i3, index * 3); + ++index; + } +} + + } // 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 combine() test suite" ); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine2< + const std::vector<int>, const std::list<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine2< + const std::vector<int>, std::list<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine2< + std::vector<int>, const std::list<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine2< + std::vector<int>, std::list<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + std::vector<int>, + std::vector<int>, + std::vector<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + std::vector<int>, + std::vector<int>, + const std::vector<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + std::vector<int>, + const std::vector<int>, + std::vector<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + std::vector<int>, + const std::vector<int>, + const std::vector<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + const std::vector<int>, + std::vector<int>, + std::vector<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + const std::vector<int>, + std::vector<int>, + const std::vector<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + const std::vector<int>, + const std::vector<int>, + std::vector<int> >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + const std::vector<int>, + const std::vector<int>, + const std::vector<int> >))); + + return test; +} diff --git a/src/boost/libs/range/test/compat2.cpp b/src/boost/libs/range/test/compat2.cpp new file mode 100644 index 00000000..feaa047b --- /dev/null +++ b/src/boost/libs/range/test/compat2.cpp @@ -0,0 +1,75 @@ +// 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/static_assert.hpp> +#include <boost/type_traits.hpp> +#include <boost/concept_check.hpp> +#include <boost/config.hpp> + +enum Container {}; +enum String {}; + +template< typename T > +struct range_iterator; + +template<> +struct range_iterator<Container> +{ + template< typename C > + struct pts + { + typedef BOOST_DEDUCED_TYPENAME C::iterator type; + }; +}; + +template<> +struct range_iterator<String> +{ + template< typename C > + struct pts + { + typedef C type; + }; +}; + +template< typename C > +class iterator_of +{ +public: + typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::BOOST_NESTED_TEMPLATE pts<C>::type type; +}; + +#include <vector> + +void compat1() +{ + std::vector<int> v; + iterator_of< std::vector<int> >::type i = v.begin(); + boost::ignore_unused_variable_warning(i); +} + +#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( &compat1 ) ); + + return test; +} + + + + + + diff --git a/src/boost/libs/range/test/compat3.cpp b/src/boost/libs/range/test/compat3.cpp new file mode 100644 index 00000000..e4e4c834 --- /dev/null +++ b/src/boost/libs/range/test/compat3.cpp @@ -0,0 +1,75 @@ +// 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/static_assert.hpp> +#include <boost/type_traits.hpp> +#include <boost/concept_check.hpp> +#include <boost/config.hpp> + +enum Container {}; +enum String {}; + +template< typename T > +struct range_iterator; + +template<> +struct range_iterator<Container> +{ + template< typename C > + struct pts + { + typedef BOOST_DEDUCED_TYPENAME C::iterator type; + }; +}; + +template<> +struct range_iterator<String> +{ + template< typename C > + struct pts + { + typedef C type; + }; +}; + +template< typename C > +class iterator_of +{ +public: + typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>:: template pts<C>::type type; +}; + +#include <vector> + +void compat1() +{ + std::vector<int> v; + iterator_of< std::vector<int> >::type i = v.begin(); + boost::ignore_unused_variable_warning(i); +} + +#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( &compat1 ) ); + + return test; +} + + + + + + diff --git a/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept.cpp b/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept.cpp new file mode 100644 index 00000000..e67215df --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept.cpp @@ -0,0 +1,39 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/adjacent_filtered.hpp> + +namespace +{ + +struct always_true +{ + typedef bool result_type; + + bool operator()(int, int) const + { + return true; + } +}; + +} // anonymous namespace + +int main(int, const char**) +{ + using boost::range::unit_test::mock_range; + using boost::adaptors::adjacent_filtered; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adjacent_filtered adaptor takes at least a + // ForwardRange. + return (mock_range<boost::single_pass_traversal_tag>() | + adjacent_filtered(always_true())).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept2.cpp b/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept2.cpp new file mode 100644 index 00000000..160f7c9d --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept2.cpp @@ -0,0 +1,39 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/adjacent_filtered.hpp> + +namespace +{ + +struct always_true +{ + typedef bool result_type; + + bool operator()(int, int) const + { + return true; + } +}; + +} // anonymous namespace + +int main(int, const char**) +{ + using boost::range::unit_test::mock_const_range; + using boost::adaptors::adjacent_filtered; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adjacent_filtered adaptor takes at least a + // ForwardRange. + return (mock_const_range<boost::single_pass_traversal_tag>() | + adjacent_filtered(always_true())).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept3.cpp b/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept3.cpp new file mode 100644 index 00000000..310ac21c --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept3.cpp @@ -0,0 +1,40 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/adjacent_filtered.hpp> + +namespace +{ + +struct always_true +{ + typedef bool result_type; + + bool operator()(int, int) const + { + return true; + } +}; + +} // anonymous namespace + +int main(int, const char**) +{ + using boost::range::unit_test::mock_range; + using boost::adaptors::adjacent_filter; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adjacent_filtered adaptor takes at least a + // ForwardRange. + return adjacent_filter( + mock_range<boost::single_pass_traversal_tag>(), + always_true()).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept4.cpp b/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept4.cpp new file mode 100644 index 00000000..f84b31ec --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/adjacent_filtered_concept4.cpp @@ -0,0 +1,40 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/adjacent_filtered.hpp> + +namespace +{ + +struct always_true +{ + typedef bool result_type; + + bool operator()(int, int) const + { + return true; + } +}; + +} // anonymous namespace + +int main(int, const char**) +{ + using boost::range::unit_test::mock_const_range; + using boost::adaptors::adjacent_filter; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adjacent_filtered adaptor takes at least a + // ForwardRange. + return adjacent_filter( + mock_const_range<boost::single_pass_traversal_tag>(), + always_true()).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/copied_concept.cpp b/src/boost/libs/range/test/compile_fail/adaptor/copied_concept.cpp new file mode 100644 index 00000000..27e7f72d --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/copied_concept.cpp @@ -0,0 +1,24 @@ +// 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 "mock_range.hpp" +#include <boost/iterator/iterator_categories.hpp> +#include <boost/range/adaptor/copied.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_range; + using boost::adaptors::copied; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a RandomAccessRange. + return (mock_range<boost::bidirectional_traversal_tag>() | + copied(0,1)).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/copied_concept2.cpp b/src/boost/libs/range/test/compile_fail/adaptor/copied_concept2.cpp new file mode 100644 index 00000000..5df8ab6b --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/copied_concept2.cpp @@ -0,0 +1,24 @@ +// 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 "mock_range.hpp" +#include <boost/iterator/iterator_categories.hpp> +#include <boost/range/adaptor/copied.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_const_range; + using boost::adaptors::copied; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a RandomAccessRange. + return (mock_const_range<boost::bidirectional_traversal_tag>() | + copied(0,1)).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/copied_concept3.cpp b/src/boost/libs/range/test/compile_fail/adaptor/copied_concept3.cpp new file mode 100644 index 00000000..da1659fb --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/copied_concept3.cpp @@ -0,0 +1,23 @@ +// 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 "mock_range.hpp" +#include <boost/iterator/iterator_categories.hpp> +#include <boost/range/adaptor/copied.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_range; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a RandomAccessRange. + return boost::adaptors::copy( + mock_range<boost::bidirectional_traversal_tag>(), 0, 1).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/copied_concept4.cpp b/src/boost/libs/range/test/compile_fail/adaptor/copied_concept4.cpp new file mode 100644 index 00000000..3df0a6c4 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/copied_concept4.cpp @@ -0,0 +1,24 @@ +// 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 "mock_range.hpp" +#include <boost/iterator/iterator_categories.hpp> +#include <boost/range/adaptor/copied.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_const_range; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a RandomAccessRange. + return boost::adaptors::copy( + mock_const_range<boost::bidirectional_traversal_tag>(), + 0, 1).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/mock_iterator.hpp b/src/boost/libs/range/test/compile_fail/adaptor/mock_iterator.hpp new file mode 100644 index 00000000..97f67a91 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/mock_iterator.hpp @@ -0,0 +1,82 @@ +// 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 +// +#ifndef BOOST_RANGE_UNIT_TEST_ADAPTOR_MOCK_ITERATOR_HPP_INCLUDED +#define BOOST_RANGE_UNIT_TEST_ADAPTOR_MOCK_ITERATOR_HPP_INCLUDED + +#include <boost/iterator/iterator_facade.hpp> + +namespace boost +{ + namespace range + { + namespace unit_test + { + +template<typename TraversalTag> +class mock_iterator + : public boost::iterator_facade< + mock_iterator<TraversalTag>, + int, + TraversalTag, + const int& + > +{ +public: + mock_iterator() + : m_value(0) + { + } + + explicit mock_iterator(int value) + : m_value(value) + { + } + +private: + + void increment() + { + ++m_value; + } + + void decrement() + { + --m_value; + } + + bool equal(const mock_iterator& other) const + { + return m_value == other.m_value; + } + + void advance(std::ptrdiff_t offset) + { + m_value += offset; + } + + std::ptrdiff_t distance_to(const mock_iterator& other) const + { + return other.m_value - m_value; + } + + const int& dereference() const + { + return m_value; + } + + int m_value; + friend class boost::iterator_core_access; +}; + + } // namespace unit_test + } // namespace range +} // namespace boost + +#endif // include guard diff --git a/src/boost/libs/range/test/compile_fail/adaptor/mock_range.hpp b/src/boost/libs/range/test/compile_fail/adaptor/mock_range.hpp new file mode 100644 index 00000000..18fe2fa3 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/mock_range.hpp @@ -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) +// +// For more information, see http://www.boost.org/libs/range +// +#ifndef BOOST_RANGE_UNIT_TEST_ADAPTOR_MOCK_RANGE_HPP_INCLUDED +#define BOOST_RANGE_UNIT_TEST_ADAPTOR_MOCK_RANGE_HPP_INCLUDED + +#include "mock_iterator.hpp" +#include <boost/range/iterator_range_core.hpp> + +namespace boost +{ + namespace range + { + namespace unit_test + { + +// Make a non-empty range that models the corresponding range concept. +// This is only useful in unit tests. It is main use is to help test concepts +// assertions are present. +template<typename TraversalTag> +iterator_range<mock_iterator<TraversalTag> >& + mock_range() +{ + static iterator_range<mock_iterator<TraversalTag> > instance( + mock_iterator<TraversalTag>(0), + mock_iterator<TraversalTag>(1)); + return instance; +} + +template<typename TraversalTag> +const iterator_range<mock_iterator<TraversalTag> >& + mock_const_range() +{ + static iterator_range<mock_iterator<TraversalTag> > instance( + mock_iterator<TraversalTag>(0), + mock_iterator<TraversalTag>(1)); + return instance; +} + + } // namespace unit_test + } // namespace range +} // namespace boost + +#endif // include guard diff --git a/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept.cpp b/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept.cpp new file mode 100644 index 00000000..5ad00419 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept.cpp @@ -0,0 +1,23 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/reversed.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_range; + using boost::adaptors::reversed; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a BidirectionalRange. + return (mock_range<boost::forward_traversal_tag>() | reversed).front(); +} + diff --git a/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept2.cpp b/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept2.cpp new file mode 100644 index 00000000..e2b8cb6f --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept2.cpp @@ -0,0 +1,23 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/reversed.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_const_range; + using boost::adaptors::reversed; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a BidirectionalRange. + return (mock_const_range<boost::forward_traversal_tag>() | reversed).front(); +} + diff --git a/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept3.cpp b/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept3.cpp new file mode 100644 index 00000000..619dfa8a --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept3.cpp @@ -0,0 +1,23 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/reversed.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_range; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a BidirectionalRange. + return boost::adaptors::reverse( + mock_range<boost::forward_traversal_tag>()).front(); +} + diff --git a/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept4.cpp b/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept4.cpp new file mode 100644 index 00000000..0e183eea --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/reversed_concept4.cpp @@ -0,0 +1,23 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/reversed.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_const_range; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a BidirectionalRange. + return boost::adaptors::reverse( + mock_const_range<boost::forward_traversal_tag>()).front(); +} + diff --git a/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept.cpp b/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept.cpp new file mode 100644 index 00000000..08a653f4 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept.cpp @@ -0,0 +1,23 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/sliced.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_range; + using boost::adaptors::sliced; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a RandomAccessRange. + return (mock_range<boost::bidirectional_traversal_tag>() | + sliced(0,1)).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept2.cpp b/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept2.cpp new file mode 100644 index 00000000..99650203 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept2.cpp @@ -0,0 +1,23 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/sliced.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_const_range; + using boost::adaptors::sliced; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a RandomAccessRange. + return (mock_const_range<boost::bidirectional_traversal_tag>() | + sliced(0,1)).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept3.cpp b/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept3.cpp new file mode 100644 index 00000000..12749113 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept3.cpp @@ -0,0 +1,22 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/sliced.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_range; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a RandomAccessRange. + return boost::adaptors::slice( + mock_range<boost::bidirectional_traversal_tag>(), 0, 1).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept4.cpp b/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept4.cpp new file mode 100644 index 00000000..c7f8206a --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/sliced_concept4.cpp @@ -0,0 +1,22 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/sliced.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_const_range; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a RandomAccessRange. + return boost::adaptors::slice( + mock_const_range<boost::bidirectional_traversal_tag>(), 0, 1).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept.cpp b/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept.cpp new file mode 100644 index 00000000..bbaaf118 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept.cpp @@ -0,0 +1,22 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/uniqued.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_range; + using boost::adaptors::uniqued; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a ForwardRange. + return (mock_range<boost::single_pass_traversal_tag>() | uniqued).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept2.cpp b/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept2.cpp new file mode 100644 index 00000000..a390d136 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept2.cpp @@ -0,0 +1,23 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/uniqued.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_const_range; + using boost::adaptors::uniqued; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a ForwardRange. + return (mock_const_range<boost::single_pass_traversal_tag>() | + uniqued).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept3.cpp b/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept3.cpp new file mode 100644 index 00000000..fea058cc --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept3.cpp @@ -0,0 +1,22 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/uniqued.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_range; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a ForwardRange. + return boost::adaptors::unique( + mock_range<boost::single_pass_traversal_tag>()).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept4.cpp b/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept4.cpp new file mode 100644 index 00000000..1e023904 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/adaptor/uniqued_concept4.cpp @@ -0,0 +1,22 @@ +// 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 "mock_range.hpp" +#include <boost/range/adaptor/uniqued.hpp> + +int main(int, const char**) +{ + using boost::range::unit_test::mock_const_range; + + // This next line should fail when Boost.Range concept checking is + // enabled since the adaptor takes at least a ForwardRange. + return boost::adaptors::unique( + mock_const_range<boost::single_pass_traversal_tag>()).front(); +} diff --git a/src/boost/libs/range/test/compile_fail/iterator_range1.cpp b/src/boost/libs/range/test/compile_fail/iterator_range1.cpp new file mode 100644 index 00000000..2e5eec37 --- /dev/null +++ b/src/boost/libs/range/test/compile_fail/iterator_range1.cpp @@ -0,0 +1,22 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. 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/iterator_range_core.hpp> + +namespace iterator_range_test_detail +{ + void check_iterator_range_doesnt_convert_pointers() + { + double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 }; + boost::iterator_range<float*> rng = boost::make_iterator_range(source); + boost::ignore_unused_variable_warning(rng); + } +} + diff --git a/src/boost/libs/range/test/const_iterator.cpp b/src/boost/libs/range/test/const_iterator.cpp new file mode 100644 index 00000000..63238c88 --- /dev/null +++ b/src/boost/libs/range/test/const_iterator.cpp @@ -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/ +// + +#include <boost/range/const_iterator.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_const_iterator() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_iterator, + boost::range_const_iterator<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_iterator, + boost::range_const_iterator<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_iterator, + boost::range_const_iterator<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_const_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_const_iterator)); + + return test; +} diff --git a/src/boost/libs/range/test/const_ranges.cpp b/src/boost/libs/range/test/const_ranges.cpp new file mode 100644 index 00000000..22bf83ce --- /dev/null +++ b/src/boost/libs/range/test/const_ranges.cpp @@ -0,0 +1,59 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // suppress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#include <boost/range.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <string> + +template< class T > +const T& as_const( const T& r ) +{ + return r; +} + +void check_const_ranges() +{ + std::string foo( "foo" ); + const std::string bar( "bar" ); + + BOOST_CHECK( boost::const_begin( foo ) == boost::begin( as_const( foo ) ) ); + BOOST_CHECK( boost::const_end( foo ) == boost::end( as_const( foo ) ) ); + BOOST_CHECK( boost::const_rbegin( foo ) == boost::rbegin( as_const( foo ) ) ); + BOOST_CHECK( boost::const_rend( foo ) == boost::rend( as_const( foo ) ) ); + + BOOST_CHECK( boost::const_begin( bar ) == boost::begin( as_const( bar ) ) ); + BOOST_CHECK( boost::const_end( bar ) == boost::end( as_const( bar ) ) ); + BOOST_CHECK( boost::const_rbegin( bar ) == boost::rbegin( as_const( bar ) ) ); + BOOST_CHECK( boost::const_rend( bar ) == boost::rend( as_const( bar ) ) ); + +} + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); + + test->add( BOOST_TEST_CASE( &check_const_ranges ) ); + + return test; +} + + + + + diff --git a/src/boost/libs/range/test/const_reverse_iterator.cpp b/src/boost/libs/range/test/const_reverse_iterator.cpp new file mode 100644 index 00000000..44726fd8 --- /dev/null +++ b/src/boost/libs/range/test/const_reverse_iterator.cpp @@ -0,0 +1,62 @@ +// 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/const_reverse_iterator.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_const_reverse_iterator() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator<cont::const_iterator>, + boost::range_const_reverse_iterator<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator<cont::const_iterator>, + boost::range_const_reverse_iterator<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator<cont::const_iterator>, + boost::range_const_reverse_iterator<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE( + "Boost.Range range_const_reverse_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_const_reverse_iterator)); + + return test; +} diff --git a/src/boost/libs/range/test/counting_range.cpp b/src/boost/libs/range/test/counting_range.cpp new file mode 100644 index 00000000..d1f1d3f5 --- /dev/null +++ b/src/boost/libs/range/test/counting_range.cpp @@ -0,0 +1,90 @@ +// 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/ +// +// Disable a warning from <xutility> since this noise might +// stop us detecting a problem in our code. +#include <boost/range/counting_range.hpp> +#include <boost/range/adaptor/indirected.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 counting_range_test_impl(int first, int last) + { + Container reference; + for (int i = first; i < last; ++i) + reference.push_back(i); + + Container test; + push_back( test, counting_range(first, last) ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test.begin(), test.end()); + } + + template<class Container> + void counting_range_test_impl() + { + counting_range_test_impl<Container>(0, 0); + counting_range_test_impl<Container>(-1, -1); + counting_range_test_impl<Container>(-1, 0); + counting_range_test_impl<Container>(0, 1); + counting_range_test_impl<Container>(-100, 100); + counting_range_test_impl<Container>(50, 55); + } + + void counting_range_test_range() + { + std::vector<int> v; + for (int i = 0; i < 10; ++i) + v.push_back(i); + + std::vector<std::vector<int>::iterator> x; + push_back(x, counting_range(v)); + + std::vector<int> t; + push_back(t, x | boost::adaptors::indirected); + + BOOST_CHECK_EQUAL_COLLECTIONS(t.begin(), t.end(), + v.begin(), v.end()); + } + } + + void counting_range_test() + { + counting_range_test_impl<std::vector<int> >(); + counting_range_test_impl<std::list<int> >(); + counting_range_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.counting_range" ); + + test->add( BOOST_TEST_CASE( &boost::counting_range_test ) ); + + return test; +} diff --git a/src/boost/libs/range/test/difference_type.cpp b/src/boost/libs/range/test/difference_type.cpp new file mode 100644 index 00000000..556250ac --- /dev/null +++ b/src/boost/libs/range/test/difference_type.cpp @@ -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/ +// + +#include <boost/range/difference_type.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_difference() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::difference_type, + boost::range_difference<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::difference_type, + boost::range_difference<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::difference_type, + boost::range_difference<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_difference meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_difference)); + + return test; +} diff --git a/src/boost/libs/range/test/end.cpp b/src/boost/libs/range/test/end.cpp new file mode 100644 index 00000000..c8855552 --- /dev/null +++ b/src/boost/libs/range/test/end.cpp @@ -0,0 +1,119 @@ +// 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/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__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/end.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/included/unit_test.hpp> + +namespace mock_std +{ + template<class SinglePassRange> + inline BOOST_DEDUCED_TYPENAME boost::range_iterator<SinglePassRange>::type + end(SinglePassRange& rng) + { + return rng.end(); + } + + template<class SinglePassRange> + inline BOOST_DEDUCED_TYPENAME boost::range_iterator<const SinglePassRange>::type + end(const SinglePassRange& rng) + { + return rng.end(); + } + + template<class SinglePassRange> + void mock_algorithm_using_end(const SinglePassRange& rng) + { + BOOST_CHECK( end(rng) == rng.end() ); + } + + template<class SinglePassRange> + void mock_algorithm_using_end(SinglePassRange& rng) + { + BOOST_CHECK( end(rng) == rng.end() ); + } +} + +namespace boost +{ +#ifdef BOOST_RANGE_SIMULATE_END_WITHOUT_ADL_NAMESPACE_BARRIER + template<class SinglePassRange> + inline BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type + end(SinglePassRange& rng) + { + return rng.end(); + } + + template<class SinglePassRange> + inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type + end(const SinglePassRange& rng) + { + return rng.end(); + } +#endif + + class MockTestEndCollection + { + public: + typedef char value_type; + typedef const char* const_pointer; + typedef char* pointer; + typedef const_pointer const_iterator; + typedef pointer iterator; + + MockTestEndCollection() + : m_first() + , m_last() + { + } + + const_iterator begin() const { return m_first; } + iterator begin() { return m_first; } + const_iterator end() const { return m_last; } + iterator end() { return m_last; } + + private: + iterator m_first; + iterator m_last; + }; +} + +namespace +{ + void test_range_end_adl_avoidance() + { + boost::MockTestEndCollection c; + const boost::MockTestEndCollection& const_c = c; + mock_std::mock_algorithm_using_end(const_c); + mock_std::mock_algorithm_using_end(c); + } +} + +using boost::unit_test::test_suite; + +boost::unit_test::test_suite* +init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - end() ADL namespace barrier" ); + + test->add( BOOST_TEST_CASE( &test_range_end_adl_avoidance ) ); + + return test; +} + + diff --git a/src/boost/libs/range/test/extension_mechanism.cpp b/src/boost/libs/range/test/extension_mechanism.cpp new file mode 100644 index 00000000..b8b71127 --- /dev/null +++ b/src/boost/libs/range/test/extension_mechanism.cpp @@ -0,0 +1,109 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // suppress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#include <boost/range.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <vector> + +// +// Generic range algorithm +// +template< class Rng > +typename boost::range_iterator<Rng>::type foo_algo( Rng& r ) +{ + // + // This will only compile for Rng = UDT if the qualified calls + // find boost_range_XXX via ADL. + // + return boost::size(r) == 0u ? boost::begin(r) : boost::end(r); +} + +namespace Foo +{ + // + // Our sample UDT + // + struct X + { + X() : vec() { } + + typedef std::vector<int> data_t; + typedef data_t::iterator iterator; + typedef data_t::const_iterator const_iterator; + + data_t vec; + + void push_back( int i ) + { vec.push_back(i); } + }; + + // + // The required functions. No type-traits need + // to be defined because X defines the proper set of + // nested types. + // + inline X::iterator range_begin( X& x ) + { + return x.vec.begin(); + } + + + inline X::const_iterator range_begin( const X& x ) + { + return x.vec.begin(); + } + + + inline X::iterator range_end( X& x ) + { + return x.vec.end(); + } + + inline X::const_iterator range_end( const X& x ) + { + return x.vec.end(); + } + +} + +void check_extension() +{ + Foo::X x; + x.push_back(3); + const Foo::X x2; + + foo_algo( x ); + foo_algo( x2 ); +} + +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_extension ) ); + + return test; +} + + + + + diff --git a/src/boost/libs/range/test/extension_size.cpp b/src/boost/libs/range/test/extension_size.cpp new file mode 100644 index 00000000..b9cc1b24 --- /dev/null +++ b/src/boost/libs/range/test/extension_size.cpp @@ -0,0 +1,224 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // suppress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#include <boost/range.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/static_assert.hpp> +#include <boost/cstdint.hpp> +#include <list> +#include <vector> + +namespace boost_range_extension_size_test +{ + class FooWithoutSize + { + typedef std::list<int> impl_t; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::range_size<std::list<int> >::type, + std::list<int>::size_type + >::value)); + + typedef impl_t::const_iterator const_iterator; + typedef impl_t::iterator iterator; + + public: + friend inline const_iterator range_begin(const FooWithoutSize& obj) { return obj.m_impl.begin(); } + friend inline iterator range_begin(FooWithoutSize& obj) { return obj.m_impl.begin(); } + friend inline const_iterator range_end(const FooWithoutSize& obj) { return obj.m_impl.end(); } + friend inline iterator range_end(FooWithoutSize& obj){ return obj.m_impl.end(); } + + private: + impl_t m_impl; + }; + + template<typename SizeType> + class FooWithSize + { + public: + typedef SizeType size_type; + typedef boost::uint8_t* iterator; + typedef const boost::uint8_t* const_iterator; + + const_iterator begin() const; + iterator begin(); + const_iterator end() const; + iterator end(); + }; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::uint8_t, + boost::range_size<FooWithSize<boost::uint8_t> >::type + >::value + )); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::uint16_t, + boost::range_size<FooWithSize<boost::uint16_t> >::type + >::value + )); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::uint32_t, + boost::range_size<FooWithSize<boost::uint32_t> >::type + >::value + )); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::uint64_t, + boost::range_size<FooWithSize<boost::uint64_t> >::type + >::value + )); + + class UdtSizeType + { + public: + typedef boost::uint16_t value_type; + + UdtSizeType() : value_(0) { } + UdtSizeType(value_type value) : value_(value) { } + + operator value_type() const { return value_; } + + private: + value_type value_; + }; + + BOOST_STATIC_ASSERT(( + boost::is_same< + UdtSizeType, + boost::range_size<FooWithSize<UdtSizeType> >::type + >::value + )); + + class Foo2WithoutSize + { + public: + struct const_iterator + { + typedef std::forward_iterator_tag iterator_category; + typedef boost::int8_t difference_type; + typedef boost::int16_t value_type; + typedef value_type* pointer; + typedef value_type& reference; + + reference operator*() const; + pointer operator->() const; + const_iterator& operator++(); + const_iterator operator++(int); + bool operator==(const const_iterator&) const; + bool operator!=(const const_iterator&) const; + }; + + struct iterator : const_iterator + { + typedef const value_type* pointer; + typedef const value_type& reference; + + reference operator*() const; + pointer operator->() const; + + iterator& operator++(); + iterator operator++(int); + + bool operator==(const iterator&) const; + bool operator!=(const iterator&) const; + }; + + const_iterator begin() const; + iterator begin(); + const_iterator end() const; + iterator end(); + }; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::uint8_t, + boost::range_size< + ::boost_range_extension_size_test::Foo2WithoutSize>::type + >::value + )); +} + +namespace boost +{ + template<> struct range_iterator<const ::boost_range_extension_size_test::FooWithoutSize> + { + typedef std::list<int>::const_iterator type; + }; + + template<> struct range_iterator< ::boost_range_extension_size_test::FooWithoutSize> + { + typedef std::list<int>::iterator type; + }; +} + +namespace boost_range_extension_size_test +{ + inline boost::range_size<FooWithoutSize>::type + range_calculate_size(const FooWithoutSize& rng) + { + return 2u; + } +} + +BOOST_STATIC_ASSERT(( + boost::is_same< + boost::make_unsigned<std::ptrdiff_t>::type, + boost::range_size< + boost_range_extension_size_test::FooWithoutSize>::type + >::value +)); + +typedef boost::make_unsigned<std::ptrdiff_t>::type t1; +typedef boost::range_size<boost_range_extension_size_test::FooWithoutSize>::type t1; + +namespace +{ + +void check_size_works_with_random_access() +{ + std::vector<int> container; + container.push_back(1); + BOOST_CHECK_EQUAL( boost::size(container), 1u ); +} + +void check_extension_size() +{ + BOOST_CHECK_EQUAL( boost::size(boost_range_extension_size_test::FooWithoutSize()), 2u ); +} + +} // anonymous namespace + +using boost::unit_test::test_suite; + +test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); + + test->add( BOOST_TEST_CASE( &check_size_works_with_random_access )); + test->add( BOOST_TEST_CASE( &check_extension_size ) ); + + return test; +} diff --git a/src/boost/libs/range/test/has_range_iterator.cpp b/src/boost/libs/range/test/has_range_iterator.cpp new file mode 100644 index 00000000..2efc88b0 --- /dev/null +++ b/src/boost/libs/range/test/has_range_iterator.cpp @@ -0,0 +1,68 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#include <boost/range/has_range_iterator.hpp> +#include <boost/config.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace +{ + class MockClassWithoutIterators {}; + + template<typename Container> + void test_has_range_iterator_impl(const bool expected_value) + { + BOOST_CHECK_EQUAL( boost::has_range_iterator<Container>::value, expected_value ); + } + + template<typename Container> + void test_has_range_const_iterator_impl(const bool expected_value) + { + BOOST_CHECK_EQUAL( boost::has_range_const_iterator<Container>::value, expected_value ); + } + + void test_has_range_iterator() + { + test_has_range_iterator_impl< std::vector<int> >(true); + test_has_range_iterator_impl< MockClassWithoutIterators >(false); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + test_has_range_iterator_impl<std::vector<int>&&>(true); + test_has_range_iterator_impl<MockClassWithoutIterators&&>(false); +#endif + } + + void test_has_range_const_iterator() + { + test_has_range_const_iterator_impl< std::vector<int> >(true); + test_has_range_const_iterator_impl< MockClassWithoutIterators >(false); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + test_has_range_const_iterator_impl<std::vector<int>&&>(true); + test_has_range_const_iterator_impl<MockClassWithoutIterators&&>(false); +#endif + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.has_range_iterator" ); + + test->add(BOOST_TEST_CASE(&test_has_range_iterator)); + test->add(BOOST_TEST_CASE(&test_has_range_const_iterator)); + + return test; +} diff --git a/src/boost/libs/range/test/irange.cpp b/src/boost/libs/range/test/irange.cpp new file mode 100644 index 00000000..7e1a5644 --- /dev/null +++ b/src/boost/libs/range/test/irange.cpp @@ -0,0 +1,191 @@ +// 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/irange.hpp> +#include <boost/range/algorithm_ext.hpp> +#include <boost/range/begin.hpp> +#include <boost/range/end.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <vector> + +namespace boost +{ + // Test an integer range with a step size of 1. + template<typename Integer> + void test_irange_impl(Integer last) + { + std::vector<Integer> reference; + for (Integer i = static_cast<Integer>(0); i < last; ++i) + { + reference.push_back(i); + } + + std::vector<Integer> test; + boost::push_back(test, boost::irange(last)); + + BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(), + reference.begin(), reference.end() ); + } + + // Test an integer range with a step size of 1. + template<typename Integer> + void test_irange_impl(Integer first, Integer last) + { + std::vector<Integer> reference; + for (Integer i = first; i < last; ++i) + { + reference.push_back(i); + } + + std::vector<Integer> test; + boost::push_back(test, boost::irange(first, last)); + + BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(), + reference.begin(), reference.end() ); + } + + // Test an integer range with a runtime specified step size. + template<typename Integer, typename IntegerInput> + void test_irange_impl(IntegerInput first, IntegerInput last, int step) + { + BOOST_ASSERT( step != 0 ); + + // Skip tests that have negative values if the type is + // unsigned + if ((static_cast<IntegerInput>(static_cast<Integer>(first)) != first) + || (static_cast<IntegerInput>(static_cast<Integer>(last)) != last)) + return; + + std::vector<Integer> reference; + + const std::ptrdiff_t first_p = static_cast<std::ptrdiff_t>(first); + const std::ptrdiff_t last_p = static_cast<std::ptrdiff_t>(last); + const std::ptrdiff_t step_p = static_cast<std::ptrdiff_t>(step); + for (std::ptrdiff_t current_value = first_p; + step_p >= 0 ? current_value < last_p : current_value > last_p; + current_value += step_p) + reference.push_back(current_value); + + std::vector<Integer> test; + boost::push_back(test, boost::irange(first, last, step)); + + BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(), + reference.begin(), reference.end() ); + } + + // Test driver function that for an integer range [first, last) + // drives the test implementation through various integer + // types. + void test_irange(int last) + { + test_irange_impl<signed char>(last); + test_irange_impl<unsigned char>(last); + test_irange_impl<signed short>(last); + test_irange_impl<unsigned short>(last); + test_irange_impl<signed int>(last); + test_irange_impl<unsigned int>(last); + test_irange_impl<signed long>(last); + test_irange_impl<unsigned long>(last); + } + + + // Test driver function that for an integer range [first, last) + // drives the test implementation through various integer + // types. + void test_irange(int first, int last) + { + test_irange_impl<signed char>(first,last); + test_irange_impl<unsigned char>(first, last); + test_irange_impl<signed short>(first, last); + test_irange_impl<unsigned short>(first, last); + test_irange_impl<signed int>(first, last); + test_irange_impl<unsigned int>(first, last); + test_irange_impl<signed long>(first, last); + test_irange_impl<unsigned long>(first, last); + } + + // Test driver function that for an integer range [first, last) + // drives the test implementation through various integer + // types step_size items at a time. + void test_irange(int first, int last, int step_size) + { + BOOST_ASSERT( step_size != 0 ); + test_irange_impl<signed char>(first, last, step_size); + test_irange_impl<unsigned char>(first, last, step_size); + test_irange_impl<signed short>(first, last, step_size); + test_irange_impl<unsigned short>(first, last, step_size); + test_irange_impl<signed int>(first, last, step_size); + test_irange_impl<unsigned int>(first, last, step_size); + test_irange_impl<signed long>(first, last, step_size); + test_irange_impl<unsigned long>(first, last, step_size); + } + + // Implementation of the unit test for the integer range + // function. + // This starts the test drivers to drive a set of integer types + // for a combination of range values chosen to exercise a large + // number of implementation branches. + void irange_unit_test() + { + // Test the single-step version of irange(last) + test_irange(0); + test_irange(1); + test_irange(10); + + // Test the single-step version of irange(first, last) + test_irange(0, 0); + test_irange(0, 1); + test_irange(0, 10); + test_irange(1, 1); + test_irange(1, 2); + test_irange(1, 11); + + // Test the n-step version of irange(first, last, step-size) + test_irange(0, 0, 1); + test_irange(0, 0, -1); + test_irange(0, 10, 1); + test_irange(10, 0, -1); + test_irange(0, 2, 2); + test_irange(2, 0, -2); + test_irange(0, 9, 2); + test_irange(9, 0, -2); + test_irange(-9, 0, 2); + test_irange(-9, 9, 2); + test_irange(9, -9, -2); + test_irange(10, 20, 5); + test_irange(20, 10, -5); + + test_irange(0, 0, 3); + test_irange(0, 1, 3); + test_irange(0, 2, 3); + test_irange(0, 3, 3); + test_irange(0, 4, 3); + test_irange(0, 10, 3); + + test_irange(0, 0, -3); + test_irange(0, -1, -3); + test_irange(0, -2, -3); + test_irange(0, -3, -3); + test_irange(0, -4, -3); + test_irange(0, -10, -3); + } +} // 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.irange" ); + + test->add(BOOST_TEST_CASE( &boost::irange_unit_test )); + + return test; +} diff --git a/src/boost/libs/range/test/istream_range.cpp b/src/boost/libs/range/test/istream_range.cpp new file mode 100644 index 00000000..7d10313f --- /dev/null +++ b/src/boost/libs/range/test/istream_range.cpp @@ -0,0 +1,58 @@ +// 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/istream_range.hpp> +#include <boost/range/algorithm_ext.hpp> +#include <boost/range/begin.hpp> +#include <boost/range/end.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <sstream> +#include <vector> + +namespace +{ + template <typename CharT> + void test_istream_range_impl() + { + std::basic_stringstream<CharT> s; + std::vector<int> reference; + for (int i = 0; i < 10; ++i) + { + reference.push_back(i); + s << i << CharT(' '); + } + + std::vector<int> target; + boost::push_back(target, boost::range::istream_range<int>(s)); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + target.begin(), target.end() ); + } + + // Test an istream range. + void test_istream_range() + { + test_istream_range_impl<char>(); + test_istream_range_impl<wchar_t>(); + } + +} // namespace 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.istream_range" ); + + test->add(BOOST_TEST_CASE( &test_istream_range )); + + return test; +} diff --git a/src/boost/libs/range/test/iterator.cpp b/src/boost/libs/range/test/iterator.cpp new file mode 100644 index 00000000..76c915a9 --- /dev/null +++ b/src/boost/libs/range/test/iterator.cpp @@ -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/ +// + +#include <boost/range/iterator.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_iterator() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_iterator<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_iterator, + boost::range_iterator<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_iterator<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator)); + + return test; +} diff --git a/src/boost/libs/range/test/iterator_ext.cpp b/src/boost/libs/range/test/iterator_ext.cpp new file mode 100644 index 00000000..820bf2a4 --- /dev/null +++ b/src/boost/libs/range/test/iterator_ext.cpp @@ -0,0 +1,153 @@ +// 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/iterator.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/is_base_of.hpp> +#include <boost/type_traits/decay.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + +struct point +{ + int x; + int y; +}; + +class shape +{ +public: + virtual ~shape() + { + } + + const std::vector<point>& points() const + { + return m_points; + } + +private: + std::vector<point> m_points; +}; + +class rectangle : public shape +{ +}; + +class circle : public shape +{ +}; + +class container +{ + typedef std::vector<point> impl_t; +}; + +} // namespace boost_range_test + +namespace boost +{ + template<typename T> + struct range_mutable_iterator< + T, + typename boost::enable_if< + boost::is_base_of< + boost_range_test::shape, + typename boost::remove_reference< + typename boost::remove_cv<T>::type + >::type + > + >::type + > + { + typedef std::vector<boost_range_test::point>::iterator type; + }; + + template<typename T> + struct range_const_iterator< + T, + typename boost::enable_if< + boost::is_base_of< + boost_range_test::shape, + typename boost::remove_reference< + typename boost::remove_cv<T>::type + >::type + > + >::type + > + { + typedef std::vector<boost_range_test::point>::const_iterator type; + }; + + template<> + struct range_mutable_iterator<boost_range_test::container> + { + typedef std::vector<boost_range_test::point>::iterator type; + }; + + template<> + struct range_const_iterator<boost_range_test::container> + { + typedef std::vector<boost_range_test::point>::const_iterator type; + }; +} + +namespace boost_range_test +{ + template<typename Shape> + void test_iterator_impl() + { + BOOST_STATIC_ASSERT(( + boost::is_same< + std::vector<point>::iterator, + typename boost::range_iterator<Shape>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + std::vector<point>::const_iterator, + typename boost::range_iterator<const Shape>::type + >::value)); + + #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + std::vector<point>::iterator, + typename boost::range_iterator<Shape&&>::type + >::value)); + #endif + } + + void test_iterator() + { + test_iterator_impl<shape>(); + test_iterator_impl<rectangle>(); + test_iterator_impl<circle>(); + + test_iterator_impl<container>(); + } +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator)); + + return test; +} diff --git a/src/boost/libs/range/test/iterator_pair.cpp b/src/boost/libs/range/test/iterator_pair.cpp new file mode 100644 index 00000000..7b615a9f --- /dev/null +++ b/src/boost/libs/range/test/iterator_pair.cpp @@ -0,0 +1,104 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // suppress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#include <boost/range/concepts.hpp> +#include <boost/range/functions.hpp> +#include <boost/range/metafunctions.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits.hpp> +#include <boost/test/test_tools.hpp> +#include <vector> +#include <iterator> +#include <utility> + +void check_iterator_pair() +{ + typedef std::vector<int> vec_t; + vec_t vec; + vec.push_back( 4 ); + typedef std::pair<vec_t::iterator,vec_t::iterator> + pair_t; + typedef std::pair<vec_t::const_iterator,vec_t::const_iterator> + const_pair_t; + typedef const pair_t const_pair_tt; + pair_t pair = std::make_pair( boost::begin( vec ), boost::end( vec ) ); + const_pair_t const_pair = std::make_pair( boost::begin( vec ), boost::end( vec ) ); + const_pair_tt constness_pair( pair ); + + + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value<pair_t>::type, + std::iterator_traits<pair_t::first_type>::value_type>::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<pair_t>::type, pair_t::first_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_const_iterator<pair_t>::type, pair_t::first_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference<pair_t>::type, + std::iterator_traits<pair_t::first_type>::difference_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size<pair_t>::type, std::size_t >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<pair_t>::type, pair_t::first_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const_pair_t>::type, const_pair_t::first_type >::value )); + + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value<const_pair_tt>::type, + std::iterator_traits<const_pair_t::first_type>::value_type>::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value )); + // + // This behavior is not supported with v2. + //BOOST_STATIC_ASSERT(( is_same< range_const_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference<const_pair_tt>::type, + std::iterator_traits<const_pair_tt::first_type>::difference_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size<const_pair_tt>::type, std::size_t >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value )); + + BOOST_CHECK( boost::begin( pair ) == pair.first ); + BOOST_CHECK( boost::end( pair ) == pair.second ); + BOOST_CHECK( boost::empty( pair ) == (pair.first == pair.second) ); + BOOST_CHECK( boost::size( pair ) == + static_cast<std::size_t>( + std::distance(pair.first, pair.second)) ); + + BOOST_CHECK( boost::begin( const_pair ) == const_pair.first ); + BOOST_CHECK( boost::end( const_pair ) == const_pair.second ); + BOOST_CHECK( boost::empty( const_pair ) == (const_pair.first == const_pair.second) ); + BOOST_CHECK( boost::size( const_pair ) == + static_cast<std::size_t>( + std::distance(const_pair.first, const_pair.second)) ); + + BOOST_CHECK( boost::begin( constness_pair ) == constness_pair.first ); + BOOST_CHECK( boost::end( constness_pair ) == constness_pair.second ); + BOOST_CHECK( boost::empty( constness_pair ) == (constness_pair.first == const_pair.second) ); + BOOST_CHECK( boost::size( constness_pair ) == + static_cast<std::size_t>( + std::distance(constness_pair.first, + constness_pair.second)) ); +} + + +#include <boost/test/unit_test.hpp> + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); + + test->add( BOOST_TEST_CASE( &check_iterator_pair ) ); + + return test; +} + + + + + + diff --git a/src/boost/libs/range/test/iterator_range.cpp b/src/boost/libs/range/test/iterator_range.cpp new file mode 100644 index 00000000..9bbcff2b --- /dev/null +++ b/src/boost/libs/range/test/iterator_range.cpp @@ -0,0 +1,330 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen & Larry Evans 2003-2005. 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/as_array.hpp> + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__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/iterator_range.hpp> +#include <boost/range/functions.hpp> +#include <boost/range/as_literal.hpp> +#include <boost/cstdint.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <iostream> +#include <string> +#include <vector> + +void check_reference_type(); + +void check_iterator_range() +{ + + typedef std::string::iterator iterator; + typedef std::string::const_iterator const_iterator; + typedef boost::iterator_range<iterator> irange; + typedef boost::iterator_range<const_iterator> cirange; + std::string str = "hello world"; + const std::string cstr = "const world"; + irange r = boost::make_iterator_range( str ); + r = boost::make_iterator_range( str.begin(), str.end() ); + cirange r2 = boost::make_iterator_range( cstr ); + r2 = boost::make_iterator_range( cstr.begin(), cstr.end() ); + r2 = boost::make_iterator_range( str ); + + BOOST_CHECK( !r.empty() ); + BOOST_CHECK( !r2.empty() ); + +//#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +// if( !(bool)r ) +// BOOST_CHECK( false ); +// if( !(bool)r2 ) +// BOOST_CHECK( false ); +//#else + if( !r ) + BOOST_CHECK( false ); + if( !r2 ) + BOOST_CHECK( false ); +//#endif + + BOOST_CHECK_EQUAL( r.size(), boost::size( r ) ); + BOOST_CHECK_EQUAL( r2.size(), boost::size( r2 ) ); + + BOOST_CHECK_EQUAL( std::distance( r.begin(), r.end() ), + std::distance( boost::begin( r2 ), boost::end( r2 ) ) ); + std::cout << r << r2; + + +#ifndef BOOST_NO_STD_WSTRING + std::wcout << boost::make_iterator_range( std::wstring( L"a wide string" ) ) + << boost::make_iterator_range( L"another wide string" ); +#endif + + std::string res = boost::copy_range<std::string>( r ); + BOOST_CHECK_EQUAL_COLLECTIONS( res.begin(), res.end(), r.begin(), r.end() ); + + irange rr = boost::make_iterator_range( str ); + BOOST_CHECK( rr.equal( r ) ); + + rr = boost::make_iterator_range( str.begin(), str.begin() + 5 ); + BOOST_CHECK( rr == boost::as_literal("hello") ); + BOOST_CHECK( rr != boost::as_literal("hell") ); + BOOST_CHECK( rr < boost::as_literal("hello dude") ); + BOOST_CHECK( boost::as_literal("hello") == rr ); + BOOST_CHECK( boost::as_literal("hell") != rr ); + BOOST_CHECK( ! (boost::as_literal("hello dude") < rr ) ); + irange rrr = rr; + BOOST_CHECK( rrr == rr ); + BOOST_CHECK( !( rrr != rr ) ); + BOOST_CHECK( !( rrr < rr ) ); + + const irange cr = boost::make_iterator_range( str ); + BOOST_CHECK_EQUAL( cr.front(), 'h' ); + BOOST_CHECK_EQUAL( cr.back(), 'd' ); + BOOST_CHECK_EQUAL( cr[1], 'e' ); + BOOST_CHECK_EQUAL( cr(1), 'e' ); + + rrr = boost::make_iterator_range( str, 1, -1 ); + BOOST_CHECK( rrr == boost::as_literal("ello worl") ); + rrr = boost::make_iterator_range( rrr, -1, 1 ); + BOOST_CHECK( rrr == str ); + + check_reference_type(); + + // Check that an iterator range can be instantiated with + // a pointer to an array as an iterator. + int arr[2][2]; + boost::make_iterator_range(arr, arr + 2); +} + +namespace iterator_range_test_detail +{ + struct less + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l < r; + } + }; + + struct greater + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l > r; + } + }; + + struct less_or_equal + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l <= r; + } + }; + + struct greater_or_equal + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l >= r; + } + }; + + struct equal_to + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l == r; + } + }; + + struct not_equal_to + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l != r; + } + }; + + template< class Pred > + void check_iterator_range_operators_impl(Pred pred) + { + std::vector<std::string> vals; + vals.push_back(std::string()); + vals.push_back("a"); + vals.push_back("b"); + vals.push_back("z"); + vals.push_back("ab"); + vals.push_back("ba"); + vals.push_back("abc"); + vals.push_back("cba"); + vals.push_back("aa"); + vals.push_back("aaa"); + vals.push_back("aab"); + vals.push_back("bba"); + + typedef std::string::const_iterator citer; + typedef boost::iterator_range<citer> iter_range; + + typedef std::vector<std::string>::const_iterator value_const_iterator; + value_const_iterator first_val = vals.begin(); + value_const_iterator last_val = vals.end(); + + for (value_const_iterator left_it = first_val; left_it != last_val; ++left_it) + { + const std::string& leftValue = *left_it; + for (value_const_iterator right_it = first_val; right_it != last_val; ++right_it) + { + const std::string& rightValue = *right_it; + iter_range left = boost::make_iterator_range(leftValue); + iter_range right = boost::make_iterator_range(rightValue); + + const bool reference = pred(leftValue, rightValue); + + BOOST_CHECK_EQUAL( pred(left, right), reference ); + BOOST_CHECK_EQUAL( pred(left, rightValue), reference ); + BOOST_CHECK_EQUAL( pred(leftValue, right), reference ); + } + } + } + + void check_iterator_range_from_array() + { + double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 }; + boost::iterator_range<double*> rng = boost::make_iterator_range(source); + BOOST_CHECK_EQUAL_COLLECTIONS( rng.begin(), rng.end(), + source, source + 6 ); + } + + void check_make_iterator_range_n() + { + using boost::uint32_t; + + std::vector<uint32_t> input; + for (uint32_t i = 0; i < 10u; ++i) + input.push_back(i); + + boost::iterator_range<std::vector<uint32_t>::iterator> rng = + boost::make_iterator_range_n(boost::begin(input), 8u); + + BOOST_CHECK(rng.begin() == input.begin()); + BOOST_CHECK(rng.end() == input.begin() + 8); + BOOST_CHECK_EQUAL(rng.size(), 8u); + + const std::vector<uint32_t>& cinput = input; + + boost::iterator_range<std::vector<uint32_t>::const_iterator> crng = + boost::make_iterator_range_n(boost::begin(cinput), 8u); + + BOOST_CHECK(crng.begin() == cinput.begin()); + BOOST_CHECK(crng.end() == cinput.begin() + 8); + BOOST_CHECK_EQUAL(crng.size(), 8u); + } + +} // namespace iterator_range_test_detail + +template<typename Pred> +inline void check_iterator_range_operator() +{ + iterator_range_test_detail::check_iterator_range_operators_impl( + Pred()); +} + +inline void test_advance() +{ + std::vector<int> l; + l.push_back(1); + l.push_back(2); + typedef boost::iterator_range<std::vector<int>::iterator> rng_t; + + rng_t r1(l.begin(), l.end()); + BOOST_CHECK(r1.advance_begin(1).advance_end(-1).empty()); + + rng_t r2(l.begin(), l.end()); + BOOST_CHECK_EQUAL(r2.advance_begin(1).size(), 1u); + + rng_t r3(l.begin(), l.end()); + BOOST_CHECK_EQUAL(r3.advance_end(-1).size(), 1u); +} + +struct ptr_iterator + : boost::iterator_adaptor<ptr_iterator, int *> +{ + ptr_iterator() {} + ptr_iterator(int *p) : boost::iterator_adaptor<ptr_iterator, int *>(p) {} +private: + typedef void iterator; // To throw off the SFINAE mechanism in iterator_range +}; + +void test_sfinae() +{ + boost::iterator_range<ptr_iterator> r(ptr_iterator(0), ptr_iterator(0)); +} + +// +// +// Check that constness is propagated correct from +// the iterator types. +// +// Test contributed by Larry Evans. +// + +template< class Container > +int test_iter_range( Container& a_cont ) +{ + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type citer_type; + typedef boost::iterator_range<citer_type> riter_type; + riter_type a_riter( boost::make_iterator_range( a_cont ) ); + a_riter.front(); + a_riter.back(); + int i = a_riter[0]; + return i; +} + + + +void check_reference_type() +{ + typedef std::vector<int> veci_type; + veci_type a_vec; + a_vec.push_back( 999 ); + test_iter_range<veci_type>(a_vec); + test_iter_range<veci_type const>(a_vec); +} + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); + + test->add(BOOST_TEST_CASE(&check_iterator_range)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::less>)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::less_or_equal>)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::greater>)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::greater_or_equal>)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::equal_to>)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator<iterator_range_test_detail::not_equal_to>)); + test->add(BOOST_TEST_CASE(&iterator_range_test_detail::check_make_iterator_range_n)); + test->add(BOOST_TEST_CASE(&test_advance)); + + return test; +} + diff --git a/src/boost/libs/range/test/iterator_range_drop.cpp b/src/boost/libs/range/test/iterator_range_drop.cpp new file mode 100644 index 00000000..58ac43ca --- /dev/null +++ b/src/boost/libs/range/test/iterator_range_drop.cpp @@ -0,0 +1,200 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#include <boost/detail/workaround.hpp> +#include <boost/range/iterator_range_core.hpp> +#include <boost/cstdint.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +class single_pass_iterator + : public boost::iterator_facade< + single_pass_iterator, + boost::int32_t, + boost::single_pass_traversal_tag, + const boost::int32_t& + > +{ + friend class boost::iterator_core_access; + + typedef std::vector<boost::int32_t>::const_iterator iterator_t; + +public: + single_pass_iterator() { } + + explicit single_pass_iterator(iterator_t it) + : m_it(it) + { + } + +private: + void increment() + { + ++m_it; + } + + bool equal(single_pass_iterator other) const + { + return m_it == other.m_it; + } + + reference dereference() const + { + return *m_it; + } + + iterator_t m_it; +}; + +class bidirectional_iterator + : public boost::iterator_facade< + bidirectional_iterator, + boost::int32_t, + boost::bidirectional_traversal_tag, + const boost::int32_t& + > +{ + friend class boost::iterator_core_access; + + typedef std::vector<boost::int32_t>::const_iterator iterator_t; + +public: + bidirectional_iterator() { } + + explicit bidirectional_iterator(iterator_t it) + : m_it(it) + { + } + +private: + void increment() + { + ++m_it; + } + + void decrement() + { + --m_it; + } + + bool equal(bidirectional_iterator other) const + { + return m_it == other.m_it; + } + + reference dereference() const + { + return *m_it; + } + + iterator_t m_it; +}; + +template<typename SinglePassRange> +boost::iterator_range<single_pass_iterator> +single_pass_range(const SinglePassRange& rng) +{ + return boost::iterator_range<single_pass_iterator>( + single_pass_iterator(boost::begin(rng)), + single_pass_iterator(boost::end(rng))); +} + +template<typename BidirectionalRange> +boost::iterator_range<bidirectional_iterator> +bidirectional_range(const BidirectionalRange& rng) +{ + return boost::iterator_range<bidirectional_iterator>( + bidirectional_iterator(boost::begin(rng)), + bidirectional_iterator(boost::end(rng))); +} + +void test_drop_front() +{ + std::vector<boost::int32_t> v; + std::vector<boost::int32_t> ref_output; + + for (boost::int32_t i = 0; i < 10; ++i) + { + v.push_back(i); + ref_output.push_back(i); + } + + boost::iterator_range<single_pass_iterator> rng = single_pass_range(v); + + BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), + ref_output.begin(), ref_output.end()); + + rng.drop_front(); + + ref_output.erase(ref_output.begin()); + + BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), + ref_output.begin(), ref_output.end()); + + rng.drop_front(5); + + ref_output.erase(ref_output.begin(), ref_output.begin() + 5); + + BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), + ref_output.begin(), ref_output.end()); +} + +void test_drop_back() +{ + std::vector<boost::int32_t> v; + std::vector<boost::int32_t> ref_output; + + for (boost::int32_t i = 0; i < 10; ++i) + { + v.push_back(i); + ref_output.push_back(i); + } + + boost::iterator_range<bidirectional_iterator> rng = bidirectional_range(v); + + BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), + ref_output.begin(), ref_output.end()); + + rng.drop_back(); + + ref_output.pop_back(); + + BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), + ref_output.begin(), ref_output.end()); + + rng.drop_back(5); + + ref_output.erase(ref_output.end() - 5, ref_output.end()); + + BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(), + ref_output.begin(), ref_output.end()); +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range iterator_range drop functions"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_drop_front)); + test->add(BOOST_TEST_CASE(&boost_range_test::test_drop_back)); + + return test; +} diff --git a/src/boost/libs/range/test/iterator_range_equality_bug.cpp b/src/boost/libs/range/test/iterator_range_equality_bug.cpp new file mode 100644 index 00000000..eea47cb5 --- /dev/null +++ b/src/boost/libs/range/test/iterator_range_equality_bug.cpp @@ -0,0 +1,39 @@ +// 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/ +// +// As reported in https://groups.google.com/forum/#!msg/boost-developers-archive/6JVNg7ZPb4k/RAlvPUec4MAJ + +#include <boost/range/iterator_range_core.hpp> +#include <boost/lambda/lambda.hpp> +#include <boost/algorithm/string.hpp> + +namespace boost +{ + enum {unnamed}; + struct S { + bool operator<(int) const {return false;} + bool operator==(int) const {return false;} + }; + template<typename T> + bool foo(T i) + { + return i < unnamed || i == unnamed; + } +} + +int main() +{ + using boost::lambda::_1; + (void)(_1 == 42); + (void)(42 == _1); + + boost::foo(42); + boost::foo(boost::S()); +} diff --git a/src/boost/libs/range/test/iterator_range_hash.cpp b/src/boost/libs/range/test/iterator_range_hash.cpp new file mode 100644 index 00000000..3ef9007f --- /dev/null +++ b/src/boost/libs/range/test/iterator_range_hash.cpp @@ -0,0 +1,52 @@ +// 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/iterator_range_hash.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_iterator_range_hash() +{ + std::vector<boost::int32_t> v; + + for (boost::int32_t i = 0; i < 10; ++i) + { + v.push_back(i); + } + + std::size_t ref_output = boost::hash_range(v.begin(), v.end()); + + boost::iterator_range<std::vector<boost::int32_t>::iterator> rng(v); + + std::size_t test_output = boost::hash_value(rng); + + BOOST_CHECK_EQUAL(ref_output, test_output); +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range iterator_range hash function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator_range_hash)); + + return test; +} diff --git a/src/boost/libs/range/test/iterator_range_variant.cpp b/src/boost/libs/range/test/iterator_range_variant.cpp new file mode 100644 index 00000000..d55ae853 --- /dev/null +++ b/src/boost/libs/range/test/iterator_range_variant.cpp @@ -0,0 +1,60 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#include <boost/detail/workaround.hpp> + +#include <boost/range/iterator_range.hpp> +#include <boost/range/functions.hpp> +#include <boost/range/as_literal.hpp> +#include <boost/variant.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <string> + +namespace +{ + enum E + { + e1, e2, e3 + }; + + void test_variant_report() + { + typedef boost::mpl::vector< + E, + std::string, + boost::iterator_range<std::string::iterator> + >::type args; + + typedef boost::make_variant_over<args>::type variant_t; + + variant_t v; + std::string s; + v = boost::iterator_range<std::string::iterator>(s.begin(), s.end()); + v = e2; + v = std::string(); + + // Rationale: + // This is cast to const char* to guard against ambiguity in the case + // where std::string::iterator it a char* + v = static_cast<const char*>(""); + } +} + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("iterator range and variant interoperability"); + + test->add(BOOST_TEST_CASE(&test_variant_report)); + + return test; +} diff --git a/src/boost/libs/range/test/join.cpp b/src/boost/libs/range/test/join.cpp new file mode 100644 index 00000000..300028b3 --- /dev/null +++ b/src/boost/libs/range/test/join.cpp @@ -0,0 +1,397 @@ +// 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/ +// +// Credits: +// Trac 7376 - was raised by Leonid Gershanovich and his sample was used to +// make the test case to cover this condition. +// +#include <boost/range/join.hpp> +#include <boost/range/adaptor/transformed.hpp> + +#include <boost/foreach.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/assign.hpp> +#include <boost/range/algorithm_ext.hpp> +#include <boost/range/irange.hpp> + +#include <boost/iterator/iterator_facade.hpp> + +#include <algorithm> +#include <deque> +#include <list> +#include <vector> + +namespace boost +{ + namespace + { + // This function is a helper function that writes integers + // of increasing value into a range. It is used to test + // that joined ranged may be written to. + // + // Requires: + // - Range uses shallow copy semantics. + template< typename Range > + void fill_with_ints(Range rng) + { + typedef typename range_iterator<Range>::type iterator; + iterator target = boost::begin(rng); + const int count = boost::distance(rng); + for (int i = 0; i < count; ++i) + { + *target = i; + ++target; + } + } + + // The test_join_traversal function is used to provide additional + // tests based upon the underlying join iterator traversal. + // The join iterator takes care of the appropriate demotion, and + // this demotion. + + // test_join_traversal - additional tests for input and forward + // traversal iterators. This is of course a no-op. + template< typename Range1, typename Range2, typename TraversalTag > + void test_join_traversal(Range1& rng1, Range2& rng2, TraversalTag) + { + } + + // test_join_traversal - additional tests for bidirectional + // traversal iterators. + template< typename Range1, typename Range2 > + void test_join_traversal(Range1& rng1, Range2& rng2, boost::bidirectional_traversal_tag) + { + typedef typename range_value<Range1>::type value_type; + std::vector<value_type> reference(boost::begin(rng1), boost::end(rng1)); + boost::push_back(reference, rng2); + std::reverse(reference.begin(), reference.end()); + + std::vector<value_type> test_result; + BOOST_REVERSE_FOREACH( value_type x, join(rng1, rng2) ) + { + test_result.push_back(x); + } + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test_result.begin(), test_result.end() ); + } + + // Test helper function to implement the additional tests for random + // access traversal iterators. This is used by the test_join_traversal + // function for random access iterators. The reason that the test + // implementation is put into this function is to utilise + // template parameter type deduction for the joined range type. + template< typename Range1, typename Range2, typename JoinedRange > + void test_random_access_join(Range1& rng1, Range2& rng2, JoinedRange joined) + { + BOOST_CHECK_EQUAL( boost::end(joined) - boost::begin(joined), boost::distance(joined) ); + BOOST_CHECK( boost::end(joined) <= boost::begin(joined) ); + BOOST_CHECK( boost::begin(joined) >= boost::end(joined) ); + if (boost::empty(joined)) + { + BOOST_CHECK(!(boost::begin(joined) < boost::end(joined))); + BOOST_CHECK(!(boost::end(joined) > boost::begin(joined))); + } + else + { + BOOST_CHECK(boost::begin(joined) < boost::end(joined)); + BOOST_CHECK(boost::end(joined) < boost::begin(joined)); + } + + typedef typename boost::range_difference<JoinedRange>::type difference_t; + const difference_t count = boost::distance(joined); + BOOST_CHECK( boost::begin(joined) + count == boost::end(joined) ); + BOOST_CHECK( boost::end(joined) - count == boost::begin(joined) ); + + typedef typename boost::range_iterator<JoinedRange>::type iterator_t; + iterator_t it = boost::begin(joined); + it += count; + BOOST_CHECK( it == boost::end(joined) ); + + it = boost::end(joined); + it -= count; + BOOST_CHECK( it == boost::begin(joined) ); + } + + // test_join_traversal function for random access traversal joined + // ranges. + template< typename Range1, typename Range2 > + void test_join_traversal(Range1& rng1, Range2& rng2, boost::random_access_traversal_tag) + { + test_join_traversal(rng1, rng2, boost::bidirectional_traversal_tag()); + test_random_access_join(rng1, rng2, join(rng1, rng2)); + } + + // Test the ability to write values into a joined range. This is + // achieved by copying the constant collections, altering them + // and then checking the result. Hence this relies upon both + // rng1 and rng2 having value copy semantics. + template< typename Collection1, typename Collection2 > + void test_write_to_joined_range(const Collection1& rng1, const Collection2& rng2) + { + Collection1 c1(rng1); + Collection2 c2(rng2); + + typedef BOOST_DEDUCED_TYPENAME boost::range_value< + Collection1 + >::type value_t BOOST_RANGE_UNUSED; + + fill_with_ints(boost::join(c1,c2)); + + // Ensure that the size of the written range has not been + // altered. + BOOST_CHECK_EQUAL( boost::distance(c1), boost::distance(rng1) ); + BOOST_CHECK_EQUAL( boost::distance(c2), boost::distance(rng2) ); + + // For each element x, in c1 ensure that it has been written to + // with incrementing integers + int x = 0; + typedef typename range_iterator<Collection1>::type iterator1; + iterator1 it1 = boost::begin(c1); + for (; it1 != boost::end(c1); ++it1) + { + BOOST_CHECK_EQUAL( x, *it1 ); + ++x; + } + + // For each element y, in c2 ensure that it has been written to + // with incrementing integers + typedef typename range_iterator<Collection2>::type iterator2; + iterator2 it2 = boost::begin(c2); + for (; it2 != boost::end(c2); ++it2) + { + BOOST_CHECK_EQUAL( x, *it2 ); + ++x; + } + } + + // Perform a unit test of a Boost.Range join() comparing + // it to a reference that is populated by appending + // elements from both source ranges into a vector. + template< typename Collection1, typename Collection2 > + void test_join_impl(Collection1& rng1, Collection2& rng2) + { + typedef typename range_value<Collection1>::type value_type; + std::vector<value_type> reference(boost::begin(rng1), boost::end(rng1)); + boost::push_back(reference, rng2); + + std::vector<value_type> test_result; + boost::push_back(test_result, join(rng1, rng2)); + + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test_result.begin(), test_result.end() ); + + typedef boost::range_detail::join_iterator< + typename boost::range_iterator<Collection1>::type, + typename boost::range_iterator<Collection2>::type + > join_iterator_t; + + typedef boost::iterator_traversal< join_iterator_t > tag_t; + + test_join_traversal(rng1, rng2, tag_t()); + + test_write_to_joined_range(rng1, rng2); + } + + // Make a collection filling it with items from the source + // range. This is used to build collections of various + // sizes populated with various values designed to optimize + // the code coverage exercised by the core test function + // test_join_impl. + template<typename Collection, typename Range> + boost::shared_ptr<Collection> makeCollection(const Range& source) + { + boost::shared_ptr<Collection> c(new Collection); + c->insert(c->end(), boost::begin(source), boost::end(source)); + return c; + } + + // This templatised version of the test_join_impl function + // generates and populates collections which are later + // used as input to the core test function. + // The caller of this function explicitly provides the + // template parameters. This supports the generation + // of testing a large combination of range types to be + // joined. It is of particular importance to remember + // to combine a random_access range with a bidirectional + // range to determine that the correct demotion of + // types occurs in the join_iterator. + template< typename Collection1, typename Collection2 > + void test_join_impl() + { + typedef boost::shared_ptr<Collection1> collection1_ptr; + typedef boost::shared_ptr<Collection2> collection2_ptr; + typedef boost::shared_ptr<const Collection1> collection1_cptr; + typedef boost::shared_ptr<const Collection2> collection2_cptr; + std::vector< collection1_cptr > left_containers; + std::vector< collection2_cptr > right_containers; + + left_containers.push_back(collection1_ptr(new Collection1)); + left_containers.push_back(makeCollection<Collection1>(irange(0,1))); + left_containers.push_back(makeCollection<Collection1>(irange(0,100))); + + right_containers.push_back(collection2_ptr(new Collection2)); + right_containers.push_back(makeCollection<Collection2>(irange(0,1))); + right_containers.push_back(makeCollection<Collection2>(irange(0,100))); + + BOOST_FOREACH( collection1_cptr left_container, left_containers ) + { + BOOST_FOREACH( collection2_cptr right_container, right_containers ) + { + test_join_impl(*left_container, *right_container); + } + } + } + + // entry-point into the unit test for the join() function + // this tests a representative sample of combinations of + // source range type. + void join_test() + { + test_join_impl< std::vector<int>, std::vector<int> >(); + test_join_impl< std::list<int>, std::list<int> >(); + test_join_impl< std::deque<int>, std::deque<int> >(); + + test_join_impl< std::vector<int>, std::list<int> >(); + test_join_impl< std::list<int>, std::vector<int> >(); + test_join_impl< std::vector<int>, std::deque<int> >(); + test_join_impl< std::deque<int>, std::vector<int> >(); + } + + void test_join_iterator_reference_type_constness_ticket8483() + { + // Just test that this compiles. + // Before the fix for bug 8483, the reference type of the joined + // range's iterator was incorrect ('int&' instead of 'const int&'), + // causing compiler errors. + const std::vector<int> v1; + std::vector<int> v2; + std::vector<int> joined; + boost::push_back(joined, join(v1, v2)); + boost::push_back(joined, join(v2, v1)); + } + + namespace trac7376 + { + struct base_type + { + explicit base_type(boost::int32_t value) + : value(value) + { + } + + virtual boost::int32_t get() const = 0; + + boost::int32_t value; + }; + + struct derived_type1 + : base_type + { + derived_type1(boost::int32_t value) + : base_type(value) + { + } + + virtual boost::int32_t get() const + { + return value * 2; + } + }; + + struct derived_type2 + : base_type + { + derived_type2(boost::int32_t value) + : base_type(value) + { + } + + virtual boost::int32_t get() const + { + return value * 4; + } + }; + + struct apply_get + { + typedef boost::int32_t result_type; + result_type operator()(const base_type& arg) const + { + return arg.get(); + } + }; + + void test_reference_types() + { + using namespace boost::adaptors; + + typedef boost::range_detail::join_iterator< + std::vector<derived_type1>::iterator, + std::vector<derived_type2>::iterator, + const base_type&, + const base_type& + > join_iterator_t; + + std::vector<boost::int32_t> reference_output; + + std::vector<derived_type1> x; + for (boost::int32_t i = 0; i < 10; ++i) + { + x.push_back(derived_type1(i)); + reference_output.push_back(i * 2); + } + + std::vector<derived_type2> y; + for (boost::int32_t i = 0; i < 10; ++i) + { + y.push_back(derived_type2(i)); + reference_output.push_back(i * 4); + } + + join_iterator_t it( + x, + y, + boost::range_detail::join_iterator_begin_tag()); + + std::vector<boost::int32_t> output; + boost::push_back( + output, + boost::make_iterator_range( + join_iterator_t( + x, y, + boost::range_detail::join_iterator_begin_tag()), + join_iterator_t( + x, y, + boost::range_detail::join_iterator_end_tag())) + | transformed(apply_get())); + + BOOST_CHECK_EQUAL_COLLECTIONS( + output.begin(), output.end(), + reference_output.begin(), reference_output.end()); + } + } // namespace trac7376 + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.joined" ); + + test->add( BOOST_TEST_CASE( &boost::join_test ) ); + test->add( BOOST_TEST_CASE( &boost::test_join_iterator_reference_type_constness_ticket8483 ) ); + test->add( BOOST_TEST_CASE( &boost::trac7376::test_reference_types ) ); + + return test; +} diff --git a/src/boost/libs/range/test/mfc.cpp b/src/boost/libs/range/test/mfc.cpp new file mode 100644 index 00000000..7a13e8e9 --- /dev/null +++ b/src/boost/libs/range/test/mfc.cpp @@ -0,0 +1,743 @@ +// Boost.Range MFC Extension +// +// Copyright Shunsuke Sogame 2005-2006. +// Distributed under 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 <afx.h> // must be here + +// #include <pstade/vodka/drink.hpp> + +#include <boost/test/test_tools.hpp> +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS +#define _ATL_NO_AUTOMATIC_NAMESPACE + +#define BOOST_LIB_NAME boost_test_exec_monitor +#include <boost/config/auto_link.hpp> + +#define BOOST_RANGE_DETAIL_MICROSOFT_TEST +#include <boost/range/mfc.hpp> // can be placed first + + +#include <map> +#include <boost/concept_check.hpp> +// #include <boost/foreach.hpp> +#include <boost/range/begin.hpp> +#include <boost/range/concepts.hpp> +#include <boost/range/end.hpp> +#include <boost/static_assert.hpp> +#include <boost/algorithm/string.hpp> + + +#include <afx.h> +#include <afxcoll.h> +#include <afxtempl.h> + +#if !(_ATL_VER < 0x0700) + #include <cstringt.h> + #include <atlsimpstr.h> + #include <atlstr.h> +#endif + + +namespace brdm = boost::range_detail_microsoft; + + +// helpers +// + +template< class MfcMapT, class MapT > +bool test_mfc_map(MfcMapT& map, const MapT& sample) +{ + typedef typename boost::range_iterator<MfcMapT>::type iter_t; + typedef typename boost::range_const_iterator<MapT>::type siter_t; + + bool result = true; + + result = result && (boost::distance(map) == boost::distance(sample)); + if (!result) + return false; + + { + for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) { + result = result && brdm::test_find_key_and_mapped(sample, *it); + } + } + + { + for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) { + result = result && (map[it->first] == it->second); + } + } + + return result; +} + + +template< class MfcMapT, class MapT > +bool test_mfc_cpair_map(MfcMapT& map, const MapT& sample) +{ + typedef typename boost::range_iterator<MfcMapT>::type iter_t; + typedef typename boost::range_const_iterator<MapT>::type siter_t; + + bool result = true; + + result = result && (boost::distance(map) == boost::distance(sample)); + if (!result) + return false; + + { + for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) { + result = result && brdm::test_find_key_and_mapped(sample, std::make_pair(it->key, it->value)); + } + } + + { + for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) { + result = result && (map[it->first] == it->second); + } + } + + return result; +} + + +// arrays +// +template< class Range > +void test_CByteArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CByteArray rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, BYTE *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, BYTE const*>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CDWordArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CDWordArray rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, DWORD *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, DWORD const*>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CObArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CObArray rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, brdm::mfc_ptr_array_iterator<rng_t, ::CObject *> >::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, brdm::mfc_ptr_array_iterator<const rng_t, const ::CObject *> >::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CPtrArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CPtrArray rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, brdm::mfc_ptr_array_iterator<rng_t, void *> >::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, brdm::mfc_ptr_array_iterator<const rng_t, const void *> >::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CStringArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CStringArray rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, ::CString *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, ::CString const *>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CUIntArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CUIntArray rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, UINT *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, UINT const *>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CWordArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CWordArray rng_t; + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, WORD *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, WORD const *>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +// lists +// + +template< class Range > +void test_CObList(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CObList rng_t; + + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, ::CObject *> >::value )); +#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CObject const *> >::value )); +#else + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CObject const * const, ::CObject const * const> >::value )); +#endif + + rng_t rng; + BOOST_CHECK( brdm::test_init_list(rng, sample) ); + BOOST_CHECK( brdm::test_bidirectional(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CPtrList(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CPtrList rng_t; + + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, void *> >::value )); +#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, void const *> >::value )); +#else + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, void const * const, void const * const> >::value )); +#endif + + rng_t rng; + BOOST_CHECK( brdm::test_init_list(rng, sample) ); + BOOST_CHECK( brdm::test_bidirectional(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CStringList(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CStringList rng_t; + + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, ::CString> >::value )); +#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CString const> >::value )); +#else + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CString const, ::CString const> >::value )); +#endif + + rng_t rng; + BOOST_CHECK( brdm::test_init_list(rng, sample) ); + BOOST_CHECK( brdm::test_bidirectional(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +// maps +// + +template< class MapT > +void test_CMapPtrToWord(const MapT& sample) +{ + typedef ::CMapPtrToWord rng_t; + + rng_t rng; + boost::function_requires< boost::ForwardRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(rng, sample) ); + BOOST_CHECK( ::test_mfc_map(rng, sample) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class MapT > +void test_CMapPtrToPtr(const MapT& sample) +{ + typedef ::CMapPtrToPtr rng_t; + + rng_t rng; + boost::function_requires< boost::ForwardRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(rng, sample) ); + BOOST_CHECK( ::test_mfc_map(rng, sample) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class MapT > +void test_CMapStringToOb(const MapT& sample) +{ + typedef ::CMapStringToOb rng_t; + + rng_t rng; + boost::function_requires< boost::ForwardRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(rng, sample) ); + BOOST_CHECK( ::test_mfc_map(rng, sample) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class MapT > +void test_CMapStringToPtr(const MapT& sample) +{ + typedef ::CMapStringToPtr rng_t; + + rng_t rng; + boost::function_requires< boost::ForwardRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(rng, sample) ); + BOOST_CHECK( ::test_mfc_map(rng, sample) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class MapT > +void test_CMapStringToString(const MapT& sample) +{ + typedef ::CMapStringToString rng_t; + + rng_t rng; + boost::function_requires< boost::ForwardRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(rng, sample) ); +#if !defined(BOOST_RANGE_MFC_NO_CPAIR) + BOOST_CHECK( ::test_mfc_cpair_map(rng, sample) ); +#endif + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class MapT > +void test_CMapWordToOb(const MapT& sample) +{ + typedef ::CMapWordToOb rng_t; + + rng_t rng; + boost::function_requires< boost::ForwardRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(rng, sample) ); + BOOST_CHECK( ::test_mfc_map(rng, sample) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class MapT > +void test_CMapWordToPtr(const MapT& sample) +{ + typedef ::CMapWordToPtr rng_t; + + rng_t rng; + boost::function_requires< boost::ForwardRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(rng, sample) ); + BOOST_CHECK( ::test_mfc_map(rng, sample) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +// templates +// + +template< class Range > +void test_CArray(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CArray<val_t, const val_t&> rng_t; // An old MFC needs the second template argument. + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_array(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class Range > +void test_CList(const Range& sample) +{ + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CList<val_t, const val_t&> rng_t; + + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, val_t> >::value )); +#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF) + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, val_t const> >::value )); +#else + BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, val_t const, val_t const> >::value )); +#endif + + rng_t rng; + BOOST_CHECK( brdm::test_init_list(rng, sample) ); + BOOST_CHECK( brdm::test_bidirectional(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +template< class MapT > +void test_CMap(const MapT& sample) +{ + typedef typename MapT::key_type k_t; + typedef typename MapT::mapped_type m_t; + + typedef ::CMap<k_t, const k_t&, m_t, const m_t&> rng_t; + + rng_t rng; + boost::function_requires< boost::ForwardRangeConcept<rng_t> >(); + BOOST_CHECK( brdm::test_init_map(rng, sample) ); +#if !defined(BOOST_RANGE_MFC_NO_CPAIR) + BOOST_CHECK( ::test_mfc_cpair_map(rng, sample) ); +#endif + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +void test_CTypedPtrArray() +{ + typedef ::CTypedPtrArray< ::CPtrArray, int * > rng_t; + boost::function_requires< boost::RandomAccessRangeConcept<rng_t> >(); + + rng_t rng; + int o1, o2, o3, o4, o5; + int *data[] = { &o1, &o2, &o3, &o4, &o5 }; + BOOST_CHECK( brdm::test_init_array(rng, boost::make_iterator_range(data, data+5)) ); + + BOOST_CHECK( *(boost::begin(rng) + 2) == &o3 ); + BOOST_CHECK( *(boost::end(rng) - 1) == &o5 ); + + // BOOST_CHECK( brdm::test_random_access(rng) ); this range is not mutable + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +void test_CTypedPtrList() +{ + typedef ::CTypedPtrList< ::CObList, ::CObList * > rng_t; + boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >(); + + rng_t rng; + + ::CObList o1, o2, o3, o4, o5; + ::CObList *data[] = { &o1, &o2, &o3, &o4, &o5 }; + BOOST_CHECK( brdm::test_init_list(rng, data) ); + + boost::range_iterator<rng_t>::type it = boost::begin(rng); + std::advance(it, 1); + BOOST_CHECK( *it == &o2 ); + std::advance(it, 2); + BOOST_CHECK( *it == &o4 ); + + // BOOST_CHECK( brdm::test_bidirectional(rng) ); this range is not mutable + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +void test_CTypedPtrMap() +{ + typedef ::CTypedPtrMap< ::CMapStringToPtr, ::CString, int *> rng_t; + boost::function_requires< boost::ForwardRangeConcept<rng_t> >(); + + rng_t rng; + ::CString o0(_T('a')), o1(_T('c')), o2(_T('f')), o3(_T('q')), o4(_T('g')); + int d0, d1, d2, d3, d4; + std::map< ::CString, int * > data; + data[o0] = &d0, data[o1] = &d1, data[o2] = &d2, data[o3] = &d3, data[o4] = &d4; + + BOOST_CHECK( brdm::test_init_map(rng, data) ); + BOOST_CHECK( ::test_mfc_map(rng, data) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); +} + + +// strings +// +#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING) + + template< class Range > + void test_CString(const Range& sample) + { + typedef typename boost::range_value<Range>::type val_t; + + typedef ::CString rng_t; // An old MFC needs the second template argument. + BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, TCHAR *>::value )); + BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, TCHAR const*>::value )); + + rng_t rng; + BOOST_CHECK( brdm::test_init_string(rng, sample) ); + BOOST_CHECK( brdm::test_random_access(rng) ); + BOOST_CHECK( brdm::test_emptiness(rng) ); + } + +#endif + + +struct CPerson +{ + void hello_range() { }; +}; + + +void test_mfc() +{ +#if 0 + // overview + // + { + CTypedPtrArray<CPtrArray, CList<CString> *> myArray; + // ... + BOOST_FOREACH (CList<CString> *theList, myArray) + { + BOOST_FOREACH (CString& str, *theList) + { + boost::to_upper(str); + std::sort(boost::begin(str), boost::end(str)); + // ... + } + } + } +#endif + + // arrays + // + { + BYTE data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 }; + + ::test_CByteArray(boost::make_iterator_range(data, data+22)); + } + + { + DWORD data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 }; + + test_CDWordArray(boost::make_iterator_range(data, data+22)); + } + + { + ::CObArray o1, o2, o3, o4, o5; + ::CObject *data[] = { &o1, &o2, &o3, &o4, &o5 }; + + ::test_CObArray(boost::make_iterator_range(data, data+5)); + } + + { + ::CPtrArray o1, o2, o3, o4, o5; + void *data[] = { &o1, &o2, &o3, &o4, &o5 }; + + ::test_CPtrArray(boost::make_iterator_range(data, data+5)); + } + + { + ::CString data[] = { + ::CString(_T('0')), ::CString(_T('1')), ::CString(_T('2')), ::CString(_T('3')), + ::CString(_T('4')), ::CString(_T('5')), ::CString(_T('6')), ::CString(_T('7')) + }; + + ::test_CStringArray(boost::make_iterator_range(data, data+8)); + } + + { + ::CUIntArray rng; + UINT data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 }; + + ::test_CUIntArray(boost::make_iterator_range(data, data+22)); + } + + { + ::CWordArray rng; + WORD data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 }; + + ::test_CWordArray(boost::make_iterator_range(data, data+22)); + } + + + // lists + // + { + ::CObList rng; + ::CObList o1, o2, o3, o4, o5; + ::CObject *data[] = { &o1, &o2, &o3, &o4, &o5 }; + + ::test_CObList(boost::make_iterator_range(data, data+5)); + } + + { + ::CPtrList rng; + ::CPtrList o1, o2, o3, o4, o5; + void *data[] = { &o1, &o2, &o3, &o4, &o5 }; + + ::test_CPtrList(boost::make_iterator_range(data, data+5)); + } + + { + ::CString data[] = { + ::CString(_T('0')), ::CString(_T('1')), ::CString(_T('2')), ::CString(_T('3')), + ::CString(_T('4')), ::CString(_T('5')), ::CString(_T('6')), ::CString(_T('7')) + }; + + ::test_CStringList(boost::make_iterator_range(data, data+8)); + } + + + // maps + // + { + std::map<void *, WORD> data; + int o0, o1, o2, o3, o4; + data[&o0] = 15, data[&o1] = 14, data[&o2] = 3, data[&o3] = 6, data[&o4] = 1; + + ::test_CMapPtrToWord(data); + } + + { + std::map<void *, void*> data; + int o0, o1, o2, o3, o4; + data[&o0] = &o3, data[&o1] = &o2, data[&o2] = &o1, data[&o3] = &o0, data[&o4] = &o4; + + ::test_CMapPtrToPtr(data); + } + + { + std::map< ::CString, CObject * > data; + CObArray o0, o1, o2, o3, o4; + data[ ::CString('0') ] = &o0, data[ ::CString('1') ] = &o1, data[ ::CString('2') ] = &o2, + data[ ::CString('3') ] = &o3, data[ ::CString('4') ] = &o4; + + ::test_CMapStringToOb(data); + } + + { + std::map< ::CString, void * > data; + CObArray o0, o1, o2, o3, o4; + data[ ::CString('0') ] = &o0, data[ ::CString('1') ] = &o1, data[ ::CString('2') ] = &o2, + data[ ::CString('3') ] = &o3, data[ ::CString('4') ] = &o4; + + ::test_CMapStringToPtr(data); + } + + { + std::map< ::CString, ::CString > data; + CString o0('a'), o1('b'), o2('c'), o3('d'), o4('e'); + data[ ::CString('0') ] = o0, data[ ::CString('1') ] = o1, data[ ::CString('2') ] = o2, + data[ ::CString('3') ] = o3, data[ ::CString('4') ] = o4; + + ::test_CMapStringToString(data); + } + + { + std::map< WORD, CObject * > data; + ::CDWordArray o0, o1, o2, o3, o4; + data[21] = &o3, data[52] = &o2, data[12] = &o1, data[76] = &o0, data[54] = &o4; + + ::test_CMapWordToOb(data); + } + + { + std::map< WORD, void * > data; + ::CDWordArray o0, o1, o2, o3, o4; + data[21] = &o3, data[52] = &o2, data[12] = &o1, data[76] = &o0, data[54] = &o4; + + ::test_CMapWordToPtr(data); + } + + // templates + // + { + std::string data("0987654321qwertyuiop"); + ::test_CArray(data); + ::test_CList(data); + } + + { + std::wstring data(L"asdfghjklzxcvbnm"); + ::test_CArray(data); + ::test_CList(data); + } + + { + std::map< int, std::string > data; + data[0] = "abcde", data[1] = "ajfie", data[2] = "lij", data[3] = "abc", data[4] = "ioiu"; + + ::test_CMap(data); + } + + + // typed + // + { + ::test_CTypedPtrArray(); + ::test_CTypedPtrList(); + ::test_CTypedPtrMap(); + } + + + // strings + // +#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING) + { + std::string data("123456789 abcdefghijklmn"); + ::test_CString(data); + } +#endif + + +} // test_mfc + + +#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("MFC Range Test Suite"); + test->add(BOOST_TEST_CASE(&test_mfc)); + + (void)argc, (void)argv; // unused + return test; +} diff --git a/src/boost/libs/range/test/mutable_iterator.cpp b/src/boost/libs/range/test/mutable_iterator.cpp new file mode 100644 index 00000000..40a38791 --- /dev/null +++ b/src/boost/libs/range/test/mutable_iterator.cpp @@ -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/ +// + +#include <boost/range/mutable_iterator.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_mutable_iterator() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_mutable_iterator<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_mutable_iterator<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_mutable_iterator<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_mutable_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_mutable_iterator)); + + return test; +} diff --git a/src/boost/libs/range/test/partial_workaround.cpp b/src/boost/libs/range/test/partial_workaround.cpp new file mode 100644 index 00000000..edaae71e --- /dev/null +++ b/src/boost/libs/range/test/partial_workaround.cpp @@ -0,0 +1,114 @@ +// 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/config.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/range/detail/implementation_help.hpp> +#include <boost/test/test_tools.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // suppress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +//#define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 1 + +#include <boost/range/iterator.hpp> +#include <boost/range/const_iterator.hpp> +#include <boost/range/size_type.hpp> +#include <boost/range/value_type.hpp> +#include <boost/range/difference_type.hpp> + +#include <boost/range/functions.hpp> +#include <boost/range/detail/sfinae.hpp> + +#include <boost/static_assert.hpp> +#include <boost/type_traits.hpp> +#include <iostream> +#include <vector> + +using namespace boost; +using namespace std; + +void check_partial_workaround() +{ + using namespace range_detail; + using type_traits::yes_type; + using type_traits::no_type; + + ////////////////////////////////////////////////////////////////////// + // string + ////////////////////////////////////////////////////////////////////// + char* c_ptr; + const char* cc_ptr; + wchar_t* w_ptr; + const wchar_t* cw_ptr; + + BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( c_ptr ) ) ); + BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( cc_ptr ) ) ); + BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( w_ptr ) ) ); + BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( cw_ptr ) ) ); + + BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_char_ptr_impl( c_ptr ) ) ); + BOOST_STATIC_ASSERT( sizeof( no_type ) == sizeof( is_char_ptr_impl( cc_ptr ) ) ); + + BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_wchar_t_ptr_impl( w_ptr ) ) ); + BOOST_STATIC_ASSERT( sizeof( no_type ) == sizeof( is_wchar_t_ptr_impl( cw_ptr ) ) ); + + BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_char_ptr_impl( c_ptr ) ) ); + BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_char_ptr_impl( cc_ptr ) ) ); + + BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_wchar_t_ptr_impl( w_ptr ) ) ); + BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_wchar_t_ptr_impl( cw_ptr ) ) ); + + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_container_, + boost::range_detail::range< vector<int> >::type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_pair_, + boost::range_detail::range< pair<int,int> >::type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::array_, + boost::range_detail::range< int[42] >::type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::char_ptr_, + boost::range_detail::range< char* >::type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::const_char_ptr_, + boost::range_detail::range< const char* >::type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::wchar_t_ptr_, + boost::range_detail::range< wchar_t* >::type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::const_wchar_t_ptr_, + boost::range_detail::range< const wchar_t* >::type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_container_, + boost::range_detail::range< vector<int> >::type >::value )); + +} + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +void check_partial_workaround() +{ + // + // test if warnings are generated + // + std::size_t s = boost::range_detail::array_size( "foo" ); + BOOST_CHECK_EQUAL( s, 4u ); +} + +#endif + +#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_partial_workaround ) ); + + return test; +} diff --git a/src/boost/libs/range/test/pointer.cpp b/src/boost/libs/range/test/pointer.cpp new file mode 100644 index 00000000..94e78f3d --- /dev/null +++ b/src/boost/libs/range/test/pointer.cpp @@ -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/ +// + +#include <boost/range/pointer.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_pointer() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::pointer, + boost::range_pointer<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_pointer, + boost::range_pointer<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::pointer, + boost::range_pointer<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_pointer meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_pointer)); + + return test; +} diff --git a/src/boost/libs/range/test/pointer_as_iterator.cpp b/src/boost/libs/range/test/pointer_as_iterator.cpp new file mode 100644 index 00000000..e0e28d06 --- /dev/null +++ b/src/boost/libs/range/test/pointer_as_iterator.cpp @@ -0,0 +1,39 @@ +// 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/iterator_range.hpp> +#include <boost/range/begin.hpp> +#include <boost/range/end.hpp> +#include <boost/array.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <iostream> +#include <vector> + +namespace +{ + void test_pointer_as_iterator() + { + boost::array<int,3> arr; + boost::iterator_range<const int*> r(arr.begin(), arr.end()); + r[0]; + } +} // 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.pointer_as_iterator" ); + + test->add(BOOST_TEST_CASE( &test_pointer_as_iterator )); + + return test; +} diff --git a/src/boost/libs/range/test/reference.cpp b/src/boost/libs/range/test/reference.cpp new file mode 100644 index 00000000..755be0ea --- /dev/null +++ b/src/boost/libs/range/test/reference.cpp @@ -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/ +// + +#include <boost/range/reference.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_reference() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::reference, + boost::range_reference<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_reference, + boost::range_reference<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::reference, + boost::range_reference<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_reference meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_reference)); + + return test; +} diff --git a/src/boost/libs/range/test/result_iterator.cpp b/src/boost/libs/range/test/result_iterator.cpp new file mode 100644 index 00000000..88dd7a51 --- /dev/null +++ b/src/boost/libs/range/test/result_iterator.cpp @@ -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/ +// + +#include <boost/range/result_iterator.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_result_iterator() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_result_iterator<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_iterator, + boost::range_result_iterator<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_result_iterator<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_result_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_result_iterator)); + + return test; +} diff --git a/src/boost/libs/range/test/reverse_iterator.cpp b/src/boost/libs/range/test/reverse_iterator.cpp new file mode 100644 index 00000000..827f244d --- /dev/null +++ b/src/boost/libs/range/test/reverse_iterator.cpp @@ -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/ +// + +#include <boost/range/reverse_iterator.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_reverse_iterator() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator<cont::iterator>, + boost::range_reverse_iterator<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator<cont::const_iterator>, + boost::range_reverse_iterator<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator<cont::iterator>, + boost::range_reverse_iterator<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_reverse_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_reverse_iterator)); + + return test; +} diff --git a/src/boost/libs/range/test/reverse_result_iterator.cpp b/src/boost/libs/range/test/reverse_result_iterator.cpp new file mode 100644 index 00000000..7d160fe1 --- /dev/null +++ b/src/boost/libs/range/test/reverse_result_iterator.cpp @@ -0,0 +1,62 @@ +// 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/reverse_result_iterator.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_reverse_result_iterator() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator<cont::iterator>, + boost::range_reverse_result_iterator<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator<cont::const_iterator>, + boost::range_reverse_result_iterator<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator<cont::iterator>, + boost::range_reverse_result_iterator<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE( + "Boost.Range range_reverse_result_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_reverse_result_iterator)); + + return test; +} diff --git a/src/boost/libs/range/test/reversible_range.cpp b/src/boost/libs/range/test/reversible_range.cpp new file mode 100644 index 00000000..a3dd20c7 --- /dev/null +++ b/src/boost/libs/range/test/reversible_range.cpp @@ -0,0 +1,74 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // suppress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#include <boost/range/rbegin.hpp> +#include <boost/range/rend.hpp> +#include <boost/range/begin.hpp> +#include <boost/range/end.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <vector> +#include <algorithm> + +void check_iterator() +{ + typedef std::vector<int> vec_t; + typedef vec_t::iterator iterator; + typedef std::pair<iterator,iterator> pair_t; + typedef boost::range_reverse_iterator<pair_t>::type rev_iterator; + typedef std::pair<rev_iterator,rev_iterator> rev_pair_t; + + vec_t vec; + pair_t p = std::make_pair( vec.begin(), vec.end() ); + rev_pair_t rp = std::make_pair( boost::rbegin( p ), boost::rend( p ) ); + int a[] = {1,2,3,4,5,6,7,8,9,10}; + const int ca[] = {1,2,3,4,5,6,7,8,9,10,11,12}; + BOOST_CHECK( boost::rbegin( vec ) == boost::range_reverse_iterator<vec_t>::type( vec.end() ) ); + BOOST_CHECK( boost::rend( vec ) == boost::range_reverse_iterator<vec_t>::type( vec.begin() ) ); + BOOST_CHECK( std::distance( boost::rbegin( vec ), boost::rend( vec ) ) == std::distance( boost::begin( vec ), boost::end( vec ) ) ); + + BOOST_CHECK( boost::rbegin( p ) == boost::begin( rp ) ); + BOOST_CHECK( boost::rend( p ) == boost::end( rp ) ); + BOOST_CHECK( std::distance( boost::rbegin( p ), boost::rend( p ) ) == std::distance( boost::begin( rp ), boost::end( rp ) ) ); + BOOST_CHECK( std::distance( boost::begin( p ), boost::end( p ) ) == std::distance( boost::rbegin( rp ), boost::rend( rp ) ) ); + + + BOOST_CHECK_EQUAL( &*boost::begin( a ), &*( boost::rend( a ) - 1 ) ); + BOOST_CHECK_EQUAL( &*( boost::end( a ) - 1 ), &*boost::rbegin( a ) ); + BOOST_CHECK_EQUAL( &*boost::begin( ca ), &*( boost::rend( ca ) - 1 ) ); + BOOST_CHECK_EQUAL( &*( boost::end( ca ) - 1 ), &*boost::rbegin( ca ) ); +} + + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); + + test->add( BOOST_TEST_CASE( &check_iterator ) ); + + return test; +} + + + + + + + diff --git a/src/boost/libs/range/test/size_type.cpp b/src/boost/libs/range/test/size_type.cpp new file mode 100644 index 00000000..9c335f14 --- /dev/null +++ b/src/boost/libs/range/test/size_type.cpp @@ -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/ +// + +#include <boost/range/size_type.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_size() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::size_type, + boost::range_size<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::size_type, + boost::range_size<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::size_type, + boost::range_size<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_size meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_size)); + + return test; +} diff --git a/src/boost/libs/range/test/std_container.cpp b/src/boost/libs/range/test/std_container.cpp new file mode 100644 index 00000000..75a584f6 --- /dev/null +++ b/src/boost/libs/range/test/std_container.cpp @@ -0,0 +1,74 @@ + // Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // 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/static_assert.hpp> +#include <boost/type_traits.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/test/test_tools.hpp> +#include <vector> + +void check_std_container() +{ + typedef std::vector<int> vec_t; + vec_t vec; + vec.push_back( 3 ); vec.push_back( 4 ); + const vec_t cvec( vec ); + + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value<vec_t>::type, vec_t::value_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<vec_t>::type, vec_t::iterator >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const vec_t>::type, vec_t::const_iterator >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference<vec_t>::type, vec_t::difference_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size<vec_t>::type, vec_t::size_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<vec_t>::type, vec_t::iterator >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator<const vec_t>::type, vec_t::const_iterator >::value )); + + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value<const vec_t>::type, vec_t::value_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference<const vec_t>::type, vec_t::difference_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size<const vec_t>::type, vec_t::size_type >::value )); + + BOOST_CHECK( boost::begin( vec ) == vec.begin() ); + BOOST_CHECK( boost::end( vec ) == vec.end() ); + BOOST_CHECK( boost::empty( vec ) == vec.empty() ); + BOOST_CHECK( static_cast<std::size_t>(boost::size( vec )) == vec.size() ); + + BOOST_CHECK( boost::begin( cvec ) == cvec.begin() ); + BOOST_CHECK( boost::end( cvec ) == cvec.end() ); + BOOST_CHECK( boost::empty( cvec ) == cvec.empty() ); + BOOST_CHECK( static_cast<std::size_t>(boost::size( cvec )) == cvec.size() ); + +} + + +#include <boost/test/unit_test.hpp> + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); + + test->add( BOOST_TEST_CASE( &check_std_container ) ); + + return test; +} + + + + + + diff --git a/src/boost/libs/range/test/string.cpp b/src/boost/libs/range/test/string.cpp new file mode 100644 index 00000000..9ff13f92 --- /dev/null +++ b/src/boost/libs/range/test/string.cpp @@ -0,0 +1,280 @@ +// 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/ +// + +//#define _MSL_USING_NAMESPACE 1 + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__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/array.hpp> +#include <boost/range/as_array.hpp> +#include <boost/range/as_literal.hpp> +#include <boost/range/functions.hpp> +#include <boost/range/metafunctions.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/config.hpp> +#include <vector> +#include <fstream> +#include <algorithm> + +namespace +{ + template< class CharT, std::size_t Length > + class test_string + { + public: + typedef CharT value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef std::size_t size_type; + typedef value_type array_t[Length]; + typedef const value_type const_array_t[Length]; + + explicit test_string(const CharT literal_sz[]) + { + std::copy(literal_sz, literal_sz + Length, m_buffer.data()); + m_buffer[Length] = value_type(); + } + + const_pointer const_sz() const { return m_buffer.data(); } + pointer mutable_sz() { return m_buffer.data(); } + + private: + typedef boost::array<value_type, Length + 1> buffer_t; + buffer_t m_buffer; + }; +} + +template< class T > +inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::type +str_begin( T& r ) +{ + return boost::begin( boost::as_literal(r) ); +} + +template< class T > +inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::type +str_end( T& r ) +{ + return boost::end( boost::as_literal(r) ); +} + +template< class T > +inline BOOST_DEDUCED_TYPENAME boost::range_difference<T>::type +str_size( const T& r ) +{ + return boost::size( boost::as_literal(r) ); +} + +template< class T > +inline bool +str_empty( T& r ) +{ + return boost::empty( boost::as_literal(r) ); +} + +template< typename Container, typename T > +BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type +find( Container& c, T value ) +{ + return std::find( str_begin(c), str_end(c), + value ); +} + +template< typename Container, typename T > +BOOST_DEDUCED_TYPENAME boost::range_iterator<const Container>::type +find( const Container& c, T value ) +{ + return std::find( str_begin(c), str_end(c), + value ); +} + +template< typename Container, typename T > +BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type +find_mutable( Container& c, T value ) +{ + str_size( c ); + return std::find( str_begin(c), str_end(c), + value ); +} + +template< typename Container, typename T > +BOOST_DEDUCED_TYPENAME boost::range_iterator<const Container>::type +find_const( const Container& c, T value ) +{ + str_size( c ); + return std::find( str_begin(c), str_end(c), + value ); +} + + +std::vector<char> +check_rvalue_return() +{ + return std::vector<char>( 10, 'm' ); +} + +using namespace boost; + + +void check_char() +{ + typedef boost::range_difference<std::string>::type diff_t; + typedef char* char_iterator_t; + typedef char char_array_t[10]; + + test_string<char, 8> a_string("a string"); + test_string<char, 14> another_string("another string"); + + const char* char_s = a_string.const_sz(); + char my_string[] = "another_string"; + const char my_const_string[] = "another string"; + const diff_t my_string_length = 14; + char* char_s2 = a_string.mutable_sz(); + + BOOST_STATIC_ASSERT(( is_same< range_value<char_iterator_t>::type, + detail::iterator_traits<char_iterator_t>::value_type>::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<char_iterator_t>::type, char_iterator_t >::value )); + + BOOST_STATIC_ASSERT(( is_same< range_difference<char_iterator_t>::type, + ::std::ptrdiff_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_size<char_iterator_t>::type, std::size_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<char_iterator_t>::type, char_iterator_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<const char*>::type, const char* >::value )); + + BOOST_STATIC_ASSERT(( is_same< range_value<char_array_t>::type, + char>::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<char_array_t>::type, char* >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<const char_array_t>::type, const char* >::value )); + BOOST_STATIC_ASSERT(( is_same< range_difference<char_array_t>::type, + ::std::ptrdiff_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_size<char_array_t>::type, std::size_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<char_array_t>::type, char* >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<const char_array_t>::type, const char* >::value )); + + BOOST_CHECK_EQUAL( str_begin( char_s ), char_s ); + const diff_t sz = str_size(char_s); + const char* str_end1 = str_begin( char_s ) + sz; + BOOST_CHECK_EQUAL( str_end( char_s ), str_end1 ); + BOOST_CHECK_EQUAL( str_empty( char_s ), (char_s == 0 || char_s[0] == char()) ); + BOOST_CHECK_EQUAL( sz, static_cast<diff_t>(std::char_traits<char>::length(char_s)) ); + + BOOST_CHECK_EQUAL( str_begin( my_string ), my_string ); + range_iterator<char_array_t>::type str_end2 = str_begin( my_string ) + str_size(my_string); + range_iterator<char_array_t>::type str_end3 = str_end(my_string); + BOOST_CHECK_EQUAL( str_end3, str_end2 ); + BOOST_CHECK_EQUAL( str_empty( my_string ), (my_string == 0 || my_string[0] == char()) ); + BOOST_CHECK_EQUAL( str_size( my_string ), my_string_length ); + BOOST_CHECK_EQUAL( str_size( my_string ), static_cast<diff_t>(std::char_traits<char>::length(my_string)) ); + + char to_search = 'n'; + BOOST_CHECK( find_mutable( char_s, to_search ) != str_end( char_s ) ); + BOOST_CHECK( find_const( char_s, to_search ) != str_end(char_s) ); + + BOOST_CHECK( find_mutable( my_string, to_search ) != str_end(my_string) ); + BOOST_CHECK( find_const( my_string, to_search ) != str_end(my_string) ); + + BOOST_CHECK( find_mutable( char_s2, to_search ) != str_end(char_s) ); + BOOST_CHECK( find_const( char_s2, to_search ) != str_end(char_s2) ); + + BOOST_CHECK( find_const( as_array( my_string ), to_search ) != str_end(my_string) ); + BOOST_CHECK( find_const( as_array( my_const_string ), to_search ) != str_end(my_string) ); + + // + // Test that as_literal() always scan for null terminator + // + char an_array[] = "foo\0bar"; + BOOST_CHECK_EQUAL( str_begin( an_array ), an_array ); + BOOST_CHECK_EQUAL( str_end( an_array ), an_array + 3 ); + BOOST_CHECK_EQUAL( str_size( an_array ), 3 ); + + const char a_const_array[] = "foobar\0doh"; + BOOST_CHECK_EQUAL( str_begin( a_const_array ), a_const_array ); + BOOST_CHECK_EQUAL( str_end( a_const_array ), a_const_array + 6 ); + BOOST_CHECK_EQUAL( str_size( a_const_array ), 6 ); + +} + + + +void check_string() +{ + check_char(); + +#ifndef BOOST_NO_STD_WSTRING + typedef wchar_t* wchar_iterator_t; + + test_string<wchar_t, 13> a_wide_string(L"a wide string"); + test_string<wchar_t, 19> another_wide_string(L"another wide string"); + + const wchar_t* char_ws = a_wide_string.const_sz(); + wchar_t my_wstring[] = L"another wide string"; + wchar_t* char_ws2 = a_wide_string.mutable_sz(); + + BOOST_STATIC_ASSERT(( is_same< range_value<wchar_iterator_t>::type, + detail::iterator_traits<wchar_iterator_t>::value_type>::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<const wchar_t*>::type, const wchar_t* >::value )); + BOOST_STATIC_ASSERT(( is_same< range_difference<wchar_iterator_t>::type, + detail::iterator_traits<wchar_iterator_t>::difference_type >::value )); + BOOST_STATIC_ASSERT(( is_same< range_size<wchar_iterator_t>::type, std::size_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value )); + BOOST_STATIC_ASSERT(( is_same< range_iterator<const wchar_t*>::type, const wchar_t* >::value )); + + typedef boost::range_difference<std::wstring>::type diff_t; + const diff_t sz = str_size( char_ws ); + BOOST_CHECK_EQUAL( str_begin( char_ws ), char_ws ); + BOOST_CHECK_EQUAL( str_end(char_ws), (str_begin( char_ws ) + sz) ); + BOOST_CHECK_EQUAL( str_empty( char_ws ), (char_ws == 0 || char_ws[0] == wchar_t()) ); + BOOST_CHECK_EQUAL( sz, static_cast<diff_t>(std::char_traits<wchar_t>::length(char_ws)) ); + + wchar_t to_search = L'n'; + BOOST_CHECK( find( char_ws, to_search ) != str_end(char_ws) ); + BOOST_CHECK( find( char_ws2, to_search ) != str_end(char_ws2) ); + +#if BOOST_WORKAROUND(_MSC_VER, BOOST_TESTED_AT(1300)) + + BOOST_CHECK( find( my_wstring, to_search ) != str_end(my_wstring) ); + +#else + + boost::ignore_unused_variable_warning( my_wstring ); + +#endif +#endif + + find( check_rvalue_return(), '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_string ) ); + + return test; +} + + + + + + diff --git a/src/boost/libs/range/test/sub_range.cpp b/src/boost/libs/range/test/sub_range.cpp new file mode 100644 index 00000000..a6dbb36b --- /dev/null +++ b/src/boost/libs/range/test/sub_range.cpp @@ -0,0 +1,289 @@ +// Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // suppress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#include <boost/range/sub_range.hpp> +#include <boost/range/as_literal.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/test/test_tools.hpp> +#include <iostream> +#include <string> +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void check_sub_range() +{ + + typedef std::string::iterator iterator; + typedef std::string::const_iterator const_iterator; + typedef boost::iterator_range<iterator> irange; + typedef boost::iterator_range<const_iterator> cirange; + std::string str = "hello world"; + const std::string cstr = "const world"; + irange r = boost::make_iterator_range( str ); + r = boost::make_iterator_range( str.begin(), str.end() ); + cirange r2 = boost::make_iterator_range( cstr ); + r2 = boost::make_iterator_range( cstr.begin(), cstr.end() ); + r2 = boost::make_iterator_range( str ); + + typedef boost::sub_range<std::string> srange; + typedef boost::sub_range<const std::string> csrange; + srange s = r; + BOOST_CHECK( r == r ); + BOOST_CHECK( s == r ); + s = boost::make_iterator_range( str ); + csrange s2 = r; + s2 = r2; + s2 = boost::make_iterator_range( cstr ); + BOOST_CHECK( r2 == r2 ); + BOOST_CHECK( s2 != r2 ); + s2 = boost::make_iterator_range( str ); + BOOST_CHECK( !(s != s) ); + + BOOST_CHECK( r.begin() == s.begin() ); + BOOST_CHECK( r2.begin()== s2.begin() ); + BOOST_CHECK( r.end() == s.end() ); + BOOST_CHECK( r2.end() == s2.end() ); + BOOST_CHECK_EQUAL( r.size(), s.size() ); + BOOST_CHECK_EQUAL( r2.size(), s2.size() ); + +//#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +// if( !(bool)r ) +// BOOST_CHECK( false ); +// if( !(bool)r2 ) +// BOOST_CHECK( false ); +// if( !(bool)s ) +// BOOST_CHECK( false ); +// if( !(bool)s2 ) +// BOOST_CHECK( false ); +//#else + if( !r ) + BOOST_CHECK( false ); + if( !r2 ) + BOOST_CHECK( false ); + if( !s ) + BOOST_CHECK( false ); + if( !s2 ) + BOOST_CHECK( false ); +//#endif + + std::cout << r << r2 << s << s2; + + std::string res = boost::copy_range<std::string>( r ); + BOOST_CHECK_EQUAL_COLLECTIONS( res.begin(), res.end(), r.begin(), r.end() ); + + r.empty(); + s.empty(); + r.size(); + s.size(); + + // + // As of range v2 not legal anymore. + // + //irange singular_irange; + //BOOST_CHECK( singular_irange.empty() ); + //BOOST_CHECK( singular_irange.size() == 0 ); + // + //srange singular_srange; + //BOOST_CHECK( singular_srange.empty() ); + //BOOST_CHECK( singular_srange.size() == 0 ); + // + //BOOST_CHECK( empty( singular_irange ) ); + //BOOST_CHECK( empty( singular_srange ) ); + // + + srange rr = boost::make_iterator_range( str ); + BOOST_CHECK( rr.equal( r ) ); + + rr = boost::make_iterator_range( str.begin(), str.begin() + 5 ); + BOOST_CHECK( rr == boost::as_literal("hello") ); + BOOST_CHECK( rr != boost::as_literal("hell") ); + BOOST_CHECK( rr < boost::as_literal("hello dude") ); + BOOST_CHECK( boost::as_literal("hello") == rr ); + BOOST_CHECK( boost::as_literal("hell") != rr ); + BOOST_CHECK( ! (boost::as_literal("hello dude") < rr ) ); + + irange rrr = rr; + BOOST_CHECK( rrr == rr ); + BOOST_CHECK( !( rrr != rr ) ); + BOOST_CHECK( !( rrr < rr ) ); + + const irange cr = boost::make_iterator_range( str ); + BOOST_CHECK_EQUAL( cr.front(), 'h' ); + BOOST_CHECK_EQUAL( cr.back(), 'd' ); + BOOST_CHECK_EQUAL( cr[1], 'e' ); + BOOST_CHECK_EQUAL( cr(1), 'e' ); + + rrr = boost::make_iterator_range( str, 1, -1 ); + BOOST_CHECK( rrr == boost::as_literal("ello worl") ); + rrr = boost::make_iterator_range( rrr, -1, 1 ); + BOOST_CHECK( rrr == str ); + rrr.front() = 'H'; + rrr.back() = 'D'; + rrr[1] = 'E'; + BOOST_CHECK( rrr == boost::as_literal("HEllo worlD") ); +} + +template<class T> +void check_mutable_type(T&) +{ + BOOST_STATIC_ASSERT(!boost::is_const<T>::value); +} + +template<class T> +void check_constant_type(T&) +{ + BOOST_STATIC_ASSERT(boost::is_const<T>::value); +} + +template<class Range, class Iterator> +void check_is_const_iterator(Iterator it) +{ + BOOST_STATIC_ASSERT(( + boost::is_same< + BOOST_DEDUCED_TYPENAME boost::range_iterator< + BOOST_DEDUCED_TYPENAME boost::add_const<Range>::type + >::type, + Iterator + >::value)); +} + +template<class Range, class Iterator> +void check_is_iterator(Iterator it) +{ + BOOST_STATIC_ASSERT(( + boost::is_same< + BOOST_DEDUCED_TYPENAME boost::range_iterator< + BOOST_DEDUCED_TYPENAME boost::remove_const<Range>::type + >::type, + Iterator + >::value)); +} + +void const_propagation_mutable_collection(void) +{ + typedef std::vector<int> coll_t; + typedef boost::sub_range<coll_t> sub_range_t; + + coll_t c; + c.push_back(0); + + sub_range_t rng(c); + const sub_range_t crng(c); + + check_is_iterator<sub_range_t>(rng.begin()); + check_is_iterator<sub_range_t>(rng.end()); + + check_is_const_iterator<sub_range_t>(crng.begin()); + check_is_const_iterator<sub_range_t>(crng.end()); + + check_mutable_type(rng[0]); + check_mutable_type(rng.front()); + check_mutable_type(rng.back()); + check_constant_type(crng[0]); + check_constant_type(crng.front()); + check_constant_type(crng.back()); +} + +void const_propagation_const_collection(void) +{ + typedef std::vector<int> coll_t; + typedef boost::sub_range<const coll_t> sub_range_t; + + coll_t c; + c.push_back(0); + + sub_range_t rng(c); + const sub_range_t crng(c); + + check_is_const_iterator<sub_range_t>(rng.begin()); + check_is_const_iterator<sub_range_t>(rng.end()); + + check_is_const_iterator<sub_range_t>(crng.begin()); + check_is_const_iterator<sub_range_t>(crng.end()); + + check_constant_type(rng[0]); + check_constant_type(rng.front()); + check_constant_type(rng.back()); + check_constant_type(crng[0]); + check_constant_type(crng.front()); + check_constant_type(crng.back()); +} + +inline void test_advance() +{ + std::vector<int> l; + l.push_back(1); + l.push_back(2); + typedef boost::sub_range<std::vector<int> > rng_t; + rng_t r1(l.begin(), l.end()); + BOOST_CHECK(r1.advance_begin(1).advance_end(-1).empty()); + + rng_t r2(l.begin(), l.end()); + BOOST_CHECK_EQUAL(r2.advance_begin(1).size(), 1u); + + rng_t r3(l.begin(), l.end()); + BOOST_CHECK_EQUAL(r3.advance_end(-1).size(), 1u); +} + +void ticket_10514() +{ + typedef std::vector<int> vec_t; + typedef boost::sub_range<vec_t> range_t; + vec_t v(10); + range_t r(v.begin(), v.end()); + const range_t& cr = r; + range_t copy_r = cr; + + BOOST_CHECK(r.begin() == copy_r.begin()); + BOOST_CHECK(r.end() == copy_r.end()); + + BOOST_CHECK(cr.begin() == copy_r.begin()); + BOOST_CHECK(cr.end() == copy_r.end()); +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite(int, char*[]) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE( "Boost.Range sub_range test suite" ); + + test->add(BOOST_TEST_CASE(&boost_range_test::check_sub_range)); + + test->add(BOOST_TEST_CASE( + &boost_range_test::const_propagation_const_collection)); + + test->add(BOOST_TEST_CASE( + &boost_range_test::const_propagation_mutable_collection)); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_advance)); + + test->add(BOOST_TEST_CASE(&boost_range_test::ticket_10514)); + + return test; +} + + + + + diff --git a/src/boost/libs/range/test/test_driver/range_overload_test_driver.hpp b/src/boost/libs/range/test/test_driver/range_overload_test_driver.hpp new file mode 100644 index 00000000..e4b2ce78 --- /dev/null +++ b/src/boost/libs/range/test/test_driver/range_overload_test_driver.hpp @@ -0,0 +1,74 @@ + // Copyright Neil Groves 2013. 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/ + // + // Acknowledgments: + // Implemented by Andy in response to Ticket 6888 - unique fix + // + #ifndef BOOST_RANGE_TEST_TEST_DRIVER_RANGE_OVERLOAD_TEST_DRIVER_HPP_INCLUDED + #define BOOST_RANGE_TEST_TEST_DRIVER_RANGE_OVERLOAD_TEST_DRIVER_HPP_INCLUDED + + #include "range_return_test_driver.hpp" + #include <boost/assert.hpp> + #include <boost/test/test_tools.hpp> + #include <boost/test/unit_test.hpp> + + namespace boost + { + namespace range_test + { + + // A test driver to exercise a test through range_return_test_driver + // plus the overload that determines the return_type by overload + // + // The test driver also contains the code required to check the + // return value correctness. + // + // The TestPolicy needs to implement all those required by + // range_return_test_driver, and additionally + // + // - perform the boost range version of the algorithm that determines + // the return_type by overload + class range_overload_test_driver : range_return_test_driver + { + public: + template< class Container, + class TestPolicy > + void operator()(Container& cont, TestPolicy policy) + { + range_return_test_driver::operator()(cont, policy); + test_range_overload<Container, TestPolicy>()(cont, policy); + } + + private: + template< class Container, class TestPolicy > + struct test_range_overload + { + void operator()(Container& cont, TestPolicy policy) + { + typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t; + typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range_overload<Container> test_range_overload_t; + const range_return_value result_type = test_range_overload_t::result_type; + typedef BOOST_DEDUCED_TYPENAME range_return<Container, result_type>::type range_return_t; + + Container reference(cont); + Container test_cont(cont); + + test_range_overload_t test_range_overload_fn; + range_return_t range_result = test_range_overload_fn(policy, test_cont); + + iterator_t reference_it = policy.reference(reference); + + check_results<result_type>::test(test_cont, reference, + range_result, reference_it); + } + }; + }; + } + } + + #endif // include guard
\ No newline at end of file diff --git a/src/boost/libs/range/test/test_driver/range_return_test_driver.hpp b/src/boost/libs/range/test/test_driver/range_return_test_driver.hpp new file mode 100644 index 00000000..3dfd2a24 --- /dev/null +++ b/src/boost/libs/range/test/test_driver/range_return_test_driver.hpp @@ -0,0 +1,406 @@ +// 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/ +// +#ifndef BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED +#define BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED + +#include <boost/assert.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +namespace boost +{ + namespace range_test + { + // check the results of an algorithm that returns + // a range_return. + // + // This version is the general version. It should never be called. + // All calls should invoke specialized implementations. + template< range_return_value return_type > + struct check_results + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + Iterator test_it, + Iterator reference_it + ) + { + BOOST_ASSERT( false ); + } + }; + + // check the results of an algorithm that returns + // a 'found' iterator + template< > + struct check_results<return_found> + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + Iterator test_it, + Iterator reference_it + ) + { + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + BOOST_CHECK_EQUAL( std::distance(test.begin(), test_it), + std::distance(reference.begin(), reference_it) ); + } + }; + + // check the results of an algorithm that returns + // a 'next(found)' iterator + template< > + struct check_results<return_next> + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + Iterator test_it, + Iterator reference_it + ) + { + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + if (reference_it == reference.end()) + { + BOOST_CHECK( test_it == test.end() ); + } + else + { + BOOST_CHECK_EQUAL( + std::distance(test.begin(), test_it), + std::distance(reference.begin(), reference_it) + 1); + } + } + }; + + // check the results of an algorithm that returns + // a 'prior(found)' iterator + template< > + struct check_results<return_prior> + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + Iterator test_it, + Iterator reference_it + ) + { + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + if (reference_it == reference.begin()) + { + BOOST_CHECK( test_it == test.begin() ); + } + else + { + BOOST_CHECK_EQUAL( + std::distance(test.begin(), test_it) + 1, + std::distance(reference.begin(), reference_it)); + } + } + }; + + // check the results of an algorithm that returns + // a '[begin, found)' range + template< > + struct check_results<return_begin_found> + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + iterator_range<Iterator> test_rng, + Iterator reference_it + ) + { + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test.begin(), test.end() + ); + + BOOST_CHECK( test_rng.begin() == test.begin() ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference_it, + boost::begin(test_rng), boost::end(test_rng) + ); + } + }; + + // check the results of an algorithm that returns + // a '[begin, next(found))' range + template< > + struct check_results<return_begin_next> + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + iterator_range<Iterator> test_rng, + Iterator reference_it + ) + { + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test.begin(), test.end() + ); + + BOOST_CHECK( test_rng.begin() == test.begin() ); + + if (reference_it == reference.end()) + { + BOOST_CHECK( test_rng.end() == test.end() ); + } + else + { + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), boost::next(reference_it), + test_rng.begin(), test_rng.end()); + } + } + }; + + // check the results of an algorithm that returns + // a '[begin, prior(found))' range + template< > + struct check_results<return_begin_prior> + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + iterator_range<Iterator> test_rng, + Iterator reference_it + ) + { + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + BOOST_CHECK( test_rng.begin() == test.begin() ); + + if (reference_it == reference.begin()) + { + BOOST_CHECK( boost::end(test_rng) == test.begin() ); + } + else + { + BOOST_CHECK_EQUAL( std::distance(boost::begin(test_rng), boost::end(test_rng)) + 1, + std::distance(reference.begin(), reference_it) ); + } + } + }; + + // check the results of an algorithm that returns + // a '[found, end)' range + template< > + struct check_results<return_found_end> + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + iterator_range<Iterator> test_rng, + Iterator reference_it + ) + { + BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), + test.begin(), test.end() ); + + BOOST_CHECK_EQUAL( + std::distance(test.begin(), boost::begin(test_rng)), + std::distance(reference.begin(), reference_it)); + + BOOST_CHECK( boost::end(test_rng) == test.end() ); + } + }; + + // check the results of an algorithm that returns + // a '[next(found), end)' range + template< > + struct check_results<return_next_end> + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + iterator_range<Iterator> test_rng, + Iterator reference_it + ) + { + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test.begin(), test.end() + ); + + BOOST_CHECK( test_rng.end() == test.end() ); + + if (reference_it == reference.end()) + { + BOOST_CHECK( test_rng.begin() == test.end() ); + } + else + { + BOOST_CHECK_EQUAL_COLLECTIONS( + boost::next(reference_it), reference.end(), + test_rng.begin(), test_rng.end() + ); + } + } + }; + + // check the results of an algorithm that returns + // a 'prior(found), end)' range + template< > + struct check_results<return_prior_end> + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + iterator_range<Iterator> test_rng, + Iterator reference_it + ) + { + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test.begin(), test.end() + ); + + BOOST_CHECK( test_rng.end() == test.end() ); + + if (reference_it == reference.begin()) + { + BOOST_CHECK( test_rng.begin() == test.begin() ); + } + else + { + BOOST_CHECK_EQUAL_COLLECTIONS( + boost::prior(reference_it), reference.end(), + test_rng.begin(), test_rng.end() + ); + } + } + }; + + // check the results of an algorithm that returns + // a '[begin, end)' range + template< > + struct check_results<return_begin_end> + { + template< class Container, class Iterator > + static void test( + Container& test, + Container& reference, + iterator_range<Iterator> test_rng, + Iterator reference_it + ) + { + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + test.begin(), test.end() + ); + + BOOST_CHECK( test_rng.begin() == test.begin() ); + BOOST_CHECK( test_rng.end() == test.end() ); + } + }; + + // A test driver to exercise a test through all of the range_return + // combinations. + // + // The test driver also contains the code required to check the + // return value correctness. + // + // The TestPolicy needs to implement two functions: + // + // - perform the boost range version of the algorithm that returns + // a range_return<Container,return_type>::type + // template<range_return_value return_type, class Container> + // BOOST_DEDUCED_TYPENAME range_return<Container,return_type>::type + // test(Container& cont); + // + // - perform the reference std version of the algorithm that + // returns the standard iterator result + // template<class Container> + // BOOST_DEDUCED_TYPENAME range_iterator<Container>::type + // reference(Container& cont); + class range_return_test_driver + { + public: + template< class Container, + class TestPolicy > + void operator()(Container& cont, TestPolicy policy) + { + test_range_iter (cont, policy); + test_range<return_found,Container,TestPolicy> ()(cont, policy); + test_range<return_next,Container,TestPolicy> ()(cont, policy); + test_range<return_prior,Container,TestPolicy> ()(cont, policy); + test_range<return_begin_found,Container,TestPolicy>()(cont, policy); + test_range<return_begin_next,Container,TestPolicy> ()(cont, policy); + test_range<return_begin_prior,Container,TestPolicy>()(cont, policy); + test_range<return_found_end,Container,TestPolicy> ()(cont, policy); + test_range<return_next_end,Container,TestPolicy> ()(cont, policy); + test_range<return_prior_end,Container,TestPolicy> ()(cont, policy); + test_range<return_begin_end,Container,TestPolicy> ()(cont, policy); + } + + private: + template< class Container, class TestPolicy > + void test_range_iter( + Container& cont, + TestPolicy policy + ) + { + typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t; + + Container reference(cont); + Container test(cont); + + iterator_t range_result = policy.test_iter(test); + iterator_t reference_it = policy.reference(reference); + + check_results<return_found>::test(test, reference, + range_result, reference_it); + } + + template< range_return_value result_type, class Container, class TestPolicy > + struct test_range + { + void operator()(Container& cont, TestPolicy policy) + { + typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t; + typedef BOOST_DEDUCED_TYPENAME range_return<Container, result_type>::type range_return_t; + typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range<result_type> test_range_t; + + Container reference(cont); + Container test_cont(cont); + + test_range_t test_range_fn; + range_return_t range_result = test_range_fn(policy, test_cont); + iterator_t reference_it = policy.reference(reference); + + check_results<result_type>::test(test_cont, reference, + range_result, reference_it); + } + }; + }; + } +} + +#endif // include guard diff --git a/src/boost/libs/range/test/test_function/check_equal_fn.hpp b/src/boost/libs/range/test/test_function/check_equal_fn.hpp new file mode 100644 index 00000000..8da2ed83 --- /dev/null +++ b/src/boost/libs/range/test/test_function/check_equal_fn.hpp @@ -0,0 +1,49 @@ +// 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/ +// +#ifndef BOOST_RANGE_TEST_FUNCTIONS_CHECK_EQUAL_FN_HPP_INCLUDED +#define BOOST_RANGE_TEST_FUNCTIONS_CHECK_EQUAL_FN_HPP_INCLUDED + +#include "counted_function.hpp" + +namespace boost +{ + namespace range_test_function + { + template< class Collection > + class check_equal_fn : private counted_function + { + typedef BOOST_DEDUCED_TYPENAME Collection::const_iterator iter_t; + public: + explicit check_equal_fn( const Collection& c ) + : m_it(boost::begin(c)), m_last(boost::end(c)) {} + + using counted_function::invocation_count; + + void operator()(int x) const + { + invoked(); + BOOST_CHECK( m_it != m_last ); + if (m_it != m_last) + { + BOOST_CHECK_EQUAL( *m_it, x ); + ++m_it; + } + } + + private: + mutable iter_t m_it; + iter_t m_last; + }; + + } // namespace range_test_function +} // namespace boost + +#endif // include guard diff --git a/src/boost/libs/range/test/test_function/counted_function.hpp b/src/boost/libs/range/test/test_function/counted_function.hpp new file mode 100644 index 00000000..4a74515c --- /dev/null +++ b/src/boost/libs/range/test/test_function/counted_function.hpp @@ -0,0 +1,40 @@ +// 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/ +// +#ifndef BOOST_RANGE_TEST_FUNCTION_COUNTED_FUNCTION_HPP_INCLUDED +#define BOOST_RANGE_TEST_FUNCTION_COUNTED_FUNCTION_HPP_INCLUDED + +namespace boost +{ + namespace range_test_function + { + + class counted_function + { + public: + counted_function() : m_count(0u) {} + + void invoked() const + { + ++m_count; + } + + // Return the number of times that this function object + // has been invoked. + unsigned int invocation_count() const { return m_count; } + + private: + mutable unsigned int m_count; + }; + + } +} + +#endif // include guard diff --git a/src/boost/libs/range/test/test_function/equal_to_x.hpp b/src/boost/libs/range/test/test_function/equal_to_x.hpp new file mode 100644 index 00000000..14d00162 --- /dev/null +++ b/src/boost/libs/range/test/test_function/equal_to_x.hpp @@ -0,0 +1,33 @@ +// 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/ +// +#ifndef BOOST_RANGE_TEST_TEST_FUNCTION_EQUAL_TO_X_HPP_INCLUDED +#define BOOST_RANGE_TEST_TEST_FUNCTION_EQUAL_TO_X_HPP_INCLUDED + +namespace boost +{ + namespace range_test_function + { + template<class Arg> + struct equal_to_x + { + typedef bool result_type; + typedef Arg argument_type; + + explicit equal_to_x(Arg x) : m_x(x) {} + bool operator()(Arg x) const { return x == m_x; } + + private: + Arg m_x; + }; + } +} + +#endif // include guard diff --git a/src/boost/libs/range/test/test_function/false_predicate.hpp b/src/boost/libs/range/test/test_function/false_predicate.hpp new file mode 100644 index 00000000..533e83d5 --- /dev/null +++ b/src/boost/libs/range/test/test_function/false_predicate.hpp @@ -0,0 +1,29 @@ +// 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/ +// +#ifndef BOOST_RANGE_TEST_TEST_FUNCTION_FALSE_PREDICATE_HPP_INCLUDED +#define BOOST_RANGE_TEST_TEST_FUNCTION_FALSE_PREDICATE_HPP_INCLUDED + +namespace boost +{ + namespace range_test_function + { + struct false_predicate + { + typedef bool result_type; + + bool operator()() const { return false; } + template<class Arg> bool operator()(Arg) const { return false; } + template<class Arg1, class Arg2> bool operator()(Arg1,Arg2) const { return false; } + }; + } +} + +#endif // include guard diff --git a/src/boost/libs/range/test/test_function/greater_than_x.hpp b/src/boost/libs/range/test/test_function/greater_than_x.hpp new file mode 100644 index 00000000..032f594e --- /dev/null +++ b/src/boost/libs/range/test/test_function/greater_than_x.hpp @@ -0,0 +1,32 @@ +// 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/ +// +#ifndef BOOST_RANGE_TEST_FUNCTION_GREATER_THAN_X_HPP_INCLUDED +#define BOOST_RANGE_TEST_FUNCTION_GREATER_THAN_X_HPP_INCLUDED + +namespace boost +{ + namespace range_test_function + { + template< class Number > + struct greater_than_x + { + typedef bool result_type; + typedef Number argument_type; + + explicit greater_than_x(Number x) : m_x(x) {} + bool operator()(Number x) const { return x > m_x; } + private: + Number m_x; + }; + } // namespace range_test_function +} // namespace boost + +#endif // include guard diff --git a/src/boost/libs/range/test/test_function/multiply_by_x.hpp b/src/boost/libs/range/test/test_function/multiply_by_x.hpp new file mode 100644 index 00000000..b343c61e --- /dev/null +++ b/src/boost/libs/range/test/test_function/multiply_by_x.hpp @@ -0,0 +1,32 @@ +// 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/ +// +#ifndef BOOST_RANGE_TEST_TEST_FUNCTION_MULTIPLY_BY_X_HPP_INCLUDED +#define BOOST_RANGE_TEST_TEST_FUNCTION_MULTIPLY_BY_X_HPP_INCLUDED + +namespace boost +{ + namespace range_test_function + { + template< class Arg > + struct multiply_by_x + { + typedef Arg result_type; + typedef Arg argument_type; + + explicit multiply_by_x(Arg x) : m_x(x) {} + Arg operator()(Arg x) const { return x * m_x; } + private: + Arg m_x; + }; + } +} + +#endif // include guard diff --git a/src/boost/libs/range/test/test_function/true_predicate.hpp b/src/boost/libs/range/test/test_function/true_predicate.hpp new file mode 100644 index 00000000..87a0dcaf --- /dev/null +++ b/src/boost/libs/range/test/test_function/true_predicate.hpp @@ -0,0 +1,29 @@ +// 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/ +// +#ifndef BOOST_RANGE_TEST_TEST_FUNCTION_TRUE_PREDICATE_HPP_INCLUDED +#define BOOST_RANGE_TEST_TEST_FUNCTION_TRUE_PREDICATE_HPP_INCLUDED + +namespace boost +{ + namespace range_test_function + { + struct true_predicate + { + typedef bool result_type; + + bool operator()() const { return true; } + template<class Arg> bool operator()(Arg) const { return true; } + template<class Arg1, class Arg2> bool operator()(Arg1,Arg2) const { return true; } + }; + } +} + +#endif // include guard diff --git a/src/boost/libs/range/test/test_utils.hpp b/src/boost/libs/range/test/test_utils.hpp new file mode 100644 index 00000000..7af920a4 --- /dev/null +++ b/src/boost/libs/range/test/test_utils.hpp @@ -0,0 +1,24 @@ +// Boost.Range library +// +// Copyright Akira Takahashi 2013. 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/concepts.hpp> + +template <class RandomAccessRng> +void check_random_access_range_concept(const RandomAccessRng& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<RandomAccessRng> )); +} + +template <class BidirectionalRng> +void check_bidirectional_range_concept(const BidirectionalRng& rng) +{ + BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRng> )); +} diff --git a/src/boost/libs/range/test/ticket_10336.cpp b/src/boost/libs/range/test/ticket_10336.cpp new file mode 100644 index 00000000..541e037a --- /dev/null +++ b/src/boost/libs/range/test/ticket_10336.cpp @@ -0,0 +1,43 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. 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/iterator_range.hpp> +#include <boost/unordered_map.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +namespace boost +{ + namespace + { + // Ticket 10336 - compilation error in iterator_range and unordered_map + void test_ticket_10336() + { + typedef boost::unordered_map<int,int> container_t; + typedef container_t::const_iterator citer_t; + typedef boost::iterator_range<citer_t> rng_t; + + const container_t c; + rng_t rng(c.begin(), c.end()); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.ticket_10336" ); + + test->add( BOOST_TEST_CASE( &boost::test_ticket_10336 ) ); + + return test; +} diff --git a/src/boost/libs/range/test/ticket_5486.cpp b/src/boost/libs/range/test/ticket_5486.cpp new file mode 100644 index 00000000..94d8dd4f --- /dev/null +++ b/src/boost/libs/range/test/ticket_5486.cpp @@ -0,0 +1,58 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. 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/range/algorithm_ext/push_back.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost +{ + namespace + { + class TestTicket5486Pred + { + public: + typedef int first_argument_type; + typedef int second_argument_type; + typedef bool result_type; + + explicit TestTicket5486Pred(int x) {} + bool operator()(int,int) const { return true; } + private: + TestTicket5486Pred(); + }; + + // Ticket 5486 - pertained to predicates erroneous + // requiring default construction + void test_ticket_5486() + { + std::vector<int> v; + boost::push_back(v, v | boost::adaptors::adjacent_filtered(TestTicket5486Pred(1))); + + BOOST_CHECK_EQUAL_COLLECTIONS( v.begin(), v.end(), + v.begin(), v.end() ); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5486" ); + + test->add( BOOST_TEST_CASE( &boost::test_ticket_5486 ) ); + + return test; +} diff --git a/src/boost/libs/range/test/ticket_5544_terminate_irange.cpp b/src/boost/libs/range/test/ticket_5544_terminate_irange.cpp new file mode 100644 index 00000000..fa64436c --- /dev/null +++ b/src/boost/libs/range/test/ticket_5544_terminate_irange.cpp @@ -0,0 +1,47 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. 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/irange.hpp> +#include <boost/range/algorithm_ext/push_back.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost +{ + namespace + { + void test_irange_termination() + { + std::vector<int> reference; + for (int i = 0; i < 9; i += 2) + reference.push_back(i); + + std::vector<int> actual; + boost::push_back(actual, boost::irange(0,9,2)); + + BOOST_CHECK_EQUAL_COLLECTIONS(actual.begin(), actual.end(), + reference.begin(), reference.end()); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5544" ); + + test->add( BOOST_TEST_CASE( &boost::test_irange_termination ) ); + + return test; +} diff --git a/src/boost/libs/range/test/ticket_5547.cpp b/src/boost/libs/range/test/ticket_5547.cpp new file mode 100644 index 00000000..1b9d3f6f --- /dev/null +++ b/src/boost/libs/range/test/ticket_5547.cpp @@ -0,0 +1,42 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. 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/algorithm/string/join.hpp> +#include <boost/range/join.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost +{ + namespace + { + + // Ticket 5547 - boost::join ambiguous with algorithm::join + void test_ticket_5547() + { + std::vector<int> x; + boost::range::join(x,x); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5547" ); + + test->add( BOOST_TEST_CASE( &boost::test_ticket_5547 ) ); + + return test; +} diff --git a/src/boost/libs/range/test/ticket_5556_is_sorted_namespace.cpp b/src/boost/libs/range/test/ticket_5556_is_sorted_namespace.cpp new file mode 100644 index 00000000..78a75cde --- /dev/null +++ b/src/boost/libs/range/test/ticket_5556_is_sorted_namespace.cpp @@ -0,0 +1,37 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. 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/ +// + +// Embarrasingly, the mere inclusion of these headers in this order was +// enough to trigger the defect. +#include <boost/range/algorithm.hpp> +#include <boost/range/algorithm_ext.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +namespace boost +{ + namespace + { + void test_ticket_5556() {} + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5556" ); + + test->add( BOOST_TEST_CASE( &boost::test_ticket_5556 ) ); + + return test; +} diff --git a/src/boost/libs/range/test/ticket_5811_indirected_optional.cpp b/src/boost/libs/range/test/ticket_5811_indirected_optional.cpp new file mode 100644 index 00000000..1279a4a4 --- /dev/null +++ b/src/boost/libs/range/test/ticket_5811_indirected_optional.cpp @@ -0,0 +1,48 @@ +// 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/indirected.hpp> +#include <boost/optional.hpp> +#include <boost/optional/optional_io.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost +{ + namespace + { + void test_ticket_5811_indirected_optional() + { + std::vector<boost::optional<int> > v; + std::vector<int> r; + for (int i = 0; i < 10; ++i) + { + v.push_back(i); + r.push_back(i); + } + BOOST_CHECK_EQUAL_COLLECTIONS(r.begin(), r.end(), + v.begin(), v.end()); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE("RangeTestSuite.ticket_5811_indirected_optional"); + + test->add(BOOST_TEST_CASE(&boost::test_ticket_5811_indirected_optional)); + + return test; +} diff --git a/src/boost/libs/range/test/ticket_6715_iterator_range_equality.cpp b/src/boost/libs/range/test/ticket_6715_iterator_range_equality.cpp new file mode 100644 index 00000000..6c6972df --- /dev/null +++ b/src/boost/libs/range/test/ticket_6715_iterator_range_equality.cpp @@ -0,0 +1,52 @@ +// 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/iterator_range_core.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> +#include <string> + +namespace boost +{ + namespace + { + class str_ref : public boost::iterator_range<const char*> + { + public: + explicit str_ref(const std::string& str) + : boost::iterator_range<const char*>( + str.c_str(), str.c_str() + str.size()) + { + } + }; + + void test_ticket_6715_iterator_range_equality() + { + std::string src("test"); + str_ref a(src); + str_ref b(src); + BOOST_CHECK(a == b); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( + "RangeTestSuite.ticket_6715_iterator_range_equality"); + + test->add(BOOST_TEST_CASE( + &boost::test_ticket_6715_iterator_range_equality)); + + return test; +} diff --git a/src/boost/libs/range/test/ticket_6944.cpp b/src/boost/libs/range/test/ticket_6944.cpp new file mode 100644 index 00000000..43796a8c --- /dev/null +++ b/src/boost/libs/range/test/ticket_6944.cpp @@ -0,0 +1,46 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. 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/concept_check.hpp> +#include <boost/iterator/iterator_adaptor.hpp> +#include <boost/range/concepts.hpp> +#include <boost/range/iterator_range.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost +{ + typedef std::vector<int>::iterator iter_base; + struct iter : boost::iterator_adaptor<iter, iter_base, int, boost::use_default, int> {}; // will be deduced as random-access traversal but input category + typedef boost::iterator_range<iter> iter_range; + + namespace + { + // Ticket 6944 - Some Range concepts use the incorrect Iterator concept + void test_ticket_6944() + { + BOOST_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<iter_range> )); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.ticket_6944" ); + + test->add( BOOST_TEST_CASE( &boost::test_ticket_6944 ) ); + + return test; +} diff --git a/src/boost/libs/range/test/value_type.cpp b/src/boost/libs/range/test/value_type.cpp new file mode 100644 index 00000000..9a18b2f2 --- /dev/null +++ b/src/boost/libs/range/test/value_type.cpp @@ -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/ +// + +#include <boost/range/value_type.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/test/test_tools.hpp> +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace boost_range_test +{ + namespace + { + +void test_value_type() +{ + typedef std::vector<int> cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::value_type, + boost::range_value<cont>::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::value_type, + boost::range_value<const cont>::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::value_type, + boost::range_value<cont&&>::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_value meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_value_type)); + + return test; +} |