1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// <forward_list>
10
11// template <class BinaryPredicate> void unique(BinaryPredicate binary_pred); // C++17 and before
12// template <class BinaryPredicate> size_type unique(BinaryPredicate binary_pred); // C++20 and after; constexpr since C++26
13
14#include <cassert>
15#include <forward_list>
16#include <functional>
17#include <iterator>
18
19#include "test_macros.h"
20#include "min_allocator.h"
21
22template <class L, class Predicate>
23TEST_CONSTEXPR_CXX26 void do_unique(L& l, Predicate pred, typename L::size_type expected) {
24 typename L::size_type old_size = std::distance(l.begin(), l.end());
25#if TEST_STD_VER > 17
26 ASSERT_SAME_TYPE(decltype(l.unique(pred)), typename L::size_type);
27 assert(l.unique(pred) == expected);
28#else
29 ASSERT_SAME_TYPE(decltype(l.unique(pred)), void);
30 l.unique(pred);
31#endif
32 assert(old_size - std::distance(l.begin(), l.end()) == expected);
33}
34
35struct PredLWG526 {
36 TEST_CONSTEXPR_CXX20 PredLWG526(int i) : i_(i) {}
37 TEST_CONSTEXPR_CXX20 ~PredLWG526() { i_ = -32767; }
38 TEST_CONSTEXPR bool operator()(const PredLWG526& lhs, const PredLWG526& rhs) const { return lhs.i_ == rhs.i_; }
39
40 TEST_CONSTEXPR bool operator==(int i) const { return i == i_; }
41 int i_;
42};
43
44TEST_CONSTEXPR bool g(int x, int y) { return x == y; }
45
46TEST_CONSTEXPR_CXX26 bool test() {
47 {
48 typedef int T;
49 typedef std::forward_list<T> C;
50 const T t1[] = {0, 5, 5, 0, 0, 0, 5};
51 const T t2[] = {0, 5, 0, 5};
52 C c1(std::begin(arr: t1), std::end(arr: t1));
53 C c2(std::begin(arr: t2), std::end(arr: t2));
54 do_unique(c1, g, 3);
55 assert(c1 == c2);
56 }
57 {
58 typedef int T;
59 typedef std::forward_list<T> C;
60 const T t1[] = {0, 0, 0, 0};
61 const T t2[] = {0};
62 C c1(std::begin(arr: t1), std::end(arr: t1));
63 C c2(std::begin(arr: t2), std::end(arr: t2));
64 do_unique(c1, g, 3);
65 assert(c1 == c2);
66 }
67 {
68 typedef int T;
69 typedef std::forward_list<T> C;
70 const T t1[] = {5, 5, 5};
71 const T t2[] = {5};
72 C c1(std::begin(arr: t1), std::end(arr: t1));
73 C c2(std::begin(arr: t2), std::end(arr: t2));
74 do_unique(c1, g, 2);
75 assert(c1 == c2);
76 }
77 {
78 typedef int T;
79 typedef std::forward_list<T> C;
80 C c1;
81 C c2;
82 do_unique(c1, g, 0);
83 assert(c1 == c2);
84 }
85 {
86 typedef int T;
87 typedef std::forward_list<T> C;
88 const T t1[] = {5, 5, 5, 0};
89 const T t2[] = {5, 0};
90 C c1(std::begin(arr: t1), std::end(arr: t1));
91 C c2(std::begin(arr: t2), std::end(arr: t2));
92 do_unique(c1, g, 2);
93 assert(c1 == c2);
94 }
95
96 { // LWG issue #526
97 int a1[] = {1, 1, 1, 2, 3, 5, 2, 11};
98 int a2[] = {1, 2, 3, 5, 2, 11};
99 std::forward_list<PredLWG526> c1(a1, a1 + 8);
100 do_unique(c1, std::ref(t&: c1.front()), 2);
101 for (std::size_t i = 0; i < 6; ++i) {
102 assert(!c1.empty());
103 assert(c1.front() == a2[i]);
104 c1.pop_front();
105 }
106 assert(c1.empty());
107 }
108
109#if TEST_STD_VER >= 11
110 {
111 typedef int T;
112 typedef std::forward_list<T, min_allocator<T>> C;
113 const T t1[] = {0, 5, 5, 0, 0, 0, 5};
114 const T t2[] = {0, 5, 0, 5};
115 C c1(std::begin(t1), std::end(t1));
116 C c2(std::begin(t2), std::end(t2));
117 do_unique(c1, g, 3);
118 assert(c1 == c2);
119 }
120 {
121 typedef int T;
122 typedef std::forward_list<T, min_allocator<T>> C;
123 const T t1[] = {0, 0, 0, 0};
124 const T t2[] = {0};
125 C c1(std::begin(t1), std::end(t1));
126 C c2(std::begin(t2), std::end(t2));
127 do_unique(c1, g, 3);
128 assert(c1 == c2);
129 }
130 {
131 typedef int T;
132 typedef std::forward_list<T, min_allocator<T>> C;
133 const T t1[] = {5, 5, 5};
134 const T t2[] = {5};
135 C c1(std::begin(t1), std::end(t1));
136 C c2(std::begin(t2), std::end(t2));
137 do_unique(c1, g, 2);
138 assert(c1 == c2);
139 }
140 {
141 typedef int T;
142 typedef std::forward_list<T, min_allocator<T>> C;
143 C c1;
144 C c2;
145 do_unique(c1, g, 0);
146 assert(c1 == c2);
147 }
148 {
149 typedef int T;
150 typedef std::forward_list<T, min_allocator<T>> C;
151 const T t1[] = {5, 5, 5, 0};
152 const T t2[] = {5, 0};
153 C c1(std::begin(t1), std::end(t1));
154 C c2(std::begin(t2), std::end(t2));
155 do_unique(c1, g, 2);
156 assert(c1 == c2);
157 }
158#endif
159
160 return true;
161}
162
163int main(int, char**) {
164 assert(test());
165#if TEST_STD_VER >= 26
166 static_assert(test());
167#endif
168
169 return 0;
170}
171

source code of libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/unique_pred.pass.cpp