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