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