xref: /llvm-project/libcxx/test/libcxx/utilities/expected/expected.void/error_or.mandates.verify.cpp (revision 9bb9ec380ace81d040d3a0a0a2ae9a75733ab330)
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 // Test the mandates
12 // template<class G = E> constexpr E error_or(G&&) const &;
13 // Mandates: is_copy_constructible_v<G> is true and is_convertible_v<U, E> is true.
14 
15 // template<class G = E> constexpr E error_or(G&&) &&;
16 // Mandates: is_move_constructible_v<G> is true and is_convertible_v<U, E> is true.
17 
18 #include <expected>
19 #include <utility>
20 
21 struct NonCopyable {
NonCopyableNonCopyable22   NonCopyable(int) {}
23   NonCopyable(const NonCopyable&) = delete;
24 };
25 
26 struct NonMovable {
NonMovableNonMovable27   NonMovable(int) {}
28   NonMovable(NonMovable&&) = delete;
29 };
30 
31 struct NotConvertibleFromInt {};
32 
33 // clang-format off
test()34 void test() {
35   // const & overload
36   // !is_copy_constructible_v<G>,
37   {
38     const std::expected<void, NonCopyable> f1(std::unexpect, 0);
39     f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NonCopyable>::error_or<int>' requested here}}
40     // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be copy constructible}}
41     // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
42   }
43 
44   // const & overload
45   // !is_convertible_v<U, T>
46   {
47     const std::expected<void, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{});
48     f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NotConvertibleFromInt>::error_or<int>' requested here}}
49     // expected-error-re@*:* {{static assertion failed {{.*}}argument has to be convertible to error_type}}
50     // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}}
51   }
52 
53   // && overload
54   // !is_move_constructible_v<T>,
55   {
56     std::expected<void, NonMovable> f1(std::unexpect, 0);
57     std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NonMovable>::error_or<int>' requested here}}
58     // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be move constructible}}
59     // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
60   }
61 
62   // && overload
63   // !is_convertible_v<U, T>
64   {
65     std::expected<void, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{});
66     std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NotConvertibleFromInt>::error_or<int>' requested here}}
67     // expected-error-re@*:* {{static assertion failed {{.*}}argument has to be convertible to error_type}}
68     // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}}
69   }
70 }
71 // clang-format on
72