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