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 value copy and move 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_assign_value()29 void test_assign_value() {
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 LHS::reset();
54 RHS::reset();
55 {
56 any lhs(LHS(1));
57 any rhs(RHS(2));
58
59 assert(LHS::count == 1);
60 assert(RHS::count == 1);
61 assert(RHS::moved == 1);
62
63 lhs = std::move(rhs);
64
65 assert(RHS::moved >= 1);
66 assert(RHS::copied == 0);
67 assert(LHS::count == 0);
68 assert(RHS::count == 1);
69
70 assertContains<RHS>(lhs, 2);
71 assertEmpty<RHS>(rhs);
72 }
73 assert(LHS::count == 0);
74 assert(RHS::count == 0);
75 }
76
77 template <class RHS>
test_assign_value_empty()78 void test_assign_value_empty() {
79 assert(RHS::count == 0);
80 RHS::reset();
81 {
82 any lhs;
83 RHS rhs(42);
84 assert(RHS::count == 1);
85 assert(RHS::copied == 0);
86
87 lhs = rhs;
88
89 assert(RHS::count == 2);
90 assert(RHS::copied == 1);
91 assert(RHS::moved >= 0);
92 assertContains<RHS>(lhs, 42);
93 }
94 assert(RHS::count == 0);
95 RHS::reset();
96 {
97 any lhs;
98 RHS rhs(42);
99 assert(RHS::count == 1);
100 assert(RHS::moved == 0);
101
102 lhs = std::move(rhs);
103
104 assert(RHS::count == 2);
105 assert(RHS::copied == 0);
106 assert(RHS::moved >= 1);
107 assertContains<RHS>(lhs, 42);
108 }
109 assert(RHS::count == 0);
110 RHS::reset();
111 }
112
113
114 template <class Tp, bool Move = false>
test_assign_throws()115 void test_assign_throws() {
116 #if !defined(TEST_HAS_NO_EXCEPTIONS)
117 auto try_throw=
118 [](any& lhs, auto&& rhs) {
119 try {
120 Move ? lhs = std::move(rhs)
121 : lhs = rhs;
122 assert(false);
123 } catch (my_any_exception const &) {
124 // do nothing
125 } catch (...) {
126 assert(false);
127 }
128 };
129 // const lvalue to empty
130 {
131 any lhs;
132 Tp rhs(1);
133 assert(Tp::count == 1);
134
135 try_throw(lhs, rhs);
136
137 assert(Tp::count == 1);
138 assertEmpty<Tp>(lhs);
139 }
140 {
141 any lhs((small(2)));
142 Tp rhs(1);
143 assert(small::count == 1);
144 assert(Tp::count == 1);
145
146 try_throw(lhs, rhs);
147
148 assert(small::count == 1);
149 assert(Tp::count == 1);
150 assertContains<small>(lhs, 2);
151 }
152 {
153 any lhs((large(2)));
154 Tp rhs(1);
155 assert(large::count == 1);
156 assert(Tp::count == 1);
157
158 try_throw(lhs, rhs);
159
160 assert(large::count == 1);
161 assert(Tp::count == 1);
162 assertContains<large>(lhs, 2);
163 }
164 #endif
165 }
166
main()167 int main() {
168 test_assign_value<small1, small2>();
169 test_assign_value<large1, large2>();
170 test_assign_value<small, large>();
171 test_assign_value<large, small>();
172 test_assign_value_empty<small>();
173 test_assign_value_empty<large>();
174 test_assign_throws<small_throws_on_copy>();
175 test_assign_throws<large_throws_on_copy>();
176 test_assign_throws<throws_on_move, /* Move = */ true>();
177 }