2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___CXX03___EXPECTED_UNEXPECTED_H
10 #define _LIBCPP___CXX03___EXPECTED_UNEXPECTED_H
12 #include <__cxx03/__config>
13 #include <__cxx03/__type_traits/conjunction.h>
14 #include <__cxx03/__type_traits/is_array.h>
15 #include <__cxx03/__type_traits/is_const.h>
16 #include <__cxx03/__type_traits/is_constructible.h>
17 #include <__cxx03/__type_traits/is_nothrow_constructible.h>
18 #include <__cxx03/__type_traits/is_object.h>
19 #include <__cxx03/__type_traits/is_same.h>
20 #include <__cxx03/__type_traits/is_swappable.h>
21 #include <__cxx03/__type_traits/is_volatile.h>
22 #include <__cxx03/__type_traits/negation.h>
23 #include <__cxx03/__type_traits/remove_cvref.h>
24 #include <__cxx03/__utility/forward.h>
25 #include <__cxx03/__utility/in_place.h>
26 #include <__cxx03/__utility/move.h>
27 #include <__cxx03/__utility/swap.h>
28 #include <__cxx03/initializer_list>
30 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
31 # pragma GCC system_header
35 #include <__cxx03/__undef_macros>
37 #if _LIBCPP_STD_VER >= 23
39 _LIBCPP_BEGIN_NAMESPACE_STD
45 struct __is_std_unexpected
: false_type
{};
48 struct __is_std_unexpected
<unexpected
<_Err
>> : true_type
{};
51 using __valid_std_unexpected
= _BoolConstant
< //
52 is_object_v
<_Tp
> && //
53 !is_array_v
<_Tp
> && //
54 !__is_std_unexpected
<_Tp
>::value
&& //
55 !is_const_v
<_Tp
> && //
56 !is_volatile_v
<_Tp
> //
61 static_assert(__valid_std_unexpected
<_Err
>::value
,
62 "[expected.un.general] states a program that instantiates std::unexpected for a non-object type, an "
63 "array type, a specialization of unexpected, or a cv-qualified type is ill-formed.");
66 _LIBCPP_HIDE_FROM_ABI
constexpr unexpected(const unexpected
&) = default;
67 _LIBCPP_HIDE_FROM_ABI
constexpr unexpected(unexpected
&&) = default;
69 template <class _Error
= _Err
>
70 requires(!is_same_v
<remove_cvref_t
<_Error
>, unexpected
> && //
71 !is_same_v
<remove_cvref_t
<_Error
>, in_place_t
> && //
72 is_constructible_v
<_Err
, _Error
>)
73 _LIBCPP_HIDE_FROM_ABI
constexpr explicit unexpected(_Error
&& __error
) //
74 noexcept(is_nothrow_constructible_v
<_Err
, _Error
>) // strengthened
75 : __unex_(std::forward
<_Error
>(__error
)) {}
77 template <class... _Args
>
78 requires is_constructible_v
<_Err
, _Args
...>
79 _LIBCPP_HIDE_FROM_ABI
constexpr explicit unexpected(in_place_t
, _Args
&&... __args
) //
80 noexcept(is_nothrow_constructible_v
<_Err
, _Args
...>) // strengthened
81 : __unex_(std::forward
<_Args
>(__args
)...) {}
83 template <class _Up
, class... _Args
>
84 requires is_constructible_v
<_Err
, initializer_list
<_Up
>&, _Args
...>
85 _LIBCPP_HIDE_FROM_ABI
constexpr explicit unexpected(in_place_t
, initializer_list
<_Up
> __il
, _Args
&&... __args
) //
86 noexcept(is_nothrow_constructible_v
<_Err
, initializer_list
<_Up
>&, _Args
...>) // strengthened
87 : __unex_(__il
, std::forward
<_Args
>(__args
)...) {}
89 _LIBCPP_HIDE_FROM_ABI
constexpr unexpected
& operator=(const unexpected
&) = default;
90 _LIBCPP_HIDE_FROM_ABI
constexpr unexpected
& operator=(unexpected
&&) = default;
92 _LIBCPP_HIDE_FROM_ABI
constexpr const _Err
& error() const& noexcept
{ return __unex_
; }
93 _LIBCPP_HIDE_FROM_ABI
constexpr _Err
& error() & noexcept
{ return __unex_
; }
94 _LIBCPP_HIDE_FROM_ABI
constexpr const _Err
&& error() const&& noexcept
{ return std::move(__unex_
); }
95 _LIBCPP_HIDE_FROM_ABI
constexpr _Err
&& error() && noexcept
{ return std::move(__unex_
); }
97 _LIBCPP_HIDE_FROM_ABI
constexpr void swap(unexpected
& __other
) noexcept(is_nothrow_swappable_v
<_Err
>) {
98 static_assert(is_swappable_v
<_Err
>, "unexpected::swap requires is_swappable_v<E> to be true");
100 swap(__unex_
, __other
.__unex_
);
103 _LIBCPP_HIDE_FROM_ABI
friend constexpr void swap(unexpected
& __x
, unexpected
& __y
) noexcept(noexcept(__x
.swap(__y
)))
104 requires is_swappable_v
<_Err
>
109 template <class _Err2
>
110 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const unexpected
& __x
, const unexpected
<_Err2
>& __y
) {
111 return __x
.__unex_
== __y
.__unex_
;
118 template <class _Err
>
119 unexpected(_Err
) -> unexpected
<_Err
>;
121 _LIBCPP_END_NAMESPACE_STD
123 #endif // _LIBCPP_STD_VER >= 23
127 #endif // _LIBCPP___CXX03___EXPECTED_UNEXPECTED_H