minmax.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2014-present
  4. // Copyright Casey Carter 2015
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // The LLVM Compiler Infrastructure
  15. //
  16. // This file is dual licensed under the MIT and the University of Illinois Open
  17. // Source Licenses. See LICENSE.TXT for details.
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #include <range/v3/algorithm/minmax.hpp>
  21. #include <range/v3/view/subrange.hpp>
  22. #include <memory>
  23. #include <numeric>
  24. #include <random>
  25. #include <algorithm>
  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. RANGES_ENSURE(first != last);
  38. auto rng = ranges::make_subrange(first, last);
  39. auto res = ranges::minmax(rng);
  40. for (Iter i = first; i != last; ++i) {
  41. CHECK(!(*i < res.min));
  42. CHECK(!(res.max < *i));
  43. }
  44. }
  45. template<class Iter, class Sent = Iter>
  46. void
  47. test_iter(unsigned N)
  48. {
  49. RANGES_ENSURE(N > 0);
  50. std::unique_ptr<int[]> a{new int[N]};
  51. std::iota(a.get(), a.get()+N, 0);
  52. std::shuffle(a.get(), a.get()+N, gen);
  53. test_iter(Iter(a.get()), Sent(a.get()+N));
  54. }
  55. template<class Iter, class Sent = Iter>
  56. void
  57. test_iter()
  58. {
  59. test_iter<Iter, Sent>(1);
  60. test_iter<Iter, Sent>(2);
  61. test_iter<Iter, Sent>(3);
  62. test_iter<Iter, Sent>(10);
  63. test_iter<Iter, Sent>(1000);
  64. }
  65. template<class Iter, class Sent = Iter>
  66. void
  67. test_iter_comp(Iter first, Sent last)
  68. {
  69. RANGES_ENSURE(first != last);
  70. typedef std::greater<int> Compare;
  71. Compare comp;
  72. auto rng = ranges::make_subrange(first, last);
  73. auto res = ranges::minmax(rng, comp);
  74. for (Iter i = first; i != last; ++i) {
  75. CHECK(!comp(*i, res.min));
  76. CHECK(!comp(res.max, *i));
  77. }
  78. }
  79. template<class Iter, class Sent = Iter>
  80. void
  81. test_iter_comp(unsigned N)
  82. {
  83. RANGES_ENSURE(N > 0);
  84. std::unique_ptr<int[]> a{new int[N]};
  85. std::iota(a.get(), a.get()+N, 0);
  86. std::shuffle(a.get(), a.get()+N, gen);
  87. test_iter_comp(Iter(a.get()), Sent(a.get()+N));
  88. }
  89. template<class Iter, class Sent = Iter>
  90. void
  91. test_iter_comp()
  92. {
  93. test_iter_comp<Iter, Sent>(1);
  94. test_iter_comp<Iter, Sent>(2);
  95. test_iter_comp<Iter, Sent>(3);
  96. test_iter_comp<Iter, Sent>(10);
  97. test_iter_comp<Iter, Sent>(1000);
  98. }
  99. struct S
  100. {
  101. int value;
  102. int index;
  103. };
  104. }
  105. int main()
  106. {
  107. test_iter<InputIterator<const int*> >();
  108. test_iter<ForwardIterator<const int*> >();
  109. test_iter<BidirectionalIterator<const int*> >();
  110. test_iter<RandomAccessIterator<const int*> >();
  111. test_iter<const int*>();
  112. test_iter<InputIterator<const int*>, Sentinel<const int*>>();
  113. test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
  114. test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
  115. test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
  116. test_iter<InputIterator<const int*> >();
  117. test_iter<ForwardIterator<const int*> >();
  118. test_iter<BidirectionalIterator<const int*> >();
  119. test_iter<RandomAccessIterator<const int*> >();
  120. test_iter<const int*>();
  121. test_iter<InputIterator<const int*>, Sentinel<const int*>>();
  122. test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
  123. test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
  124. test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
  125. test_iter_comp<InputIterator<const int*> >();
  126. test_iter_comp<ForwardIterator<const int*> >();
  127. test_iter_comp<BidirectionalIterator<const int*> >();
  128. test_iter_comp<RandomAccessIterator<const int*> >();
  129. test_iter_comp<const int*>();
  130. test_iter_comp<InputIterator<const int*>, Sentinel<const int*>>();
  131. test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
  132. test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
  133. test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
  134. test_iter_comp<InputIterator<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<InputIterator<const int*>, Sentinel<const int*>>();
  140. test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
  141. test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
  142. test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
  143. // Works with projections?
  144. S s[] = {S{1,0},S{2,1},S{3,2},S{4,3},S{-4,4},S{40,5},S{-4,6},S{40,7},S{7,8},S{8,9},S{9,10}};
  145. auto res = ranges::minmax(s, std::less<int>{}, &S::value);
  146. CHECK(res.min.value == -4);
  147. CHECK(res.min.index == 4);
  148. CHECK(res.max.value == 40);
  149. CHECK(res.max.index == 7);
  150. // Works with initializer_lists? (Regression test for #1004)
  151. CHECK(ranges::minmax({4,3,1,2,6,5}) == ranges::minmax_result<int>{1,6});
  152. return test_result();
  153. }