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