nth_element.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2014-present
  4. //
  5. // Use, modification and distribution is subject to the
  6. // Boost Software License, Version 1.0. (See accompanying
  7. // file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // Project home: https://github.com/ericniebler/range-v3
  11. //===----------------------------------------------------------------------===//
  12. //
  13. // The LLVM Compiler Infrastructure
  14. //
  15. // This file is dual licensed under the MIT and the University of Illinois Open
  16. // Source Licenses. See LICENSE.TXT for details.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #include <memory>
  20. #include <random>
  21. #include <algorithm>
  22. #include <range/v3/core.hpp>
  23. #include <range/v3/algorithm/nth_element.hpp>
  24. #include "../simple_test.hpp"
  25. #include "../test_utils.hpp"
  26. #include "../test_iterators.hpp"
  27. RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
  28. RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
  29. namespace
  30. {
  31. std::mt19937 gen;
  32. void
  33. test_one(unsigned N, unsigned M)
  34. {
  35. RANGES_ENSURE(N != 0);
  36. RANGES_ENSURE(M < N);
  37. std::unique_ptr<int[]> array{new int[N]};
  38. for (int i = 0; (unsigned)i < N; ++i)
  39. array[i] = i;
  40. std::shuffle(array.get(), array.get()+N, gen);
  41. CHECK(ranges::nth_element(array.get(), array.get()+M, array.get()+N) == array.get()+N);
  42. CHECK((unsigned)array[M] == M);
  43. std::shuffle(array.get(), array.get()+N, gen);
  44. CHECK(ranges::nth_element(::as_lvalue(ranges::make_subrange(array.get(), array.get()+N)), array.get()+M) == array.get()+N);
  45. CHECK((unsigned)array[M] == M);
  46. std::shuffle(array.get(), array.get()+N, gen);
  47. CHECK(ranges::nth_element(ranges::make_subrange(array.get(), array.get()+N), array.get()+M) == array.get()+N);
  48. CHECK((unsigned)array[M] == M);
  49. ranges::nth_element(array.get(), array.get()+N, array.get()+N); // first, last, end
  50. }
  51. void
  52. test(unsigned N)
  53. {
  54. test_one(N, 0);
  55. test_one(N, 1);
  56. test_one(N, 2);
  57. test_one(N, 3);
  58. test_one(N, N/2-1);
  59. test_one(N, N/2);
  60. test_one(N, N/2+1);
  61. test_one(N, N-3);
  62. test_one(N, N-2);
  63. test_one(N, N-1);
  64. }
  65. struct S
  66. {
  67. int i,j;
  68. };
  69. }
  70. int main()
  71. {
  72. int d = 0;
  73. ranges::nth_element(&d, &d, &d);
  74. CHECK(d == 0);
  75. test(256);
  76. test(257);
  77. test(499);
  78. test(500);
  79. test(997);
  80. test(1000);
  81. test(1009);
  82. // Works with projections?
  83. const int N = 257;
  84. const int M = 56;
  85. S ia[N];
  86. for(int i = 0; i < N; ++i)
  87. ia[i].i = ia[i].j = i;
  88. std::shuffle(ia, ia+N, gen);
  89. ranges::nth_element(ia, ia+M, std::less<int>(), &S::i);
  90. CHECK(ia[M].i == M);
  91. CHECK(ia[M].j == M);
  92. return test_result();
  93. }