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
24template <class LHS, class RHS>
25void 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
51template <class LHS>
52void 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
90void 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
127template <class Tp>
128void 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
183int 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

source code of libcxx/test/std/utilities/any/any.class/any.assign/copy.pass.cpp