summaryrefslogtreecommitdiff
path: root/libcxx/test/libcxx/utilities/expected/expected.void/error_or.mandates.verify.cpp
blob: a36665b25c876d06662c9aa82b7a9c3c97e2cc09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// Test the mandates
// template<class G = E> constexpr E error_or(G&&) const &;
// Mandates: is_copy_constructible_v<G> is true and is_convertible_v<U, E> is true.

// template<class G = E> constexpr E error_or(G&&) &&;
// Mandates: is_move_constructible_v<G> is true and is_convertible_v<U, E> is true.

#include <expected>
#include <utility>

struct NonCopyable {
  NonCopyable(int) {}
  NonCopyable(const NonCopyable&) = delete;
};

struct NonMovable {
  NonMovable(int) {}
  NonMovable(NonMovable&&) = delete;
};

struct NotConvertibleFromInt {};

// clang-format off
void test() {
  // const & overload
  // !is_copy_constructible_v<G>,
  {
    const std::expected<void, NonCopyable> f1(std::unexpect, 0);
    f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NonCopyable>::error_or<int>' requested here}}
    // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}error_type has to be copy constructible}}
    // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
  }

  // const & overload
  // !is_convertible_v<U, T>
  {
    const std::expected<void, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{});
    f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NotConvertibleFromInt>::error_or<int>' requested here}}
    // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}argument has to be convertible to error_type}}
    // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}}
  }

  // && overload
  // !is_move_constructible_v<T>,
  {
    std::expected<void, NonMovable> f1(std::unexpect, 0);
    std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NonMovable>::error_or<int>' requested here}}
    // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}error_type has to be move constructible}}
    // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
  }

  // && overload
  // !is_convertible_v<U, T>
  {
    std::expected<void, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{});
    std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NotConvertibleFromInt>::error_or<int>' requested here}}
    // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}argument has to be convertible to error_type}}
    // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}}
  }
}
// clang-format on