1a9e65961SEric Fiselier //===----------------------------------------------------------------------===//
2a9e65961SEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a9e65961SEric Fiselier //
7a9e65961SEric Fiselier //===----------------------------------------------------------------------===//
8a9e65961SEric Fiselier
931cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14
10a9e65961SEric Fiselier // <optional>
11a9e65961SEric Fiselier
12a9e65961SEric Fiselier // template <class U>
13a9e65961SEric Fiselier // optional(optional<U>&& rhs);
14a9e65961SEric Fiselier
15*52915d78SNikolas Klauser #include <cassert>
16*52915d78SNikolas Klauser #include <memory>
17a9e65961SEric Fiselier #include <optional>
18a9e65961SEric Fiselier #include <type_traits>
19*52915d78SNikolas Klauser #include <utility>
20a9e65961SEric Fiselier
21a9e65961SEric Fiselier #include "test_macros.h"
22a9e65961SEric Fiselier
23a9e65961SEric Fiselier using std::optional;
24a9e65961SEric Fiselier
25a9e65961SEric Fiselier template <class T, class U>
2654644993SChristopher Di Bella TEST_CONSTEXPR_CXX20 void
test(optional<U> && rhs,bool is_going_to_throw=false)27a9e65961SEric Fiselier test(optional<U>&& rhs, bool is_going_to_throw = false)
28a9e65961SEric Fiselier {
29a9e65961SEric Fiselier bool rhs_engaged = static_cast<bool>(rhs);
30a9e65961SEric Fiselier #ifndef TEST_HAS_NO_EXCEPTIONS
31a9e65961SEric Fiselier try
32a9e65961SEric Fiselier {
33a9e65961SEric Fiselier optional<T> lhs = std::move(rhs);
34a9e65961SEric Fiselier assert(is_going_to_throw == false);
35a9e65961SEric Fiselier assert(static_cast<bool>(lhs) == rhs_engaged);
36a9e65961SEric Fiselier }
37a9e65961SEric Fiselier catch (int i)
38a9e65961SEric Fiselier {
39a9e65961SEric Fiselier assert(i == 6);
40a9e65961SEric Fiselier }
41a9e65961SEric Fiselier #else
42a9e65961SEric Fiselier if (is_going_to_throw) return;
43a9e65961SEric Fiselier optional<T> lhs = std::move(rhs);
44a9e65961SEric Fiselier assert(static_cast<bool>(lhs) == rhs_engaged);
45a9e65961SEric Fiselier #endif
46a9e65961SEric Fiselier }
47a9e65961SEric Fiselier
48a9e65961SEric Fiselier class X
49a9e65961SEric Fiselier {
50a9e65961SEric Fiselier int i_;
51a9e65961SEric Fiselier public:
X(int i)5254644993SChristopher Di Bella TEST_CONSTEXPR_CXX20 X(int i) : i_(i) {}
X(X && x)5354644993SChristopher Di Bella TEST_CONSTEXPR_CXX20 X(X&& x) : i_(std::exchange(x.i_, 0)) {}
~X()5454644993SChristopher Di Bella TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;}
operator ==(const X & x,const X & y)5554644993SChristopher Di Bella friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
56a9e65961SEric Fiselier };
57a9e65961SEric Fiselier
58a9e65961SEric Fiselier struct Z
59a9e65961SEric Fiselier {
ZZ60a9e65961SEric Fiselier Z(int) { TEST_THROW(6); }
61a9e65961SEric Fiselier };
62a9e65961SEric Fiselier
6354644993SChristopher Di Bella template<class T, class U>
test_all()6454644993SChristopher Di Bella TEST_CONSTEXPR_CXX20 bool test_all()
6554644993SChristopher Di Bella {
6654644993SChristopher Di Bella {
6754644993SChristopher Di Bella optional<T> rhs;
6854644993SChristopher Di Bella test<U>(std::move(rhs));
6954644993SChristopher Di Bella }
7054644993SChristopher Di Bella {
7154644993SChristopher Di Bella optional<T> rhs(short{3});
7254644993SChristopher Di Bella test<U>(std::move(rhs));
7354644993SChristopher Di Bella }
7454644993SChristopher Di Bella return true;
7554644993SChristopher Di Bella }
7654644993SChristopher Di Bella
main(int,char **)772df59c50SJF Bastien int main(int, char**)
78a9e65961SEric Fiselier {
7954644993SChristopher Di Bella test_all<short, int>();
8054644993SChristopher Di Bella test_all<int, X>();
8154644993SChristopher Di Bella #if TEST_STD_VER > 17
8254644993SChristopher Di Bella static_assert(test_all<short, int>());
8354644993SChristopher Di Bella static_assert(test_all<int, X>());
8454644993SChristopher Di Bella #endif
85a9e65961SEric Fiselier {
86a9e65961SEric Fiselier optional<int> rhs;
87a9e65961SEric Fiselier test<Z>(std::move(rhs));
88a9e65961SEric Fiselier }
89a9e65961SEric Fiselier {
90a9e65961SEric Fiselier optional<int> rhs(3);
91a9e65961SEric Fiselier test<Z>(std::move(rhs), true);
92a9e65961SEric Fiselier }
93a9e65961SEric Fiselier
94a9e65961SEric Fiselier static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "");
952df59c50SJF Bastien
962df59c50SJF Bastien return 0;
97a9e65961SEric Fiselier }
98