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, c++17, c++20
10
11// constexpr const T& value() const &;
12// constexpr T& value() &;
13// constexpr T&& value() &&;
14// constexpr const T&& value() const &&;
15
16#include <cassert>
17#include <concepts>
18#include <expected>
19#include <type_traits>
20#include <utility>
21
22#include "test_macros.h"
23
24constexpr bool test() {
25 // non-const &
26 {
27 std::expected<int, int> e(5);
28 decltype(auto) x = e.value();
29 static_assert(std::same_as<decltype(x), int&>);
30 assert(&x == &(*e));
31 assert(x == 5);
32 }
33
34 // const &
35 {
36 const std::expected<int, int> e(5);
37 decltype(auto) x = e.value();
38 static_assert(std::same_as<decltype(x), const int&>);
39 assert(&x == &(*e));
40 assert(x == 5);
41 }
42
43 // non-const &&
44 {
45 std::expected<int, int> e(5);
46 decltype(auto) x = std::move(e).value();
47 static_assert(std::same_as<decltype(x), int&&>);
48 assert(&x == &(*e));
49 assert(x == 5);
50 }
51
52 // const &&
53 {
54 const std::expected<int, int> e(5);
55 decltype(auto) x = std::move(e).value();
56 static_assert(std::same_as<decltype(x), const int&&>);
57 assert(&x == &(*e));
58 assert(x == 5);
59 }
60
61 return true;
62}
63
64void testException() {
65#ifndef TEST_HAS_NO_EXCEPTIONS
66
67 // int
68 {
69 const std::expected<int, int> e(std::unexpect, 5);
70 try {
71 (void) e.value();
72 assert(false);
73 } catch (const std::bad_expected_access<int>& ex) {
74 assert(ex.error() == 5);
75 }
76 }
77
78#endif // TEST_HAS_NO_EXCEPTIONS
79}
80
81void testAsConst() {
82#ifndef TEST_HAS_NO_EXCEPTIONS
83 struct Error {
84 enum { Default, MutableRefCalled, ConstRefCalled } From = Default;
85 Error() = default;
86 Error(const Error&) { From = ConstRefCalled; }
87 Error(Error&) { From = MutableRefCalled; }
88 Error(Error&& e) { From = e.From; }
89 };
90
91 // Test & overload
92 {
93 std::expected<int, Error> e(std::unexpect, Error());
94 try {
95 (void)e.value();
96 assert(false);
97 } catch (const std::bad_expected_access<Error>& ex) {
98 assert(ex.error().From == Error::ConstRefCalled);
99 }
100 }
101
102 // There are no effects for `const &` overload.
103
104#endif // TEST_HAS_NO_EXCEPTIONS
105}
106
107int main(int, char**) {
108 test();
109 static_assert(test());
110 testException();
111 testAsConst();
112
113 return 0;
114}
115

source code of libcxx/test/std/utilities/expected/expected.expected/observers/value.pass.cpp