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