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