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
21 template <class L>
do_remove(L & l,const typename L::value_type & value,typename L::size_type expected)22 void 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
36 struct S {
SS37 S(int i) : i_(new int(i)) {}
SS38 S(const S &rhs) : i_(new int(*rhs.i_)) {}
operator =S39 S& operator = (const S &rhs) { *i_ = *rhs.i_; return *this; }
~SS40 ~S () { delete i_; i_ = NULL; }
operator ==S41 bool operator == (const S &rhs) const { return *i_ == *rhs.i_; }
getS42 int get () const { return *i_; }
43 int *i_;
44 };
45
46
main(int,char **)47 int 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(t1), std::end(t1));
55 C c2(std::begin(t2), std::end(t2));
56 do_remove(c1, 0, 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(t1), std::end(t1));
64 C c2;
65 do_remove(c1, 0, 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(t1), std::end(t1));
74 C c2(std::begin(t2), std::end(t2));
75 do_remove(c1, 0, 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(c1, 0, 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(t1), std::end(t1));
92 C c2(std::begin(t2), std::end(t2));
93 do_remove(c1, 0, 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(t1), std::end(t1));
102 C c2(std::begin(t2), std::end(t2));
103 do_remove(c1, c1.front(), 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(t1); ip != std::begin(t1);)
113 c.push_front(S(*--ip));
114 do_remove(c, c.front(), 3);
115 C::const_iterator it = c.begin();
116 for(int *ip = std::begin(t2); ip != std::end(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