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 // constexpr const T* optional<T>::operator->() const;
14 
15 #ifdef _LIBCPP_DEBUG
16 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
17 #endif
18 
19 #include <optional>
20 #include <type_traits>
21 #include <cassert>
22 
23 #include "test_macros.h"
24 
25 using std::optional;
26 
27 struct X
28 {
testX29     constexpr int test() const {return 3;}
30 };
31 
32 struct Y
33 {
testY34     int test() const noexcept {return 2;}
35 };
36 
37 struct Z
38 {
39     const Z* operator&() const;
testZ40     constexpr int test() const {return 1;}
41 };
42 
main()43 int main()
44 {
45     {
46         const std::optional<X> opt; ((void)opt);
47         ASSERT_SAME_TYPE(decltype(opt.operator->()), X const*);
48         // ASSERT_NOT_NOEXCEPT(opt.operator->());
49         // FIXME: This assertion fails with GCC because it can see that
50         // (A) operator->() is constexpr, and
51         // (B) there is no path through the function that throws.
52         // It's arguable if this is the correct behavior for the noexcept
53         // operator.
54         // Regardless this function should still be noexcept(false) because
55         // it has a narrow contract.
56     }
57     {
58         constexpr optional<X> opt(X{});
59         static_assert(opt->test() == 3, "");
60     }
61     {
62         constexpr optional<Y> opt(Y{});
63         assert(opt->test() == 2);
64     }
65     {
66         constexpr optional<Z> opt(Z{});
67         static_assert(opt->test() == 1, "");
68     }
69 #ifdef _LIBCPP_DEBUG
70     {
71         const optional<X> opt;
72         assert(opt->test() == 3);
73         assert(false);
74     }
75 #endif  // _LIBCPP_DEBUG
76 }
77