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 10 #ifndef _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H 11 #define _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H 12 13 #include <__config> 14 #include <__functional/binary_function.h> 15 #include <__functional/invoke.h> 16 #include <__functional/unary_function.h> 17 #include <__type_traits/integral_constant.h> 18 #include <__type_traits/is_same.h> 19 #include <__utility/declval.h> 20 21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 22 # pragma GCC system_header 23 #endif 24 25 _LIBCPP_BEGIN_NAMESPACE_STD 26 27 template <class _Tp> 28 struct __has_result_type { 29 private: 30 template <class _Up> 31 static false_type __test(...); 32 template <class _Up> 33 static true_type __test(typename _Up::result_type* = 0); 34 35 public: 36 static const bool value = decltype(__test<_Tp>(0))::value; 37 }; 38 39 // __weak_result_type 40 41 template <class _Tp> 42 struct __derives_from_unary_function { 43 private: 44 struct __two { 45 char __lx; 46 char __lxx; 47 }; 48 static __two __test(...); 49 template <class _Ap, class _Rp> 50 static __unary_function<_Ap, _Rp> __test(const volatile __unary_function<_Ap, _Rp>*); 51 52 public: 53 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; 54 typedef decltype(__test((_Tp*)0)) type; 55 }; 56 57 template <class _Tp> 58 struct __derives_from_binary_function { 59 private: 60 struct __two { 61 char __lx; 62 char __lxx; 63 }; 64 static __two __test(...); 65 template <class _A1, class _A2, class _Rp> 66 static __binary_function<_A1, _A2, _Rp> __test(const volatile __binary_function<_A1, _A2, _Rp>*); 67 68 public: 69 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; 70 typedef decltype(__test((_Tp*)0)) type; 71 }; 72 73 template <class _Tp, bool = __derives_from_unary_function<_Tp>::value> 74 struct __maybe_derive_from_unary_function // bool is true 75 : public __derives_from_unary_function<_Tp>::type {}; 76 77 template <class _Tp> 78 struct __maybe_derive_from_unary_function<_Tp, false> {}; 79 80 template <class _Tp, bool = __derives_from_binary_function<_Tp>::value> 81 struct __maybe_derive_from_binary_function // bool is true 82 : public __derives_from_binary_function<_Tp>::type {}; 83 84 template <class _Tp> 85 struct __maybe_derive_from_binary_function<_Tp, false> {}; 86 87 template <class _Tp, bool = __has_result_type<_Tp>::value> 88 struct __weak_result_type_imp // bool is true 89 : public __maybe_derive_from_unary_function<_Tp>, 90 public __maybe_derive_from_binary_function<_Tp> { 91 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 92 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type; 93 #endif 94 }; 95 96 template <class _Tp> 97 struct __weak_result_type_imp<_Tp, false> 98 : public __maybe_derive_from_unary_function<_Tp>, public __maybe_derive_from_binary_function<_Tp> {}; 99 100 template <class _Tp> 101 struct __weak_result_type : public __weak_result_type_imp<_Tp> {}; 102 103 // 0 argument case 104 105 template <class _Rp> 106 struct __weak_result_type<_Rp()> { 107 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 108 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 109 #endif 110 }; 111 112 template <class _Rp> 113 struct __weak_result_type<_Rp (&)()> { 114 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 115 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 116 #endif 117 }; 118 119 template <class _Rp> 120 struct __weak_result_type<_Rp (*)()> { 121 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 122 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 123 #endif 124 }; 125 126 // 1 argument case 127 128 template <class _Rp, class _A1> 129 struct __weak_result_type<_Rp(_A1)> : public __unary_function<_A1, _Rp> {}; 130 131 template <class _Rp, class _A1> 132 struct __weak_result_type<_Rp (&)(_A1)> : public __unary_function<_A1, _Rp> {}; 133 134 template <class _Rp, class _A1> 135 struct __weak_result_type<_Rp (*)(_A1)> : public __unary_function<_A1, _Rp> {}; 136 137 template <class _Rp, class _Cp> 138 struct __weak_result_type<_Rp (_Cp::*)()> : public __unary_function<_Cp*, _Rp> {}; 139 140 template <class _Rp, class _Cp> 141 struct __weak_result_type<_Rp (_Cp::*)() const> : public __unary_function<const _Cp*, _Rp> {}; 142 143 template <class _Rp, class _Cp> 144 struct __weak_result_type<_Rp (_Cp::*)() volatile> : public __unary_function<volatile _Cp*, _Rp> {}; 145 146 template <class _Rp, class _Cp> 147 struct __weak_result_type<_Rp (_Cp::*)() const volatile> : public __unary_function<const volatile _Cp*, _Rp> {}; 148 149 // 2 argument case 150 151 template <class _Rp, class _A1, class _A2> 152 struct __weak_result_type<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; 153 154 template <class _Rp, class _A1, class _A2> 155 struct __weak_result_type<_Rp (*)(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; 156 157 template <class _Rp, class _A1, class _A2> 158 struct __weak_result_type<_Rp (&)(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; 159 160 template <class _Rp, class _Cp, class _A1> 161 struct __weak_result_type<_Rp (_Cp::*)(_A1)> : public __binary_function<_Cp*, _A1, _Rp> {}; 162 163 template <class _Rp, class _Cp, class _A1> 164 struct __weak_result_type<_Rp (_Cp::*)(_A1) const> : public __binary_function<const _Cp*, _A1, _Rp> {}; 165 166 template <class _Rp, class _Cp, class _A1> 167 struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> : public __binary_function<volatile _Cp*, _A1, _Rp> {}; 168 169 template <class _Rp, class _Cp, class _A1> 170 struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> : public __binary_function<const volatile _Cp*, _A1, _Rp> { 171 }; 172 173 // 3 or more arguments 174 175 template <class _Rp, class _A1, class _A2, class _A3, class... _A4> 176 struct __weak_result_type<_Rp(_A1, _A2, _A3, _A4...)> { 177 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 178 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 179 #endif 180 }; 181 182 template <class _Rp, class _A1, class _A2, class _A3, class... _A4> 183 struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> { 184 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 185 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 186 #endif 187 }; 188 189 template <class _Rp, class _A1, class _A2, class _A3, class... _A4> 190 struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> { 191 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 192 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 193 #endif 194 }; 195 196 template <class _Rp, class _Cp, class _A1, class _A2, class... _A3> 197 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> { 198 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 199 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 200 #endif 201 }; 202 203 template <class _Rp, class _Cp, class _A1, class _A2, class... _A3> 204 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> { 205 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 206 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 207 #endif 208 }; 209 210 template <class _Rp, class _Cp, class _A1, class _A2, class... _A3> 211 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> { 212 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 213 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 214 #endif 215 }; 216 217 template <class _Rp, class _Cp, class _A1, class _A2, class... _A3> 218 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> { 219 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 220 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 221 #endif 222 }; 223 224 template <class _Tp, class... _Args> 225 struct __invoke_return { 226 typedef decltype(std::__invoke(std::declval<_Tp>(), std::declval<_Args>()...)) type; 227 }; 228 229 _LIBCPP_END_NAMESPACE_STD 230 231 #endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H 232