max.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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/max.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 v = ranges::max(rng);
  40. for (Iter i = first; i != last; ++i)
  41. CHECK(!(v < *i));
  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 comp = std::greater<int>();
  70. auto v = ranges::max(rng, comp);
  71. for (Iter i = first; i != last; ++i)
  72. CHECK(!comp(v, *i));
  73. }
  74. template<class Iter, class Sent = Iter>
  75. void
  76. test_iter_comp(unsigned N)
  77. {
  78. RANGES_ENSURE(N > 0);
  79. std::unique_ptr<int[]> a{new int[N]};
  80. std::iota(a.get(), a.get()+N, 0);
  81. std::shuffle(a.get(), a.get()+N, gen);
  82. test_iter_comp(Iter(a.get()), Sent(a.get()+N));
  83. }
  84. template<class Iter, class Sent = Iter>
  85. void
  86. test_iter_comp()
  87. {
  88. test_iter_comp<Iter, Sent>(1);
  89. test_iter_comp<Iter, Sent>(2);
  90. test_iter_comp<Iter, Sent>(3);
  91. test_iter_comp<Iter, Sent>(10);
  92. test_iter_comp<Iter, Sent>(1000);
  93. }
  94. struct S
  95. {
  96. int i;
  97. };
  98. }
  99. int main()
  100. {
  101. test_iter<InputIterator<const int*> >();
  102. test_iter<ForwardIterator<const int*> >();
  103. test_iter<BidirectionalIterator<const int*> >();
  104. test_iter<RandomAccessIterator<const int*> >();
  105. test_iter<const int*>();
  106. test_iter<InputIterator<const int*>, Sentinel<const int*>>();
  107. test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
  108. test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
  109. test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
  110. test_iter_comp<InputIterator<const int*> >();
  111. test_iter_comp<ForwardIterator<const int*> >();
  112. test_iter_comp<BidirectionalIterator<const int*> >();
  113. test_iter_comp<RandomAccessIterator<const int*> >();
  114. test_iter_comp<const int*>();
  115. test_iter_comp<InputIterator<const int*>, Sentinel<const int*>>();
  116. test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
  117. test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
  118. test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
  119. // Works with projections?
  120. S s[] = {S{1},S{2},S{3},S{4},S{40},S{5},S{6},S{7},S{8},S{9}};
  121. S v = ranges::max(s, std::less<int>{}, &S::i);
  122. CHECK(v.i == 40);
  123. // Works with initializer_lists? (Regression test for #1004)
  124. CHECK(ranges::max({4,3,1,2,6,5}) == 6);
  125. return test_result();
  126. }