min_element.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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 <numeric>
  22. #include <algorithm>
  23. #include <range/v3/core.hpp>
  24. #include <range/v3/algorithm/min_element.hpp>
  25. #include "../array.hpp"
  26. #include "../simple_test.hpp"
  27. #include "../test_utils.hpp"
  28. #include "../test_iterators.hpp"
  29. RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
  30. namespace
  31. {
  32. std::mt19937 gen;
  33. template<class Iter, class Sent = Iter>
  34. void
  35. test_iter(Iter first, Sent last)
  36. {
  37. Iter i = ranges::min_element(first, last);
  38. if (first != last)
  39. {
  40. for (Iter j = first; j != last; ++j)
  41. CHECK(!(*j < *i));
  42. }
  43. else
  44. CHECK(i == last);
  45. auto rng = ::MakeTestRange(first, last);
  46. i = ranges::min_element(rng);
  47. if (first != last)
  48. {
  49. for (Iter j = first; j != last; ++j)
  50. CHECK(!(*j < *i));
  51. }
  52. else
  53. CHECK(i == last);
  54. auto res = ranges::min_element(std::move(rng));
  55. CHECK(::is_dangling(res));
  56. }
  57. template<class Iter, class Sent = Iter>
  58. void
  59. test_iter(unsigned N)
  60. {
  61. std::unique_ptr<int[]> a{new int[N]};
  62. std::iota(a.get(), a.get()+N, 0);
  63. std::shuffle(a.get(), a.get()+N, gen);
  64. test_iter(Iter(a.get()), Sent(a.get()+N));
  65. }
  66. template<class Iter, class Sent = Iter>
  67. void
  68. test_iter()
  69. {
  70. test_iter<Iter, Sent>(0);
  71. test_iter<Iter, Sent>(1);
  72. test_iter<Iter, Sent>(2);
  73. test_iter<Iter, Sent>(3);
  74. test_iter<Iter, Sent>(10);
  75. test_iter<Iter, Sent>(1000);
  76. }
  77. template<class Iter, class Sent = Iter>
  78. void
  79. test_iter_comp(Iter first, Sent last)
  80. {
  81. Iter i = ranges::min_element(first, last, std::greater<int>());
  82. if (first != last)
  83. {
  84. for (Iter j = first; j != last; ++j)
  85. CHECK(!std::greater<int>()(*j, *i));
  86. }
  87. else
  88. CHECK(i == last);
  89. auto rng = ::MakeTestRange(first, last);
  90. i = ranges::min_element(rng, std::greater<int>());
  91. if (first != last)
  92. {
  93. for (Iter j = first; j != last; ++j)
  94. CHECK(!std::greater<int>()(*j, *i));
  95. }
  96. else
  97. CHECK(i == last);
  98. auto res = ranges::min_element(std::move(rng), std::greater<int>());
  99. CHECK(::is_dangling(res));
  100. }
  101. template<class Iter, class Sent = Iter>
  102. void
  103. test_iter_comp(unsigned N)
  104. {
  105. std::unique_ptr<int[]> a{new int[N]};
  106. std::iota(a.get(), a.get()+N, 0);
  107. std::shuffle(a.get(), a.get()+N, gen);
  108. test_iter_comp(Iter(a.get()), Sent(a.get()+N));
  109. }
  110. template<class Iter, class Sent = Iter>
  111. void
  112. test_iter_comp()
  113. {
  114. test_iter_comp<Iter, Sent>(0);
  115. test_iter_comp<Iter, Sent>(1);
  116. test_iter_comp<Iter, Sent>(2);
  117. test_iter_comp<Iter, Sent>(3);
  118. test_iter_comp<Iter, Sent>(10);
  119. test_iter_comp<Iter, Sent>(1000);
  120. }
  121. struct S
  122. {
  123. int i;
  124. };
  125. }
  126. int main()
  127. {
  128. test_iter<ForwardIterator<const int*> >();
  129. test_iter<BidirectionalIterator<const int*> >();
  130. test_iter<RandomAccessIterator<const int*> >();
  131. test_iter<const int*>();
  132. test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
  133. test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
  134. test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
  135. test_iter_comp<ForwardIterator<const int*> >();
  136. test_iter_comp<BidirectionalIterator<const int*> >();
  137. test_iter_comp<RandomAccessIterator<const int*> >();
  138. test_iter_comp<const int*>();
  139. test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
  140. test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
  141. test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
  142. // Works with projections?
  143. S s[] = {S{1},S{2},S{3},S{4},S{-4},S{5},S{6},S{7},S{8},S{9}};
  144. S const *ps = ranges::min_element(s, std::less<int>{}, &S::i);
  145. CHECK(ps->i == -4);
  146. {
  147. constexpr auto a = test::array<int, 10>{{1, 2, 3, 4, -4, 5, 6, 7, 8, 9}};
  148. STATIC_CHECK(ranges::min_element(a) == ranges::begin(a) + 4);
  149. }
  150. return test_result();
  151. }