transformed.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Boost.Range library
  2. //
  3. // Copyright Neil Groves 2009. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. //
  9. // For more information, see http://www.boost.org/libs/range/
  10. //
  11. #include <boost/range/adaptor/transformed.hpp>
  12. #include <boost/test/test_tools.hpp>
  13. #include <boost/test/unit_test.hpp>
  14. #include <boost/assign.hpp>
  15. #include <boost/bind.hpp>
  16. #include <boost/range/algorithm_ext.hpp>
  17. #include <algorithm>
  18. #include <list>
  19. #include <set>
  20. #include <vector>
  21. namespace boost
  22. {
  23. namespace
  24. {
  25. struct double_x
  26. {
  27. typedef int result_type;
  28. int operator()(int x) const { return x * 2; }
  29. };
  30. struct halve_x
  31. {
  32. typedef int result_type;
  33. int operator()(int x) const { return x / 2; }
  34. };
  35. struct lambda_init
  36. {
  37. };
  38. struct lambda
  39. {
  40. typedef int result_type;
  41. lambda(const lambda_init& init) {}
  42. lambda(const lambda& rhs) {}
  43. int operator()(int x) const { return x + 1; }
  44. private:
  45. lambda() {}
  46. lambda& operator=(const lambda& rhs) { return *this; }
  47. };
  48. template< class Container, class TransformFn >
  49. void transformed_test_impl_core( Container& c, TransformFn fn )
  50. {
  51. using namespace boost::adaptors;
  52. std::vector< int > test_result1;
  53. boost::push_back(test_result1, c | transformed(fn));
  54. std::vector< int > test_result2;
  55. boost::push_back(test_result2, adaptors::transform(c, fn));
  56. std::vector< int > reference;
  57. std::transform(c.begin(), c.end(), std::back_inserter(reference), fn);
  58. BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
  59. test_result1.begin(), test_result1.end() );
  60. BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
  61. test_result2.begin(), test_result2.end() );
  62. }
  63. template< class Rng >
  64. void check_copy_assign(Rng r)
  65. {
  66. Rng r2 = r;
  67. r2 = r;
  68. }
  69. template< class Container, class TransformFn >
  70. void transformed_range_copy_assign(Container& c, TransformFn fn)
  71. {
  72. using namespace boost::adaptors;
  73. check_copy_assign(c | transformed(fn));
  74. check_copy_assign(adaptors::transform(c, fn));
  75. }
  76. template< class Container, class TransformFn, class TransformFnInit >
  77. void transformed_test_fn_impl()
  78. {
  79. using namespace boost::assign;
  80. Container c;
  81. TransformFnInit init;
  82. TransformFn fn( init );
  83. // Test empty
  84. transformed_test_impl_core(c, fn);
  85. // Test one element
  86. c += 1;
  87. transformed_test_impl_core(c, fn);
  88. // Test many elements
  89. c += 1,1,1,2,2,2,2,2,3,4,5,6,7,8,9;
  90. transformed_test_impl_core(c, fn);
  91. // test the range and iterator are copy assignable
  92. transformed_range_copy_assign(c, fn);
  93. }
  94. template< class Container >
  95. void transformed_test_impl()
  96. {
  97. transformed_test_fn_impl< Container, double_x, double_x >();
  98. transformed_test_fn_impl< Container, halve_x, halve_x >();
  99. transformed_test_fn_impl< Container, lambda, lambda_init >();
  100. }
  101. void transformed_test()
  102. {
  103. transformed_test_impl< std::vector< int > >();
  104. transformed_test_impl< std::list< int > >();
  105. transformed_test_impl< std::set< int > >();
  106. transformed_test_impl< std::multiset< int > >();
  107. }
  108. struct foo_bind
  109. {
  110. int foo() const { return 7; }
  111. };
  112. void transformed_bind()
  113. {
  114. using namespace boost::adaptors;
  115. std::vector<foo_bind> input(5);
  116. std::vector<int> output;
  117. boost::range::push_back(
  118. output,
  119. input | transformed(boost::bind(&foo_bind::foo, _1)));
  120. BOOST_CHECK_EQUAL(output.size(), input.size());
  121. std::vector<int> reference_output(5, 7);
  122. BOOST_CHECK_EQUAL_COLLECTIONS(
  123. output.begin(), output.end(),
  124. reference_output.begin(), reference_output.end());
  125. }
  126. }
  127. }
  128. boost::unit_test::test_suite*
  129. init_unit_test_suite(int argc, char* argv[])
  130. {
  131. boost::unit_test::test_suite* test
  132. = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed" );
  133. test->add(BOOST_TEST_CASE(&boost::transformed_test));
  134. test->add(BOOST_TEST_CASE(&boost::transformed_bind));
  135. return test;
  136. }