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 // <optional> 12 13 // template <class... Args> T& optional<T>::emplace(Args&&... args); 14 15 #include <optional> 16 #include <type_traits> 17 #include <cassert> 18 #include <memory> 19 20 #include "test_macros.h" 21 #include "archetypes.hpp" 22 23 using std::optional; 24 25 class X 26 { 27 int i_; 28 int j_ = 0; 29 public: 30 X() : i_(0) {} 31 X(int i) : i_(i) {} 32 X(int i, int j) : i_(i), j_(j) {} 33 34 friend bool operator==(const X& x, const X& y) 35 {return x.i_ == y.i_ && x.j_ == y.j_;} 36 }; 37 38 class Y 39 { 40 public: 41 static bool dtor_called; 42 Y() = default; 43 Y(int) { TEST_THROW(6);} 44 ~Y() {dtor_called = true;} 45 }; 46 47 bool Y::dtor_called = false; 48 49 template <class T> 50 void test_one_arg() { 51 using Opt = std::optional<T>; 52 { 53 Opt opt; 54 auto & v = opt.emplace(); 55 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 56 assert(static_cast<bool>(opt) == true); 57 assert(*opt == T(0)); 58 assert(&v == &*opt); 59 } 60 { 61 Opt opt; 62 auto & v = opt.emplace(1); 63 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 64 assert(static_cast<bool>(opt) == true); 65 assert(*opt == T(1)); 66 assert(&v == &*opt); 67 } 68 { 69 Opt opt(2); 70 auto & v = opt.emplace(); 71 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 72 assert(static_cast<bool>(opt) == true); 73 assert(*opt == T(0)); 74 assert(&v == &*opt); 75 } 76 { 77 Opt opt(2); 78 auto & v = opt.emplace(1); 79 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 80 assert(static_cast<bool>(opt) == true); 81 assert(*opt == T(1)); 82 assert(&v == &*opt); 83 } 84 } 85 86 87 template <class T> 88 void test_multi_arg() 89 { 90 test_one_arg<T>(); 91 using Opt = std::optional<T>; 92 { 93 Opt opt; 94 auto &v = opt.emplace(101, 41); 95 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 96 assert(static_cast<bool>(opt) == true); 97 assert( v == T(101, 41)); 98 assert(*opt == T(101, 41)); 99 } 100 { 101 Opt opt; 102 auto &v = opt.emplace({1, 2, 3, 4}); 103 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 104 assert(static_cast<bool>(opt) == true); 105 assert( v == T(4)); // T sets its value to the size of the init list 106 assert(*opt == T(4)); 107 } 108 { 109 Opt opt; 110 auto &v = opt.emplace({1, 2, 3, 4, 5}, 6); 111 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 112 assert(static_cast<bool>(opt) == true); 113 assert( v == T(5)); // T sets its value to the size of the init list 114 assert(*opt == T(5)); // T sets its value to the size of the init list 115 } 116 } 117 118 template <class T> 119 void test_on_test_type() { 120 121 T::reset(); 122 optional<T> opt; 123 assert(T::alive == 0); 124 { 125 T::reset_constructors(); 126 auto &v = opt.emplace(); 127 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 128 assert(T::alive == 1); 129 assert(T::constructed == 1); 130 assert(T::default_constructed == 1); 131 assert(T::destroyed == 0); 132 assert(static_cast<bool>(opt) == true); 133 assert(*opt == T()); 134 assert(&v == &*opt); 135 } 136 { 137 T::reset_constructors(); 138 auto &v = opt.emplace(); 139 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 140 assert(T::alive == 1); 141 assert(T::constructed == 1); 142 assert(T::default_constructed == 1); 143 assert(T::destroyed == 1); 144 assert(static_cast<bool>(opt) == true); 145 assert(*opt == T()); 146 assert(&v == &*opt); 147 } 148 { 149 T::reset_constructors(); 150 auto &v = opt.emplace(101); 151 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 152 assert(T::alive == 1); 153 assert(T::constructed == 1); 154 assert(T::value_constructed == 1); 155 assert(T::destroyed == 1); 156 assert(static_cast<bool>(opt) == true); 157 assert(*opt == T(101)); 158 assert(&v == &*opt); 159 } 160 { 161 T::reset_constructors(); 162 auto &v = opt.emplace(-10, 99); 163 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 164 assert(T::alive == 1); 165 assert(T::constructed == 1); 166 assert(T::value_constructed == 1); 167 assert(T::destroyed == 1); 168 assert(static_cast<bool>(opt) == true); 169 assert(*opt == T(-10, 99)); 170 assert(&v == &*opt); 171 } 172 { 173 T::reset_constructors(); 174 auto &v = opt.emplace(-10, 99); 175 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 176 assert(T::alive == 1); 177 assert(T::constructed == 1); 178 assert(T::value_constructed == 1); 179 assert(T::destroyed == 1); 180 assert(static_cast<bool>(opt) == true); 181 assert(*opt == T(-10, 99)); 182 assert(&v == &*opt); 183 } 184 { 185 T::reset_constructors(); 186 auto &v = opt.emplace({-10, 99, 42, 1}); 187 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 188 assert(T::alive == 1); 189 assert(T::constructed == 1); 190 assert(T::value_constructed == 1); 191 assert(T::destroyed == 1); 192 assert(static_cast<bool>(opt) == true); 193 assert(*opt == T(4)); // size of the initializer list 194 assert(&v == &*opt); 195 } 196 { 197 T::reset_constructors(); 198 auto &v = opt.emplace({-10, 99, 42, 1}, 42); 199 static_assert( std::is_same_v<T&, decltype(v)>, "" ); 200 assert(T::alive == 1); 201 assert(T::constructed == 1); 202 assert(T::value_constructed == 1); 203 assert(T::destroyed == 1); 204 assert(static_cast<bool>(opt) == true); 205 assert(*opt == T(4)); // size of the initializer list 206 assert(&v == &*opt); 207 } 208 } 209 210 211 212 int main() 213 { 214 { 215 test_on_test_type<TestTypes::TestType>(); 216 test_on_test_type<ExplicitTestTypes::TestType>(); 217 } 218 { 219 using T = int; 220 test_one_arg<T>(); 221 test_one_arg<const T>(); 222 } 223 { 224 using T = ConstexprTestTypes::TestType; 225 test_multi_arg<T>(); 226 } 227 { 228 using T = ExplicitConstexprTestTypes::TestType; 229 test_multi_arg<T>(); 230 } 231 { 232 using T = TrivialTestTypes::TestType; 233 test_multi_arg<T>(); 234 } 235 { 236 using T = ExplicitTrivialTestTypes::TestType; 237 test_multi_arg<T>(); 238 } 239 { 240 optional<const int> opt; 241 auto &v = opt.emplace(42); 242 static_assert( std::is_same_v<const int&, decltype(v)>, "" ); 243 assert(*opt == 42); 244 assert( v == 42); 245 opt.emplace(); 246 assert(*opt == 0); 247 } 248 #ifndef TEST_HAS_NO_EXCEPTIONS 249 Y::dtor_called = false; 250 { 251 Y y; 252 optional<Y> opt(y); 253 try 254 { 255 assert(static_cast<bool>(opt) == true); 256 assert(Y::dtor_called == false); 257 auto &v = opt.emplace(1); 258 static_assert( std::is_same_v<Y&, decltype(v)>, "" ); 259 assert(false); 260 } 261 catch (int i) 262 { 263 assert(i == 6); 264 assert(static_cast<bool>(opt) == false); 265 assert(Y::dtor_called == true); 266 } 267 } 268 #endif 269 } 270