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