min.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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/min.hpp>
  21. #include <range/v3/view/subrange.hpp>
  22. #include <memory>
  23. #include <random>
  24. #include <numeric>
  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 v1 = ranges::min(rng);
  40. for (Iter i = first; i != last; ++i)
  41. CHECK(!(*i < v1));
  42. }
  43. template<class Iter, class Sent = Iter>
  44. void
  45. test_iter(unsigned N)
  46. {
  47. RANGES_ENSURE(N > 0);
  48. std::unique_ptr<int[]> a{new int[N]};
  49. std::iota(a.get(), a.get()+N, 0);
  50. std::shuffle(a.get(), a.get()+N, gen);
  51. test_iter(Iter(a.get()), Sent(a.get()+N));
  52. }
  53. template<class Iter, class Sent = Iter>
  54. void
  55. test_iter()
  56. {
  57. test_iter<Iter, Sent>(1);
  58. test_iter<Iter, Sent>(2);
  59. test_iter<Iter, Sent>(3);
  60. test_iter<Iter, Sent>(10);
  61. test_iter<Iter, Sent>(1000);
  62. }
  63. template<class Iter, class Sent = Iter>
  64. void
  65. test_iter_comp(Iter first, Sent last)
  66. {
  67. RANGES_ENSURE(first != last);
  68. auto rng = ranges::make_subrange(first, last);
  69. auto v = ranges::min(rng, std::greater<int>());
  70. for (Iter i = first; i != last; ++i)
  71. CHECK(!std::greater<int>()(*i, v));
  72. }
  73. template<class Iter, class Sent = Iter>
  74. void
  75. test_iter_comp(unsigned N)
  76. {
  77. RANGES_ENSURE(N > 0);
  78. std::unique_ptr<int[]> a{new int[N]};
  79. std::iota(a.get(), a.get()+N, 0);
  80. std::shuffle(a.get(), a.get()+N, gen);
  81. test_iter_comp(Iter(a.get()), Sent(a.get()+N));
  82. }
  83. template<class Iter, class Sent = Iter>
  84. void
  85. test_iter_comp()
  86. {
  87. test_iter_comp<Iter, Sent>(1);
  88. test_iter_comp<Iter, Sent>(2);
  89. test_iter_comp<Iter, Sent>(3);
  90. test_iter_comp<Iter, Sent>(10);
  91. test_iter_comp<Iter, Sent>(1000);
  92. }
  93. struct S
  94. {
  95. int i;
  96. };
  97. }
  98. int main()
  99. {
  100. test_iter<InputIterator<const int*> >();
  101. test_iter<ForwardIterator<const int*> >();
  102. test_iter<BidirectionalIterator<const int*> >();
  103. test_iter<RandomAccessIterator<const int*> >();
  104. test_iter<const int*>();
  105. test_iter<InputIterator<const int*>, Sentinel<const int*>>();
  106. test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
  107. test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
  108. test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
  109. test_iter_comp<InputIterator<const int*> >();
  110. test_iter_comp<ForwardIterator<const int*> >();
  111. test_iter_comp<BidirectionalIterator<const int*> >();
  112. test_iter_comp<RandomAccessIterator<const int*> >();
  113. test_iter_comp<const int*>();
  114. test_iter_comp<InputIterator<const int*>, Sentinel<const int*>>();
  115. test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
  116. test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
  117. test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
  118. // Works with projections?
  119. S s[] = {S{1},S{2},S{3},S{4},S{-4},S{5},S{6},S{7},S{8},S{9}};
  120. S v = ranges::min(s, std::less<int>{}, &S::i);
  121. CHECK(v.i == -4);
  122. // Works with initializer_lists? (Regression test for #1004)
  123. CHECK(ranges::min({4,3,1,2,6,5}) == 1);
  124. return test_result();
  125. }