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// void remove(const value_type& v); // C++17 and before
12// size_type remove(const value_type& v); // C++20 and after
13
14#include <forward_list>
15#include <iterator>
16#include <cassert>
17
18#include "test_macros.h"
19#include "min_allocator.h"
20
21template <class L>
22void do_remove(L &l, const typename L::value_type &value, typename L::size_type expected)
23{
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.remove(value)), typename L::size_type);
27 assert(l.remove(value) == expected);
28#else
29 ASSERT_SAME_TYPE(decltype(l.remove(value)), void);
30 l.remove(value);
31#endif
32 assert(old_size - std::distance(l.begin(), l.end()) == expected);
33}
34
35
36struct S {
37 S(int i) : i_(new int(i)) {}
38 S(const S &rhs) : i_(new int(*rhs.i_)) {}
39 S& operator = (const S &rhs) { *i_ = *rhs.i_; return *this; }
40 ~S () { delete i_; i_ = NULL; }
41 bool operator == (const S &rhs) const { return *i_ == *rhs.i_; }
42 int get () const { return *i_; }
43 int *i_;
44 };
45
46
47int main(int, char**)
48{
49 {
50 typedef int T;
51 typedef std::forward_list<T> C;
52 const T t1[] = {0, 5, 5, 0, 0, 0, 5};
53 const T t2[] = {5, 5, 5};
54 C c1(std::begin(arr: t1), std::end(arr: t1));
55 C c2(std::begin(arr: t2), std::end(arr: t2));
56 do_remove(l&: c1, value: 0, expected: 4);
57 assert(c1 == c2);
58 }
59 {
60 typedef int T;
61 typedef std::forward_list<T> C;
62 const T t1[] = {0, 0, 0, 0};
63 C c1(std::begin(arr: t1), std::end(arr: t1));
64 C c2;
65 do_remove(l&: c1, value: 0, expected: 4);
66 assert(c1 == c2);
67 }
68 {
69 typedef int T;
70 typedef std::forward_list<T> C;
71 const T t1[] = {5, 5, 5};
72 const T t2[] = {5, 5, 5};
73 C c1(std::begin(arr: t1), std::end(arr: t1));
74 C c2(std::begin(arr: t2), std::end(arr: t2));
75 do_remove(l&: c1, value: 0, expected: 0);
76 assert(c1 == c2);
77 }
78 {
79 typedef int T;
80 typedef std::forward_list<T> C;
81 C c1;
82 C c2;
83 do_remove(l&: c1, value: 0, expected: 0);
84 assert(c1 == c2);
85 }
86 {
87 typedef int T;
88 typedef std::forward_list<T> C;
89 const T t1[] = {5, 5, 5, 0};
90 const T t2[] = {5, 5, 5};
91 C c1(std::begin(arr: t1), std::end(arr: t1));
92 C c2(std::begin(arr: t2), std::end(arr: t2));
93 do_remove(l&: c1, value: 0, expected: 1);
94 assert(c1 == c2);
95 }
96 { // LWG issue #526
97 typedef int T;
98 typedef std::forward_list<T> C;
99 int t1[] = {1, 2, 1, 3, 5, 8, 11};
100 int t2[] = { 2, 3, 5, 8, 11};
101 C c1(std::begin(arr&: t1), std::end(arr&: t1));
102 C c2(std::begin(arr&: t2), std::end(arr&: t2));
103 do_remove(l&: c1, value: c1.front(), expected: 2);
104 assert(c1 == c2);
105 }
106 {
107 typedef S T;
108 typedef std::forward_list<T> C;
109 int t1[] = {1, 2, 1, 3, 5, 8, 11, 1};
110 int t2[] = { 2, 3, 5, 8, 11 };
111 C c;
112 for(int *ip = std::end(arr&: t1); ip != std::begin(arr&: t1);)
113 c.push_front(val: S(*--ip));
114 do_remove(l&: c, value: c.front(), expected: 3);
115 C::const_iterator it = c.begin();
116 for(int *ip = std::begin(arr&: t2); ip != std::end(arr&: t2); ++ip, ++it) {
117 assert ( it != c.end());
118 assert ( *ip == it->get());
119 }
120 assert ( it == c.end ());
121 }
122#if TEST_STD_VER >= 11
123 {
124 typedef int T;
125 typedef std::forward_list<T, min_allocator<T>> C;
126 const T t1[] = {0, 5, 5, 0, 0, 0, 5};
127 const T t2[] = {5, 5, 5};
128 C c1(std::begin(t1), std::end(t1));
129 C c2(std::begin(t2), std::end(t2));
130 do_remove(c1, 0, 4);
131 assert(c1 == c2);
132 }
133 {
134 typedef int T;
135 typedef std::forward_list<T, min_allocator<T>> C;
136 const T t1[] = {0, 0, 0, 0};
137 C c1(std::begin(t1), std::end(t1));
138 C c2;
139 do_remove(c1, 0, 4);
140 assert(c1 == c2);
141 }
142 {
143 typedef int T;
144 typedef std::forward_list<T, min_allocator<T>> C;
145 const T t1[] = {5, 5, 5};
146 const T t2[] = {5, 5, 5};
147 C c1(std::begin(t1), std::end(t1));
148 C c2(std::begin(t2), std::end(t2));
149 do_remove(c1, 0, 0);
150 assert(c1 == c2);
151 }
152 {
153 typedef int T;
154 typedef std::forward_list<T, min_allocator<T>> C;
155 C c1;
156 C c2;
157 do_remove(c1, 0, 0);
158 assert(c1 == c2);
159 }
160 {
161 typedef int T;
162 typedef std::forward_list<T, min_allocator<T>> C;
163 const T t1[] = {5, 5, 5, 0};
164 const T t2[] = {5, 5, 5};
165 C c1(std::begin(t1), std::end(t1));
166 C c2(std::begin(t2), std::end(t2));
167 do_remove(c1, 0, 1);
168 assert(c1 == c2);
169 }
170#endif
171
172 return 0;
173}
174

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