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, Predicate<auto, Iter::value_type> Pred>
13//   requires OutputIterator<Iter, RvalueOf<Iter::reference>::type>
14//         && CopyConstructible<Pred>
15//   constexpr Iter         // constexpr after C++17
16//   remove_if(Iter first, Iter last, Pred pred);
17
18#include <algorithm>
19#include <functional>
20#include <cassert>
21#include <memory>
22
23#include "test_macros.h"
24#include "test_iterators.h"
25#include "counting_predicates.hpp"
26
27TEST_CONSTEXPR bool equal2 ( int i ) { return i == 2; }
28
29#if TEST_STD_VER > 17
30TEST_CONSTEXPR bool test_constexpr() {
31    int ia[] = {1, 3, 5, 2, 5, 6};
32
33    auto it = std::remove_if(std::begin(ia), std::end(ia), equal2);
34
35    return (std::begin(ia) + std::size(ia) - 1) == it  // we removed one element
36        && std::none_of(std::begin(ia), it, equal2)
37           ;
38    }
39#endif
40
41template <class Iter>
42void
43test()
44{
45    int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
46    const unsigned sa = sizeof(ia)/sizeof(ia[0]);
47//     int* r = std::remove_if(ia, ia+sa, std::bind2nd(std::equal_to<int>(), 2));
48    unary_counting_predicate<bool(*)(int), int> cp(equal2);
49    int* r = std::remove_if(ia, ia+sa, std::ref(cp));
50    assert(r == ia + sa-3);
51    assert(ia[0] == 0);
52    assert(ia[1] == 1);
53    assert(ia[2] == 3);
54    assert(ia[3] == 4);
55    assert(ia[4] == 3);
56    assert(ia[5] == 4);
57    assert(cp.count() == sa);
58}
59
60#if TEST_STD_VER >= 11
61struct pred
62{
63    bool operator()(const std::unique_ptr<int>& i) {return *i == 2;}
64};
65
66template <class Iter>
67void
68test1()
69{
70    const unsigned sa = 9;
71    std::unique_ptr<int> ia[sa];
72    ia[0].reset(new int(0));
73    ia[1].reset(new int(1));
74    ia[2].reset(new int(2));
75    ia[3].reset(new int(3));
76    ia[4].reset(new int(4));
77    ia[5].reset(new int(2));
78    ia[6].reset(new int(3));
79    ia[7].reset(new int(4));
80    ia[8].reset(new int(2));
81    Iter r = std::remove_if(Iter(ia), Iter(ia+sa), pred());
82    assert(base(r) == ia + sa-3);
83    assert(*ia[0] == 0);
84    assert(*ia[1] == 1);
85    assert(*ia[2] == 3);
86    assert(*ia[3] == 4);
87    assert(*ia[4] == 3);
88    assert(*ia[5] == 4);
89}
90#endif // TEST_STD_VER >= 11
91
92int main()
93{
94    test<forward_iterator<int*> >();
95    test<bidirectional_iterator<int*> >();
96    test<random_access_iterator<int*> >();
97    test<int*>();
98
99#if TEST_STD_VER >= 11
100    test1<forward_iterator<std::unique_ptr<int>*> >();
101    test1<bidirectional_iterator<std::unique_ptr<int>*> >();
102    test1<random_access_iterator<std::unique_ptr<int>*> >();
103    test1<std::unique_ptr<int>*>();
104#endif // TEST_STD_VER >= 11
105
106#if TEST_STD_VER > 17
107    static_assert(test_constexpr());
108#endif
109}
110