xref: /llvm-project/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp (revision f814dcbafbabd46a1babaeabec6acc3b70951bf4)
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