1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14 10 // <optional> 11 12 // template <class U> 13 // optional(optional<U>&& rhs); 14 15 #include <optional> 16 #include <type_traits> 17 #include <memory> 18 #include <cassert> 19 20 #include "test_macros.h" 21 22 using std::optional; 23 24 template <class T, class U> 25 void 26 test(optional<U>&& rhs, bool is_going_to_throw = false) 27 { 28 bool rhs_engaged = static_cast<bool>(rhs); 29 #ifndef TEST_HAS_NO_EXCEPTIONS 30 try 31 { 32 optional<T> lhs = std::move(rhs); 33 assert(is_going_to_throw == false); 34 assert(static_cast<bool>(lhs) == rhs_engaged); 35 } 36 catch (int i) 37 { 38 assert(i == 6); 39 } 40 #else 41 if (is_going_to_throw) return; 42 optional<T> lhs = std::move(rhs); 43 assert(static_cast<bool>(lhs) == rhs_engaged); 44 #endif 45 } 46 47 class X 48 { 49 int i_; 50 public: 51 X(int i) : i_(i) {} 52 X(X&& x) : i_(std::exchange(x.i_, 0)) {} 53 ~X() {i_ = 0;} 54 friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} 55 }; 56 57 int count = 0; 58 59 struct Z 60 { 61 Z(int) { TEST_THROW(6); } 62 }; 63 64 int main(int, char**) 65 { 66 { 67 optional<short> rhs; 68 test<int>(std::move(rhs)); 69 } 70 { 71 optional<short> rhs(short{3}); 72 test<int>(std::move(rhs)); 73 } 74 { 75 optional<int> rhs; 76 test<X>(std::move(rhs)); 77 } 78 { 79 optional<int> rhs(3); 80 test<X>(std::move(rhs)); 81 } 82 { 83 optional<int> rhs; 84 test<Z>(std::move(rhs)); 85 } 86 { 87 optional<int> rhs(3); 88 test<Z>(std::move(rhs), true); 89 } 90 91 static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), ""); 92 93 return 0; 94 } 95