xref: /llvm-project/libcxx/test/std/utilities/any/any.class/any.assign/copy.pass.cpp (revision ec350ad418a24f70c88758259c774a1e11c06d74)
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 // UNSUPPORTED: c++03, c++11, c++14
10 
11 // <any>
12 
13 // any& operator=(const any&);
14 
15 // Test copy assignment
16 
17 #include <any>
18 #include <cassert>
19 
20 #include "any_helpers.h"
21 #include "count_new.h"
22 #include "test_macros.h"
23 
24 template <class LHS, class RHS>
test_copy_assign()25 void test_copy_assign() {
26     assert(LHS::count == 0);
27     assert(RHS::count == 0);
28     LHS::reset();
29     RHS::reset();
30     {
31         std::any lhs = LHS(1);
32         const std::any rhs = RHS(2);
33 
34         assert(LHS::count == 1);
35         assert(RHS::count == 1);
36         assert(RHS::copied == 0);
37 
38         lhs = rhs;
39 
40         assert(RHS::copied == 1);
41         assert(LHS::count == 0);
42         assert(RHS::count == 2);
43 
44         assertContains<RHS>(lhs, 2);
45         assertContains<RHS>(rhs, 2);
46     }
47     assert(LHS::count == 0);
48     assert(RHS::count == 0);
49 }
50 
51 template <class LHS>
test_copy_assign_empty()52 void test_copy_assign_empty() {
53     assert(LHS::count == 0);
54     LHS::reset();
55     {
56         std::any lhs;
57         const std::any rhs = LHS(42);
58 
59         assert(LHS::count == 1);
60         assert(LHS::copied == 0);
61 
62         lhs = rhs;
63 
64         assert(LHS::copied == 1);
65         assert(LHS::count == 2);
66 
67         assertContains<LHS>(lhs, 42);
68         assertContains<LHS>(rhs, 42);
69     }
70     assert(LHS::count == 0);
71     LHS::reset();
72     {
73         std::any lhs = LHS(1);
74         const std::any rhs;
75 
76         assert(LHS::count == 1);
77         assert(LHS::copied == 0);
78 
79         lhs = rhs;
80 
81         assert(LHS::copied == 0);
82         assert(LHS::count == 0);
83 
84         assertEmpty<LHS>(lhs);
85         assertEmpty(rhs);
86     }
87     assert(LHS::count == 0);
88 }
89 
test_copy_assign_self()90 void test_copy_assign_self() {
91     // empty
92     {
93         std::any a;
94         a = (std::any&)a;
95         assertEmpty(a);
96         assert(globalMemCounter.checkOutstandingNewEq(0));
97     }
98     assert(globalMemCounter.checkOutstandingNewEq(0));
99     // small
100     {
101         std::any a = small(1);
102         assert(small::count == 1);
103 
104         a = (std::any&)a;
105 
106         assert(small::count == 1);
107         assertContains<small>(a, 1);
108         assert(globalMemCounter.checkOutstandingNewEq(0));
109     }
110     assert(small::count == 0);
111     assert(globalMemCounter.checkOutstandingNewEq(0));
112     // large
113     {
114         std::any a = large(1);
115         assert(large::count == 1);
116 
117         a = (std::any&)a;
118 
119         assert(large::count == 1);
120         assertContains<large>(a, 1);
121         assert(globalMemCounter.checkOutstandingNewEq(1));
122     }
123     assert(large::count == 0);
124     assert(globalMemCounter.checkOutstandingNewEq(0));
125 }
126 
127 template <class Tp>
test_copy_assign_throws()128 void test_copy_assign_throws()
129 {
130 #if !defined(TEST_HAS_NO_EXCEPTIONS)
131     auto try_throw =
132     [](std::any& lhs, const std::any& rhs) {
133         try {
134             lhs = rhs;
135             assert(false);
136         } catch (const my_any_exception&) {
137             // do nothing
138         } catch (...) {
139             assert(false);
140         }
141     };
142     // const lvalue to empty
143     {
144         std::any lhs;
145         const std::any rhs = Tp(1);
146         assert(Tp::count == 1);
147 
148         try_throw(lhs, rhs);
149 
150         assert(Tp::count == 1);
151         assertEmpty<Tp>(lhs);
152         assertContains<Tp>(rhs, 1);
153     }
154     {
155         std::any lhs = small(2);
156         const std::any rhs = Tp(1);
157         assert(small::count == 1);
158         assert(Tp::count == 1);
159 
160         try_throw(lhs, rhs);
161 
162         assert(small::count == 1);
163         assert(Tp::count == 1);
164         assertContains<small>(lhs, 2);
165         assertContains<Tp>(rhs, 1);
166     }
167     {
168         std::any lhs = large(2);
169         const std::any rhs = Tp(1);
170         assert(large::count == 1);
171         assert(Tp::count == 1);
172 
173         try_throw(lhs, rhs);
174 
175         assert(large::count == 1);
176         assert(Tp::count == 1);
177         assertContains<large>(lhs, 2);
178         assertContains<Tp>(rhs, 1);
179     }
180 #endif
181 }
182 
main(int,char **)183 int main(int, char**) {
184     globalMemCounter.reset();
185     test_copy_assign<small1, small2>();
186     test_copy_assign<large1, large2>();
187     test_copy_assign<small, large>();
188     test_copy_assign<large, small>();
189     test_copy_assign_empty<small>();
190     test_copy_assign_empty<large>();
191     test_copy_assign_self();
192     test_copy_assign_throws<small_throws_on_copy>();
193     test_copy_assign_throws<large_throws_on_copy>();
194 
195   return 0;
196 }
197