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 // <optional> 12 13 // optional(optional<T>&& rhs) noexcept(is_nothrow_move_constructible<T>::value); 14 15 #include <experimental/optional> 16 #include <type_traits> 17 #include <cassert> 18 19 #include "test_macros.h" 20 21 using std::experimental::optional; 22 23 template <class T> 24 void 25 test(optional<T>& rhs, bool is_going_to_throw = false) 26 { 27 static_assert(std::is_nothrow_move_constructible<optional<T>>::value == 28 std::is_nothrow_move_constructible<T>::value, ""); 29 bool rhs_engaged = static_cast<bool>(rhs); 30 #ifdef TEST_HAS_NO_EXCEPTIONS 31 if (is_going_to_throw) 32 return; 33 #else 34 try 35 #endif 36 { 37 optional<T> lhs = std::move(rhs); 38 assert(is_going_to_throw == false); 39 assert(static_cast<bool>(lhs) == rhs_engaged); 40 } 41 #ifndef TEST_HAS_NO_EXCEPTIONS 42 catch (int i) 43 { 44 assert(i == 6); 45 assert(is_going_to_throw); 46 } 47 #endif 48 } 49 50 class X 51 { 52 int i_; 53 public: 54 X(int i) : i_(i) {} 55 X(X&& x) : i_(x.i_) {x.i_ = 0;} 56 ~X() {i_ = 0;} 57 friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} 58 }; 59 60 class Y 61 { 62 int i_; 63 public: 64 Y(int i) : i_(i) {} 65 Y(Y&& x) noexcept : i_(x.i_) {x.i_ = 0;} 66 67 friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} 68 }; 69 70 int count = 0; 71 72 class Z 73 { 74 int i_; 75 public: 76 Z(int i) : i_(i) {} 77 Z(Z&&) 78 { 79 if (++count == 2) 80 TEST_THROW(6); 81 } 82 83 friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} 84 }; 85 86 87 class ConstMovable 88 { 89 int i_; 90 public: 91 ConstMovable(int i) : i_(i) {} 92 ConstMovable(const ConstMovable&& x) : i_(x.i_) {} 93 ~ConstMovable() {i_ = 0;} 94 friend bool operator==(const ConstMovable& x, const ConstMovable& y) {return x.i_ == y.i_;} 95 }; 96 97 int main() 98 { 99 { 100 typedef int T; 101 optional<T> rhs; 102 test(rhs); 103 } 104 { 105 typedef int T; 106 optional<T> rhs(3); 107 test(rhs); 108 } 109 { 110 typedef const int T; 111 optional<T> rhs(3); 112 test(rhs); 113 } 114 { 115 typedef X T; 116 optional<T> rhs; 117 test(rhs); 118 } 119 { 120 typedef X T; 121 optional<T> rhs(X(3)); 122 test(rhs); 123 } 124 { 125 typedef const ConstMovable T; 126 optional<T> rhs(ConstMovable(3)); 127 test(rhs); 128 } 129 { 130 typedef Y T; 131 optional<T> rhs; 132 test(rhs); 133 } 134 { 135 typedef Y T; 136 optional<T> rhs(Y(3)); 137 test(rhs); 138 } 139 { 140 typedef Z T; 141 optional<T> rhs; 142 test(rhs); 143 } 144 { 145 typedef Z T; 146 optional<T> rhs(Z(3)); 147 test(rhs, true); 148 } 149 } 150