1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
11 // <optional>
12 
13 // XFAIL: availability=macosx10.13
14 // XFAIL: availability=macosx10.12
15 // XFAIL: availability=macosx10.11
16 // XFAIL: availability=macosx10.10
17 // XFAIL: availability=macosx10.9
18 // XFAIL: availability=macosx10.8
19 // XFAIL: availability=macosx10.7
20 
21 // constexpr T& optional<T>::value() &&;
22 
23 #include <optional>
24 #include <type_traits>
25 #include <cassert>
26 
27 #include "test_macros.h"
28 
29 using std::optional;
30 using std::bad_optional_access;
31 
32 struct X
33 {
34     X() = default;
35     X(const X&) = delete;
testX36     constexpr int test() const & {return 3;}
testX37     int test() & {return 4;}
testX38     constexpr int test() const && {return 5;}
testX39     int test() && {return 6;}
40 };
41 
42 struct Y
43 {
testY44     constexpr int test() && {return 7;}
45 };
46 
47 constexpr int
test()48 test()
49 {
50     optional<Y> opt{Y{}};
51     return std::move(opt).value().test();
52 }
53 
main()54 int main()
55 {
56     {
57         optional<X> opt; ((void)opt);
58         ASSERT_NOT_NOEXCEPT(std::move(opt).value());
59         ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X&&);
60     }
61     {
62         optional<X> opt;
63         opt.emplace();
64         assert(std::move(opt).value().test() == 6);
65     }
66 #ifndef TEST_HAS_NO_EXCEPTIONS
67     {
68         optional<X> opt;
69         try
70         {
71             (void)std::move(opt).value();
72             assert(false);
73         }
74         catch (const bad_optional_access&)
75         {
76         }
77     }
78 #endif
79     static_assert(test() == 7, "");
80 }
81