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
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>
23void do_unique(L &l, Predicate pred, typename L::size_type expected)
24{
25 typename L::size_type old_size = std::distance(l.begin(), l.end());
26#if TEST_STD_VER > 17
27 ASSERT_SAME_TYPE(decltype(l.unique(pred)), typename L::size_type);
28 assert(l.unique(pred) == expected);
29#else
30 ASSERT_SAME_TYPE(decltype(l.unique(pred)), void);
31 l.unique(pred);
32#endif
33 assert(old_size - std::distance(l.begin(), l.end()) == expected);
34}
35
36
37struct PredLWG526 {
38 PredLWG526(int i) : i_(i) {}
39 ~PredLWG526() { i_ = -32767; }
40 bool operator()(const PredLWG526& lhs, const PredLWG526& rhs) const { return lhs.i_ == rhs.i_; }
41
42 bool operator==(int i) const { return i == i_; }
43 int i_;
44};
45
46
47bool g(int x, int y)
48{
49 return x == y;
50}
51
52int main(int, char**)
53{
54 {
55 typedef int T;
56 typedef std::forward_list<T> C;
57 const T t1[] = {0, 5, 5, 0, 0, 0, 5};
58 const T t2[] = {0, 5, 0, 5};
59 C c1(std::begin(arr: t1), std::end(arr: t1));
60 C c2(std::begin(arr: t2), std::end(arr: t2));
61 do_unique(l&: c1, pred: g, expected: 3);
62 assert(c1 == c2);
63 }
64 {
65 typedef int T;
66 typedef std::forward_list<T> C;
67 const T t1[] = {0, 0, 0, 0};
68 const T t2[] = {0};
69 C c1(std::begin(arr: t1), std::end(arr: t1));
70 C c2(std::begin(arr: t2), std::end(arr: t2));
71 do_unique(l&: c1, pred: g, expected: 3);
72 assert(c1 == c2);
73 }
74 {
75 typedef int T;
76 typedef std::forward_list<T> C;
77 const T t1[] = {5, 5, 5};
78 const T t2[] = {5};
79 C c1(std::begin(arr: t1), std::end(arr: t1));
80 C c2(std::begin(arr: t2), std::end(arr: t2));
81 do_unique(l&: c1, pred: g, expected: 2);
82 assert(c1 == c2);
83 }
84 {
85 typedef int T;
86 typedef std::forward_list<T> C;
87 C c1;
88 C c2;
89 do_unique(l&: c1, pred: g, expected: 0);
90 assert(c1 == c2);
91 }
92 {
93 typedef int T;
94 typedef std::forward_list<T> C;
95 const T t1[] = {5, 5, 5, 0};
96 const T t2[] = {5, 0};
97 C c1(std::begin(arr: t1), std::end(arr: t1));
98 C c2(std::begin(arr: t2), std::end(arr: t2));
99 do_unique(l&: c1, pred: g, expected: 2);
100 assert(c1 == c2);
101 }
102
103 { // LWG issue #526
104 int a1[] = {1, 1, 1, 2, 3, 5, 2, 11};
105 int a2[] = {1, 2, 3, 5, 2, 11};
106 std::forward_list<PredLWG526> c1(a1, a1 + 8);
107 do_unique(l&: c1, pred: std::ref(t&: c1.front()), expected: 2);
108 for (std::size_t i = 0; i < 6; ++i)
109 {
110 assert(!c1.empty());
111 assert(c1.front() == a2[i]);
112 c1.pop_front();
113 }
114 assert(c1.empty());
115 }
116
117#if TEST_STD_VER >= 11
118 {
119 typedef int T;
120 typedef std::forward_list<T, min_allocator<T>> C;
121 const T t1[] = {0, 5, 5, 0, 0, 0, 5};
122 const T t2[] = {0, 5, 0, 5};
123 C c1(std::begin(t1), std::end(t1));
124 C c2(std::begin(t2), std::end(t2));
125 do_unique(c1, g, 3);
126 assert(c1 == c2);
127 }
128 {
129 typedef int T;
130 typedef std::forward_list<T, min_allocator<T>> C;
131 const T t1[] = {0, 0, 0, 0};
132 const T t2[] = {0};
133 C c1(std::begin(t1), std::end(t1));
134 C c2(std::begin(t2), std::end(t2));
135 do_unique(c1, g, 3);
136 assert(c1 == c2);
137 }
138 {
139 typedef int T;
140 typedef std::forward_list<T, min_allocator<T>> C;
141 const T t1[] = {5, 5, 5};
142 const T t2[] = {5};
143 C c1(std::begin(t1), std::end(t1));
144 C c2(std::begin(t2), std::end(t2));
145 do_unique(c1, g, 2);
146 assert(c1 == c2);
147 }
148 {
149 typedef int T;
150 typedef std::forward_list<T, min_allocator<T>> C;
151 C c1;
152 C c2;
153 do_unique(c1, g, 0);
154 assert(c1 == c2);
155 }
156 {
157 typedef int T;
158 typedef std::forward_list<T, min_allocator<T>> C;
159 const T t1[] = {5, 5, 5, 0};
160 const T t2[] = {5, 0};
161 C c1(std::begin(t1), std::end(t1));
162 C c2(std::begin(t2), std::end(t2));
163 do_unique(c1, g, 2);
164 assert(c1 == c2);
165 }
166#endif
167
168 return 0;
169}
170

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