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

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