1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
11 // template<class... Args>
12 // constexpr explicit expected(unexpect_t, Args&&... args);
14 // Constraints: is_constructible_v<E, Args...> is true.
16 // Effects: Direct-non-list-initializes unex with std::forward<Args>(args)....
18 // Postconditions: has_value() is false.
20 // Throws: Any exception thrown by the initialization of unex.
25 #include <type_traits>
29 #include "test_macros.h"
30 #include "../../types.h"
33 static_assert(std::is_constructible_v
<std::expected
<void, int>, std::unexpect_t
>);
34 static_assert(std::is_constructible_v
<std::expected
<void, int>, std::unexpect_t
, int>);
36 // !is_constructible_v<T, Args...>
38 static_assert(!std::is_constructible_v
<std::expected
<void, foo
>, std::unexpect_t
, int>);
42 void conversion_test(T
);
44 template <class T
, class... Args
>
45 concept ImplicitlyConstructible
= requires(Args
&&... args
) { conversion_test
<T
>({std::forward
<Args
>(args
)...}); };
46 static_assert(ImplicitlyConstructible
<int, int>);
48 static_assert(!ImplicitlyConstructible
<std::expected
<void, int>, std::unexpect_t
>);
49 static_assert(!ImplicitlyConstructible
<std::expected
<void, int>, std::unexpect_t
, int>);
53 constexpr CopyOnly(int ii
) : i(ii
) {}
54 CopyOnly(const CopyOnly
&) = default;
55 CopyOnly(CopyOnly
&&) = delete;
56 friend constexpr bool operator==(const CopyOnly
& mi
, int ii
) { return mi
.i
== ii
; }
60 constexpr void testInt() {
61 std::expected
<void, T
> e(std::unexpect
, 5);
62 assert(!e
.has_value());
63 assert(e
.error() == 5);
67 constexpr void testLValue() {
69 std::expected
<void, T
> e(std::unexpect
, t
);
70 assert(!e
.has_value());
71 assert(e
.error() == 5);
75 constexpr void testRValue() {
76 std::expected
<void, T
> e(std::unexpect
, T(5));
77 assert(!e
.has_value());
78 assert(e
.error() == 5);
81 constexpr bool test() {
85 testInt
<TailClobberer
<1>>();
87 testLValue
<CopyOnly
>();
88 testLValue
<TailClobberer
<1>>();
90 testRValue
<MoveOnly
>();
91 testRValue
<TailClobberer
<1>>();
95 std::expected
<void, int> e(std::unexpect
);
96 assert(!e
.has_value());
97 assert(e
.error() == 0);
102 std::expected
<void, int> e(std::unexpect
, 5);
103 assert(!e
.has_value());
104 assert(e
.error() == 5);
109 std::expected
<void, std::tuple
<int, short, MoveOnly
>> e(std::unexpect
, 1, short{2}, MoveOnly(3));
110 assert(!e
.has_value());
111 assert((e
.error() == std::tuple
<int, short, MoveOnly
>(1, short{2}, MoveOnly(3))));
117 void testException() {
118 #ifndef TEST_HAS_NO_EXCEPTIONS
120 Throwing(int) { throw Except
{}; };
124 std::expected
<void, Throwing
> u(std::unexpect
, 5);
128 #endif // TEST_HAS_NO_EXCEPTIONS
131 int main(int, char**) {
133 static_assert(test());