1//===----------------------------------------------------------------------===//
2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3// See https://llvm.org/LICENSE.txt for license information.
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6//===----------------------------------------------------------------------===//
7
8// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
9
10// template<class G>
11// constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
12//
13// Let GF be const G&
14//
15// Constraints: is_constructible_v<E, GF> is true.
16//
17// Effects: Direct-non-list-initializes unex with std::forward<GF>(e.error()).
18//
19// Postconditions: has_value() is false.
20//
21// Throws: Any exception thrown by the initialization of unex.
22
23#include <cassert>
24#include <expected>
25#include <type_traits>
26#include <utility>
27
28#include "MoveOnly.h"
29#include "test_macros.h"
30#include "../../types.h"
31
32// Test Constraints
33static_assert(std::is_constructible_v<std::expected<void, int>, const std::unexpected<int>&>);
34
35// !is_constructible_v<E, GF>
36struct foo {};
37static_assert(!std::is_constructible_v<std::expected<void, int>, const std::unexpected<foo>&>);
38static_assert(!std::is_constructible_v<std::expected<void, MoveOnly>, const std::unexpected<MoveOnly>&>);
39
40// explicit(!is_convertible_v<const G&, E>)
41struct NotConvertible {
42 explicit NotConvertible(int);
43};
44static_assert(std::is_convertible_v<const std::unexpected<int>&, std::expected<void, int>>);
45static_assert(!std::is_convertible_v<const std::unexpected<int>&, std::expected<void, NotConvertible>>);
46
47struct MyInt {
48 int i;
49 constexpr MyInt(int ii) : i(ii) {}
50 friend constexpr bool operator==(const MyInt&, const MyInt&) = default;
51};
52
53template <class T>
54constexpr void testUnexpected() {
55 const std::unexpected<int> u(5);
56 std::expected<void, T> e(u);
57 assert(!e.has_value());
58 assert(e.error() == 5);
59}
60
61constexpr bool test() {
62 testUnexpected<int>();
63 testUnexpected<MyInt>();
64 testUnexpected<TailClobberer<1>>();
65 return true;
66}
67
68void testException() {
69#ifndef TEST_HAS_NO_EXCEPTIONS
70 struct Throwing {
71 Throwing(int) { throw Except{}; }
72 };
73
74 {
75 const std::unexpected<int> u(5);
76 try {
77 [[maybe_unused]] std::expected<void, Throwing> e(u);
78 assert(false);
79 } catch (Except) {
80 }
81 }
82
83#endif // TEST_HAS_NO_EXCEPTIONS
84}
85
86int main(int, char**) {
87 test();
88 static_assert(test());
89 testException();
90 return 0;
91}
92

source code of libcxx/test/std/utilities/expected/expected.void/ctor/ctor.unexpected.copy.pass.cpp