partial_sort.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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/algorithm/partial_sort.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 <algorithm>
  17. #include <functional>
  18. #include <list>
  19. #include <numeric>
  20. #include <deque>
  21. #include <vector>
  22. namespace boost
  23. {
  24. namespace
  25. {
  26. struct partial_sort_policy
  27. {
  28. template<class Container, class Iterator>
  29. void test_partial_sort(Container& cont, Iterator mid)
  30. {
  31. const Container old_cont(cont);
  32. boost::partial_sort(cont, mid);
  33. const std::size_t index = std::distance(cont.begin(), mid);
  34. Container cont2(old_cont);
  35. Iterator mid2(cont2.begin());
  36. std::advance(mid2, index);
  37. boost::partial_sort(cont2, mid2);
  38. BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
  39. cont2.begin(), cont2.end() );
  40. }
  41. template<class Container, class Iterator>
  42. void reference_partial_sort(Container& cont, Iterator mid)
  43. {
  44. std::partial_sort(cont.begin(), mid, cont.end());
  45. }
  46. };
  47. template<class BinaryPredicate>
  48. struct partial_sort_pred_policy
  49. {
  50. template<class Container, class Iterator>
  51. void test_partial_sort(Container& cont, Iterator mid)
  52. {
  53. const Container old_cont(cont);
  54. boost::partial_sort(cont, mid, BinaryPredicate());
  55. const std::size_t index = std::distance(cont.begin(), mid);
  56. Container cont2(old_cont);
  57. Iterator mid2(cont2.begin());
  58. std::advance(mid2, index);
  59. boost::partial_sort(cont2, mid2, BinaryPredicate());
  60. BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
  61. cont2.begin(), cont2.end() );
  62. }
  63. template<class Container, class Iterator>
  64. void reference_partial_sort(Container& cont, Iterator mid)
  65. {
  66. std::partial_sort(cont.begin(), mid, cont.end(), BinaryPredicate());
  67. }
  68. };
  69. template<class Container, class TestPolicy>
  70. void test_partial_sort_tp_impl(Container& cont, TestPolicy policy)
  71. {
  72. Container reference(cont);
  73. Container test(cont);
  74. typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
  75. BOOST_CHECK_EQUAL( reference.size(), test.size() );
  76. if (reference.size() != test.size())
  77. return;
  78. iterator_t reference_mid = reference.begin();
  79. iterator_t test_mid = test.begin();
  80. bool complete = false;
  81. while (!complete)
  82. {
  83. if (reference_mid == reference.end())
  84. complete = true;
  85. policy.test_partial_sort(test, test_mid);
  86. policy.reference_partial_sort(reference, reference_mid);
  87. BOOST_CHECK_EQUAL_COLLECTIONS(
  88. reference.begin(), reference.end(),
  89. test.begin(), test.end()
  90. );
  91. if (reference_mid != reference.end())
  92. {
  93. ++reference_mid;
  94. ++test_mid;
  95. }
  96. }
  97. }
  98. template<class Container>
  99. void test_partial_sort_impl(Container& cont)
  100. {
  101. test_partial_sort_tp_impl(cont, partial_sort_policy());
  102. }
  103. template<class Container, class BinaryPredicate>
  104. void test_partial_sort_impl(Container& cont, BinaryPredicate pred)
  105. {
  106. test_partial_sort_tp_impl(cont, partial_sort_pred_policy<BinaryPredicate>());
  107. }
  108. template<class Container>
  109. void test_partial_sort_impl()
  110. {
  111. using namespace boost::assign;
  112. Container cont;
  113. test_partial_sort_impl(cont);
  114. test_partial_sort_impl(cont, std::less<int>());
  115. test_partial_sort_impl(cont, std::greater<int>());
  116. cont.clear();
  117. cont += 1;
  118. test_partial_sort_impl(cont);
  119. test_partial_sort_impl(cont, std::less<int>());
  120. test_partial_sort_impl(cont, std::greater<int>());
  121. cont.clear();
  122. cont += 1,2,3,4,5,6,7,8,9;
  123. test_partial_sort_impl(cont);
  124. test_partial_sort_impl(cont, std::less<int>());
  125. test_partial_sort_impl(cont, std::greater<int>());
  126. }
  127. void test_partial_sort()
  128. {
  129. test_partial_sort_impl< std::vector<int> >();
  130. test_partial_sort_impl< std::deque<int> >();
  131. }
  132. }
  133. }
  134. boost::unit_test::test_suite*
  135. init_unit_test_suite(int argc, char* argv[])
  136. {
  137. boost::unit_test::test_suite* test
  138. = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.partial_sort" );
  139. test->add( BOOST_TEST_CASE( &boost::test_partial_sort ) );
  140. return test;
  141. }