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 "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> 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> 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> 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 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 }