diff options
Diffstat (limited to 'src/boost/libs/range/test/adaptor_test')
49 files changed, 4836 insertions, 0 deletions
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; +} |