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 const T& optional<T>::value() const &&;
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::in_place_t;
26 using std::in_place;
27 using std::bad_optional_access;
28 
29 struct X
30 {
31     X() = default;
32     X(const X&) = delete;
testX33     constexpr int test() const & {return 3;}
testX34     int test() & {return 4;}
testX35     constexpr int test() const && {return 5;}
testX36     int test() && {return 6;}
37 };
38 
main(int,char **)39 int main(int, char**)
40 {
41     {
42         const optional<X> opt; ((void)opt);
43         ASSERT_NOT_NOEXCEPT(std::move(opt).value());
44         ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X const&&);
45     }
46     {
47         constexpr optional<X> opt(in_place);
48         static_assert(std::move(opt).value().test() == 5, "");
49     }
50     {
51         const optional<X> opt(in_place);
52         assert(std::move(opt).value().test() == 5);
53     }
54 #ifndef TEST_HAS_NO_EXCEPTIONS
55     {
56         const optional<X> opt;
57         try
58         {
59             (void)std::move(opt).value();
60             assert(false);
61         }
62         catch (const bad_optional_access&)
63         {
64         }
65     }
66 #endif
67 
68   return 0;
69 }
70