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 TEST_CONSTEXPR_CXX20 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 TEST_CONSTEXPR_CXX20 X(int i) : i_(i) {} 52 TEST_CONSTEXPR_CXX20 X(X&& x) : i_(std::exchange(x.i_, 0)) {} 53 TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;} 54 friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} 55 }; 56 57 struct Z 58 { 59 Z(int) { TEST_THROW(6); } 60 }; 61 62 template<class T, class U> 63 TEST_CONSTEXPR_CXX20 bool test_all() 64 { 65 { 66 optional<T> rhs; 67 test<U>(std::move(rhs)); 68 } 69 { 70 optional<T> rhs(short{3}); 71 test<U>(std::move(rhs)); 72 } 73 return true; 74 } 75 76 int main(int, char**) 77 { 78 test_all<short, int>(); 79 test_all<int, X>(); 80 #if TEST_STD_VER > 17 81 static_assert(test_all<short, int>()); 82 static_assert(test_all<int, X>()); 83 #endif 84 { 85 optional<int> rhs; 86 test<Z>(std::move(rhs)); 87 } 88 { 89 optional<int> rhs(3); 90 test<Z>(std::move(rhs), true); 91 } 92 93 static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), ""); 94 95 return 0; 96 } 97