xref: /freebsd-src/contrib/llvm-project/libcxx/include/__expected/unexpected.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1bdd1243dSDimitry Andric // -*- C++ -*-
2bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
3bdd1243dSDimitry Andric //
4bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7bdd1243dSDimitry Andric //
8bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
9bdd1243dSDimitry Andric #ifndef _LIBCPP___EXPECTED_UNEXPECTED_H
10bdd1243dSDimitry Andric #define _LIBCPP___EXPECTED_UNEXPECTED_H
11bdd1243dSDimitry Andric 
12bdd1243dSDimitry Andric #include <__config>
13bdd1243dSDimitry Andric #include <__type_traits/conjunction.h>
14bdd1243dSDimitry Andric #include <__type_traits/is_array.h>
15bdd1243dSDimitry Andric #include <__type_traits/is_const.h>
16bdd1243dSDimitry Andric #include <__type_traits/is_constructible.h>
17bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_constructible.h>
18bdd1243dSDimitry Andric #include <__type_traits/is_object.h>
19bdd1243dSDimitry Andric #include <__type_traits/is_same.h>
20bdd1243dSDimitry Andric #include <__type_traits/is_swappable.h>
21bdd1243dSDimitry Andric #include <__type_traits/is_volatile.h>
22bdd1243dSDimitry Andric #include <__type_traits/negation.h>
23bdd1243dSDimitry Andric #include <__type_traits/remove_cvref.h>
24bdd1243dSDimitry Andric #include <__utility/forward.h>
25bdd1243dSDimitry Andric #include <__utility/in_place.h>
26bdd1243dSDimitry Andric #include <__utility/move.h>
27bdd1243dSDimitry Andric #include <__utility/swap.h>
28bdd1243dSDimitry Andric #include <initializer_list>
29bdd1243dSDimitry Andric 
30bdd1243dSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
31bdd1243dSDimitry Andric #  pragma GCC system_header
32bdd1243dSDimitry Andric #endif
33bdd1243dSDimitry Andric 
34*06c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS
35*06c3fb27SDimitry Andric #include <__undef_macros>
36*06c3fb27SDimitry Andric 
37bdd1243dSDimitry Andric #if _LIBCPP_STD_VER >= 23
38bdd1243dSDimitry Andric 
39bdd1243dSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
40bdd1243dSDimitry Andric 
41bdd1243dSDimitry Andric template <class _Err>
42bdd1243dSDimitry Andric class unexpected;
43bdd1243dSDimitry Andric 
44bdd1243dSDimitry Andric template <class _Tp>
45bdd1243dSDimitry Andric struct __is_std_unexpected : false_type {};
46bdd1243dSDimitry Andric 
47bdd1243dSDimitry Andric template <class _Err>
48bdd1243dSDimitry Andric struct __is_std_unexpected<unexpected<_Err>> : true_type {};
49bdd1243dSDimitry Andric 
50bdd1243dSDimitry Andric template <class _Tp>
51bdd1243dSDimitry Andric using __valid_std_unexpected = _BoolConstant< //
52bdd1243dSDimitry Andric     is_object_v<_Tp> &&                       //
53bdd1243dSDimitry Andric     !is_array_v<_Tp> &&                       //
54bdd1243dSDimitry Andric     !__is_std_unexpected<_Tp>::value &&       //
55bdd1243dSDimitry Andric     !is_const_v<_Tp> &&                       //
56bdd1243dSDimitry Andric     !is_volatile_v<_Tp>                       //
57bdd1243dSDimitry Andric     >;
58bdd1243dSDimitry Andric 
59bdd1243dSDimitry Andric template <class _Err>
60bdd1243dSDimitry Andric class unexpected {
61bdd1243dSDimitry Andric   static_assert(__valid_std_unexpected<_Err>::value,
62bdd1243dSDimitry Andric                 "[expected.un.general] states a program that instantiates std::unexpected for a non-object type, an "
63bdd1243dSDimitry Andric                 "array type, a specialization of unexpected, or a cv-qualified type is ill-formed.");
64bdd1243dSDimitry Andric 
65bdd1243dSDimitry Andric public:
66bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr unexpected(const unexpected&) = default;
67bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr unexpected(unexpected&&)      = default;
68bdd1243dSDimitry Andric 
69bdd1243dSDimitry Andric   template <class _Error = _Err>
70bdd1243dSDimitry Andric     requires(!is_same_v<remove_cvref_t<_Error>, unexpected> && //
71bdd1243dSDimitry Andric              !is_same_v<remove_cvref_t<_Error>, in_place_t> && //
72bdd1243dSDimitry Andric              is_constructible_v<_Err, _Error>)
73bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(_Error&& __error) //
74bdd1243dSDimitry Andric       noexcept(is_nothrow_constructible_v<_Err, _Error>)                // strengthened
75bdd1243dSDimitry Andric       : __unex_(std::forward<_Error>(__error)) {}
76bdd1243dSDimitry Andric 
77bdd1243dSDimitry Andric   template <class... _Args>
78bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _Args...>
79bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(in_place_t, _Args&&... __args) //
80bdd1243dSDimitry Andric       noexcept(is_nothrow_constructible_v<_Err, _Args...>)                           // strengthened
81bdd1243dSDimitry Andric       : __unex_(std::forward<_Args>(__args)...) {}
82bdd1243dSDimitry Andric 
83bdd1243dSDimitry Andric   template <class _Up, class... _Args>
84bdd1243dSDimitry Andric     requires is_constructible_v<_Err, initializer_list<_Up>&, _Args...>
85bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) //
86bdd1243dSDimitry Andric       noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
87bdd1243dSDimitry Andric       : __unex_(__il, std::forward<_Args>(__args)...) {}
88bdd1243dSDimitry Andric 
89bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(const unexpected&) = default;
90bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(unexpected&&)      = default;
91bdd1243dSDimitry Andric 
92bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { return __unex_; }
93bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { return __unex_; }
94bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { return std::move(__unex_); }
95bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { return std::move(__unex_); }
96bdd1243dSDimitry Andric 
97bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Err>) {
98bdd1243dSDimitry Andric     static_assert(is_swappable_v<_Err>, "unexpected::swap requires is_swappable_v<E> to be true");
99bdd1243dSDimitry Andric     using std::swap;
100bdd1243dSDimitry Andric     swap(__unex_, __other.__unex_);
101bdd1243dSDimitry Andric   }
102bdd1243dSDimitry Andric 
103bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y)))
104bdd1243dSDimitry Andric     requires is_swappable_v<_Err>
105bdd1243dSDimitry Andric   {
106bdd1243dSDimitry Andric     __x.swap(__y);
107bdd1243dSDimitry Andric   }
108bdd1243dSDimitry Andric 
109bdd1243dSDimitry Andric   template <class _Err2>
110bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const unexpected& __x, const unexpected<_Err2>& __y) {
111bdd1243dSDimitry Andric     return __x.__unex_ == __y.__unex_;
112bdd1243dSDimitry Andric   }
113bdd1243dSDimitry Andric 
114bdd1243dSDimitry Andric private:
115bdd1243dSDimitry Andric   _Err __unex_;
116bdd1243dSDimitry Andric };
117bdd1243dSDimitry Andric 
118bdd1243dSDimitry Andric template <class _Err>
119bdd1243dSDimitry Andric unexpected(_Err) -> unexpected<_Err>;
120bdd1243dSDimitry Andric 
121bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
122bdd1243dSDimitry Andric 
123bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER >= 23
124bdd1243dSDimitry Andric 
125*06c3fb27SDimitry Andric _LIBCPP_POP_MACROS
126*06c3fb27SDimitry Andric 
127bdd1243dSDimitry Andric #endif // _LIBCPP___EXPECTED_UNEXPECTED_H
128