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 // XFAIL: availability-bad_optional_access-missing && !no-exceptions
13 
14 // constexpr T& optional<T>::value() &&;
15 
16 #include <optional>
17 #include <type_traits>
18 #include <cassert>
19 
20 #include "test_macros.h"
21 
22 using std::optional;
23 using std::bad_optional_access;
24 
25 struct X
26 {
27     X() = default;
28     X(const X&) = delete;
29     constexpr int test() const & {return 3;}
30     int test() & {return 4;}
31     constexpr int test() const && {return 5;}
32     int test() && {return 6;}
33 };
34 
35 struct Y
36 {
37     constexpr int test() && {return 7;}
38 };
39 
40 constexpr int
41 test()
42 {
43     optional<Y> opt{Y{}};
44     return std::move(opt).value().test();
45 }
46 
47 int main(int, char**)
48 {
49     {
50         optional<X> opt; ((void)opt);
51         ASSERT_NOT_NOEXCEPT(std::move(opt).value());
52         ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X&&);
53     }
54     {
55         optional<X> opt;
56         opt.emplace();
57         assert(std::move(opt).value().test() == 6);
58     }
59 #ifndef TEST_HAS_NO_EXCEPTIONS
60     {
61         optional<X> opt;
62         try
63         {
64             (void)std::move(opt).value();
65             assert(false);
66         }
67         catch (const bad_optional_access&)
68         {
69         }
70     }
71 #endif
72     static_assert(test() == 7, "");
73 
74   return 0;
75 }
76