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