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 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 81 template <class _Tp, bool = __derives_from_binary_function<_Tp>::value> 82 struct __maybe_derive_from_binary_function // bool is true 83 : public __derives_from_binary_function<_Tp>::type {}; 84 85 template <class _Tp> 86 struct __maybe_derive_from_binary_function<_Tp, false> {}; 87 88 template <class _Tp, bool = __has_result_type<_Tp>::value> 89 struct __weak_result_type_imp // bool is true 90 : public __maybe_derive_from_unary_function<_Tp>, 91 public __maybe_derive_from_binary_function<_Tp> { 92 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 93 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type; 94 #endif 95 }; 96 97 template <class _Tp> 98 struct __weak_result_type_imp<_Tp, false> 99 : public __maybe_derive_from_unary_function<_Tp>, public __maybe_derive_from_binary_function<_Tp> {}; 100 101 template <class _Tp> 102 struct __weak_result_type : public __weak_result_type_imp<_Tp> {}; 103 _LIBCPP_SUPPRESS_DEPRECATED_POP 104 105 // 0 argument case 106 107 template <class _Rp> 108 struct __weak_result_type<_Rp()> { 109 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 110 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 111 #endif 112 }; 113 114 template <class _Rp> 115 struct __weak_result_type<_Rp (&)()> { 116 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 117 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 118 #endif 119 }; 120 121 template <class _Rp> 122 struct __weak_result_type<_Rp (*)()> { 123 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 124 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 125 #endif 126 }; 127 128 // 1 argument case 129 130 template <class _Rp, class _A1> 131 struct __weak_result_type<_Rp(_A1)> : public __unary_function<_A1, _Rp> {}; 132 133 template <class _Rp, class _A1> 134 struct __weak_result_type<_Rp (&)(_A1)> : public __unary_function<_A1, _Rp> {}; 135 136 template <class _Rp, class _A1> 137 struct __weak_result_type<_Rp (*)(_A1)> : public __unary_function<_A1, _Rp> {}; 138 139 template <class _Rp, class _Cp> 140 struct __weak_result_type<_Rp (_Cp::*)()> : public __unary_function<_Cp*, _Rp> {}; 141 142 template <class _Rp, class _Cp> 143 struct __weak_result_type<_Rp (_Cp::*)() const> : public __unary_function<const _Cp*, _Rp> {}; 144 145 template <class _Rp, class _Cp> 146 struct __weak_result_type<_Rp (_Cp::*)() volatile> : public __unary_function<volatile _Cp*, _Rp> {}; 147 148 template <class _Rp, class _Cp> 149 struct __weak_result_type<_Rp (_Cp::*)() const volatile> : public __unary_function<const volatile _Cp*, _Rp> {}; 150 151 // 2 argument case 152 153 template <class _Rp, class _A1, class _A2> 154 struct __weak_result_type<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; 155 156 template <class _Rp, class _A1, class _A2> 157 struct __weak_result_type<_Rp (*)(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; 158 159 template <class _Rp, class _A1, class _A2> 160 struct __weak_result_type<_Rp (&)(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; 161 162 template <class _Rp, class _Cp, class _A1> 163 struct __weak_result_type<_Rp (_Cp::*)(_A1)> : public __binary_function<_Cp*, _A1, _Rp> {}; 164 165 template <class _Rp, class _Cp, class _A1> 166 struct __weak_result_type<_Rp (_Cp::*)(_A1) const> : public __binary_function<const _Cp*, _A1, _Rp> {}; 167 168 template <class _Rp, class _Cp, class _A1> 169 struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> : public __binary_function<volatile _Cp*, _A1, _Rp> {}; 170 171 template <class _Rp, class _Cp, class _A1> 172 struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> : public __binary_function<const volatile _Cp*, _A1, _Rp> { 173 }; 174 175 // 3 or more arguments 176 177 template <class _Rp, class _A1, class _A2, class _A3, class... _A4> 178 struct __weak_result_type<_Rp(_A1, _A2, _A3, _A4...)> { 179 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 180 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 181 #endif 182 }; 183 184 template <class _Rp, class _A1, class _A2, class _A3, class... _A4> 185 struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> { 186 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 187 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 188 #endif 189 }; 190 191 template <class _Rp, class _A1, class _A2, class _A3, class... _A4> 192 struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> { 193 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 194 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 195 #endif 196 }; 197 198 template <class _Rp, class _Cp, class _A1, class _A2, class... _A3> 199 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> { 200 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 201 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 202 #endif 203 }; 204 205 template <class _Rp, class _Cp, class _A1, class _A2, class... _A3> 206 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> { 207 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 208 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 209 #endif 210 }; 211 212 template <class _Rp, class _Cp, class _A1, class _A2, class... _A3> 213 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> { 214 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 215 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 216 #endif 217 }; 218 219 template <class _Rp, class _Cp, class _A1, class _A2, class... _A3> 220 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> { 221 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 222 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 223 #endif 224 }; 225 226 template <class _Tp, class... _Args> 227 struct __invoke_return { 228 typedef decltype(std::__invoke(std::declval<_Tp>(), std::declval<_Args>()...)) type; 229 }; 230 231 _LIBCPP_END_NAMESPACE_STD 232 233 #endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H 234