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> void 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 opt.emplace(); 55 assert(static_cast<bool>(opt) == true); 56 assert(*opt == T(0)); 57 } 58 { 59 Opt opt; 60 opt.emplace(1); 61 assert(static_cast<bool>(opt) == true); 62 assert(*opt == T(1)); 63 } 64 { 65 Opt opt(2); 66 opt.emplace(); 67 assert(static_cast<bool>(opt) == true); 68 assert(*opt == T(0)); 69 } 70 { 71 Opt opt(2); 72 opt.emplace(1); 73 assert(static_cast<bool>(opt) == true); 74 assert(*opt == T(1)); 75 } 76 } 77 78 79 template <class T> 80 void test_multi_arg() 81 { 82 test_one_arg<T>(); 83 using Opt = std::optional<T>; 84 { 85 Opt opt; 86 opt.emplace(101, 41); 87 assert(static_cast<bool>(opt) == true); 88 assert(*opt == T(101, 41)); 89 } 90 { 91 Opt opt; 92 opt.emplace({1, 2, 3, 4}); 93 assert(static_cast<bool>(opt) == true); 94 assert(*opt == T(4)); // T sets its value to the size of the init list 95 } 96 { 97 Opt opt; 98 opt.emplace({1, 2, 3, 4, 5}, 6); 99 assert(static_cast<bool>(opt) == true); 100 assert(*opt == T(5)); // T sets its value to the size of the init list 101 } 102 } 103 104 template <class T> 105 void test_on_test_type() { 106 107 T::reset(); 108 optional<T> opt; 109 assert(T::alive == 0); 110 { 111 T::reset_constructors(); 112 opt.emplace(); 113 assert(T::alive == 1); 114 assert(T::constructed == 1); 115 assert(T::default_constructed == 1); 116 assert(T::destroyed == 0); 117 assert(static_cast<bool>(opt) == true); 118 assert(*opt == T()); 119 } 120 { 121 T::reset_constructors(); 122 opt.emplace(); 123 assert(T::alive == 1); 124 assert(T::constructed == 1); 125 assert(T::default_constructed == 1); 126 assert(T::destroyed == 1); 127 assert(static_cast<bool>(opt) == true); 128 assert(*opt == T()); 129 } 130 { 131 T::reset_constructors(); 132 opt.emplace(101); 133 assert(T::alive == 1); 134 assert(T::constructed == 1); 135 assert(T::value_constructed == 1); 136 assert(T::destroyed == 1); 137 assert(static_cast<bool>(opt) == true); 138 assert(*opt == T(101)); 139 } 140 { 141 T::reset_constructors(); 142 opt.emplace(-10, 99); 143 assert(T::alive == 1); 144 assert(T::constructed == 1); 145 assert(T::value_constructed == 1); 146 assert(T::destroyed == 1); 147 assert(static_cast<bool>(opt) == true); 148 assert(*opt == T(-10, 99)); 149 } 150 { 151 T::reset_constructors(); 152 opt.emplace(-10, 99); 153 assert(T::alive == 1); 154 assert(T::constructed == 1); 155 assert(T::value_constructed == 1); 156 assert(T::destroyed == 1); 157 assert(static_cast<bool>(opt) == true); 158 assert(*opt == T(-10, 99)); 159 } 160 { 161 T::reset_constructors(); 162 opt.emplace({-10, 99, 42, 1}); 163 assert(T::alive == 1); 164 assert(T::constructed == 1); 165 assert(T::value_constructed == 1); 166 assert(T::destroyed == 1); 167 assert(static_cast<bool>(opt) == true); 168 assert(*opt == T(4)); // size of the initializer list 169 } 170 { 171 T::reset_constructors(); 172 opt.emplace({-10, 99, 42, 1}, 42); 173 assert(T::alive == 1); 174 assert(T::constructed == 1); 175 assert(T::value_constructed == 1); 176 assert(T::destroyed == 1); 177 assert(static_cast<bool>(opt) == true); 178 assert(*opt == T(4)); // size of the initializer list 179 } 180 } 181 182 183 184 int main() 185 { 186 { 187 test_on_test_type<TestTypes::TestType>(); 188 test_on_test_type<ExplicitTestTypes::TestType>(); 189 } 190 { 191 using T = int; 192 test_one_arg<T>(); 193 test_one_arg<const T>(); 194 } 195 { 196 using T = ConstexprTestTypes::TestType; 197 test_multi_arg<T>(); 198 } 199 { 200 using T = ExplicitConstexprTestTypes::TestType; 201 test_multi_arg<T>(); 202 } 203 { 204 using T = TrivialTestTypes::TestType; 205 test_multi_arg<T>(); 206 } 207 { 208 using T = ExplicitTrivialTestTypes::TestType; 209 test_multi_arg<T>(); 210 } 211 { 212 optional<const int> opt; 213 opt.emplace(42); 214 assert(*opt == 42); 215 opt.emplace(); 216 assert(*opt == 0); 217 } 218 #ifndef TEST_HAS_NO_EXCEPTIONS 219 Y::dtor_called = false; 220 { 221 Y y; 222 optional<Y> opt(y); 223 try 224 { 225 assert(static_cast<bool>(opt) == true); 226 assert(Y::dtor_called == false); 227 opt.emplace(1); 228 } 229 catch (int i) 230 { 231 assert(i == 6); 232 assert(static_cast<bool>(opt) == false); 233 assert(Y::dtor_called == true); 234 } 235 } 236 #endif 237 } 238