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<G, E>) expected(unexpected<G>&& e);
12//
13// Let GF be 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<int, int>, std::unexpected<int>>);
34static_assert(std::is_constructible_v<std::expected<int, MoveOnly>, std::unexpected<MoveOnly>>);
35
36// !is_constructible_v<E, GF>
37struct foo {};
38static_assert(!std::is_constructible_v<std::expected<int, int>, std::unexpected<foo>>);
39
40// explicit(!is_convertible_v<G, E>)
41struct NotConvertible {
42 explicit NotConvertible(int);
43};
44static_assert(std::is_convertible_v<std::unexpected<int>&&, std::expected<int, int>>);
45static_assert(!std::is_convertible_v<std::unexpected<int>&&, std::expected<int, 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 Err, class V = int>
54constexpr void testInt() {
55 std::unexpected<int> u(5);
56 std::expected<V, Err> e(std::move(u));
57 assert(!e.has_value());
58 assert(e.error() == 5);
59}
60
61constexpr void testMoveOnly() {
62 std::unexpected<MoveOnly> u(MoveOnly(5));
63 std::expected<int, MoveOnly> e(std::move(u));
64 assert(!e.has_value());
65 assert(e.error() == 5);
66 assert(u.error() == 0);
67}
68
69constexpr bool test() {
70 testInt<int>();
71 testInt<MyInt>();
72 testInt<MoveOnly>();
73 testInt<TailClobberer<1>, bool>();
74 testMoveOnly();
75 return true;
76}
77
78void testException() {
79#ifndef TEST_HAS_NO_EXCEPTIONS
80 struct Throwing {
81 Throwing(int) { throw Except{}; }
82 };
83
84 {
85 std::unexpected<int> u(5);
86 try {
87 [[maybe_unused]] std::expected<int, Throwing> e(std::move(u));
88 assert(false);
89 } catch (Except) {
90 }
91 }
92
93#endif // TEST_HAS_NO_EXCEPTIONS
94}
95
96int main(int, char**) {
97 test();
98 static_assert(test());
99 testException();
100 return 0;
101}
102

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