91 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410// <optional>11 12// template <class U>13// optional(optional<U>&& rhs);14 15#include <cassert>16#include <memory>17#include <optional>18#include <type_traits>19#include <utility>20 21#include "test_macros.h"22 23using std::optional;24 25template <class T, class U>26TEST_CONSTEXPR_CXX20 void test(optional<U>&& rhs, bool is_going_to_throw = false) {27 bool rhs_engaged = static_cast<bool>(rhs);28#ifndef TEST_HAS_NO_EXCEPTIONS29 try {30 optional<T> lhs = std::move(rhs);31 assert(is_going_to_throw == false);32 assert(static_cast<bool>(lhs) == rhs_engaged);33 } catch (int i) {34 assert(i == 6);35 }36#else37 if (is_going_to_throw)38 return;39 optional<T> lhs = std::move(rhs);40 assert(static_cast<bool>(lhs) == rhs_engaged);41#endif42}43 44class X {45 int i_;46 47public:48 TEST_CONSTEXPR_CXX20 X(int i) : i_(i) {}49 TEST_CONSTEXPR_CXX20 X(X&& x) : i_(std::exchange(x.i_, 0)) {}50 TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; }51 friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; }52};53 54struct Z {55 Z(int) { TEST_THROW(6); }56};57 58template <class T, class U>59TEST_CONSTEXPR_CXX20 bool test_all() {60 {61 optional<T> rhs;62 test<U>(std::move(rhs));63 }64 {65 optional<T> rhs(short{3});66 test<U>(std::move(rhs));67 }68 return true;69}70 71int main(int, char**) {72 test_all<short, int>();73 test_all<int, X>();74#if TEST_STD_VER > 1775 static_assert(test_all<short, int>());76 static_assert(test_all<int, X>());77#endif78 {79 optional<int> rhs;80 test<Z>(std::move(rhs));81 }82 {83 optional<int> rhs(3);84 test<Z>(std::move(rhs), true);85 }86 87 static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "");88 89 return 0;90}91