1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <algorithm>
11
12// template<ForwardIterator Iter, StrictWeakOrder<auto, Iter::value_type> Compare>
13//   requires CopyConstructible<Compare>
14//   Iter
15//   min_element(Iter first, Iter last, Compare comp);
16
17#include <algorithm>
18#include <functional>
19#include <random>
20#include <cassert>
21
22#include "test_macros.h"
23#include "test_iterators.h"
24
25std::mt19937 randomness;
26
27template <class Iter>
28void
29test(Iter first, Iter last)
30{
31    Iter i = std::min_element(first, last, std::greater<int>());
32    if (first != last)
33    {
34        for (Iter j = first; j != last; ++j)
35            assert(!std::greater<int>()(*j, *i));
36    }
37    else
38        assert(i == last);
39}
40
41template <class Iter>
42void
43test(int N)
44{
45    int* a = new int[N];
46    for (int i = 0; i < N; ++i)
47        a[i] = i;
48    std::shuffle(a, a+N, randomness);
49    test(Iter(a), Iter(a+N));
50    delete [] a;
51}
52
53template <class Iter>
54void
55test()
56{
57    test<Iter>(0);
58    test<Iter>(1);
59    test<Iter>(2);
60    test<Iter>(3);
61    test<Iter>(10);
62    test<Iter>(1000);
63}
64
65template <class Iter, class Pred>
66void test_eq0(Iter first, Iter last, Pred p)
67{
68    assert(first == std::min_element(first, last, p));
69}
70
71void test_eq()
72{
73    const int N = 10;
74    int* a = new int[N];
75    for (int i = 0; i < N; ++i)
76        a[i] = 10; // all the same
77    test_eq0(a, a+N, std::less<int>());
78    test_eq0(a, a+N, std::greater<int>());
79    delete [] a;
80}
81
82#if TEST_STD_VER >= 14
83constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
84struct less { constexpr bool operator ()( const int &x, const int &y) const { return x < y; }};
85#endif
86
87void constexpr_test()
88{
89#if TEST_STD_VER >= 14
90    constexpr auto p = std::min_element(il, il+8, less());
91    static_assert(*p == 1, "");
92#endif
93}
94
95int main()
96{
97    test<forward_iterator<const int*> >();
98    test<bidirectional_iterator<const int*> >();
99    test<random_access_iterator<const int*> >();
100    test<const int*>();
101    test_eq();
102
103    constexpr_test();
104}
105