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 27template <class _Tp> 28struct __has_result_type 29{ 30private: 31 template <class _Up> static false_type __test(...); 32 template <class _Up> static true_type __test(typename _Up::result_type* = 0); 33public: 34 static const bool value = decltype(__test<_Tp>(0))::value; 35}; 36 37// __weak_result_type 38 39template <class _Tp> 40struct __derives_from_unary_function 41{ 42private: 43 struct __two {char __lx; char __lxx;}; 44 static __two __test(...); 45 template <class _Ap, class _Rp> 46 static __unary_function<_Ap, _Rp> 47 __test(const volatile __unary_function<_Ap, _Rp>*); 48 49public: 50 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; 51 typedef decltype(__test((_Tp*)0)) type; 52}; 53 54template <class _Tp> 55struct __derives_from_binary_function 56{ 57private: 58 struct __two {char __lx; char __lxx;}; 59 static __two __test(...); 60 template <class _A1, class _A2, class _Rp> 61 static __binary_function<_A1, _A2, _Rp> 62 __test(const volatile __binary_function<_A1, _A2, _Rp>*); 63 64public: 65 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; 66 typedef decltype(__test((_Tp*)0)) type; 67}; 68 69template <class _Tp, bool = __derives_from_unary_function<_Tp>::value> 70struct __maybe_derive_from_unary_function // bool is true 71 : public __derives_from_unary_function<_Tp>::type 72{ 73}; 74 75template <class _Tp> 76struct __maybe_derive_from_unary_function<_Tp, false> 77{ 78}; 79 80template <class _Tp, bool = __derives_from_binary_function<_Tp>::value> 81struct __maybe_derive_from_binary_function // bool is true 82 : public __derives_from_binary_function<_Tp>::type 83{ 84}; 85 86template <class _Tp> 87struct __maybe_derive_from_binary_function<_Tp, false> 88{ 89}; 90 91template <class _Tp, bool = __has_result_type<_Tp>::value> 92struct __weak_result_type_imp // bool is true 93 : public __maybe_derive_from_unary_function<_Tp>, 94 public __maybe_derive_from_binary_function<_Tp> 95{ 96#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 97 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type; 98#endif 99}; 100 101template <class _Tp> 102struct __weak_result_type_imp<_Tp, false> 103 : public __maybe_derive_from_unary_function<_Tp>, 104 public __maybe_derive_from_binary_function<_Tp> 105{ 106}; 107 108template <class _Tp> 109struct __weak_result_type 110 : public __weak_result_type_imp<_Tp> 111{ 112}; 113 114// 0 argument case 115 116template <class _Rp> 117struct __weak_result_type<_Rp ()> 118{ 119#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 120 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 121#endif 122}; 123 124template <class _Rp> 125struct __weak_result_type<_Rp (&)()> 126{ 127#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 128 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 129#endif 130}; 131 132template <class _Rp> 133struct __weak_result_type<_Rp (*)()> 134{ 135#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 136 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 137#endif 138}; 139 140// 1 argument case 141 142template <class _Rp, class _A1> 143struct __weak_result_type<_Rp (_A1)> 144 : public __unary_function<_A1, _Rp> 145{ 146}; 147 148template <class _Rp, class _A1> 149struct __weak_result_type<_Rp (&)(_A1)> 150 : public __unary_function<_A1, _Rp> 151{ 152}; 153 154template <class _Rp, class _A1> 155struct __weak_result_type<_Rp (*)(_A1)> 156 : public __unary_function<_A1, _Rp> 157{ 158}; 159 160template <class _Rp, class _Cp> 161struct __weak_result_type<_Rp (_Cp::*)()> 162 : public __unary_function<_Cp*, _Rp> 163{ 164}; 165 166template <class _Rp, class _Cp> 167struct __weak_result_type<_Rp (_Cp::*)() const> 168 : public __unary_function<const _Cp*, _Rp> 169{ 170}; 171 172template <class _Rp, class _Cp> 173struct __weak_result_type<_Rp (_Cp::*)() volatile> 174 : public __unary_function<volatile _Cp*, _Rp> 175{ 176}; 177 178template <class _Rp, class _Cp> 179struct __weak_result_type<_Rp (_Cp::*)() const volatile> 180 : public __unary_function<const volatile _Cp*, _Rp> 181{ 182}; 183 184// 2 argument case 185 186template <class _Rp, class _A1, class _A2> 187struct __weak_result_type<_Rp (_A1, _A2)> 188 : public __binary_function<_A1, _A2, _Rp> 189{ 190}; 191 192template <class _Rp, class _A1, class _A2> 193struct __weak_result_type<_Rp (*)(_A1, _A2)> 194 : public __binary_function<_A1, _A2, _Rp> 195{ 196}; 197 198template <class _Rp, class _A1, class _A2> 199struct __weak_result_type<_Rp (&)(_A1, _A2)> 200 : public __binary_function<_A1, _A2, _Rp> 201{ 202}; 203 204template <class _Rp, class _Cp, class _A1> 205struct __weak_result_type<_Rp (_Cp::*)(_A1)> 206 : public __binary_function<_Cp*, _A1, _Rp> 207{ 208}; 209 210template <class _Rp, class _Cp, class _A1> 211struct __weak_result_type<_Rp (_Cp::*)(_A1) const> 212 : public __binary_function<const _Cp*, _A1, _Rp> 213{ 214}; 215 216template <class _Rp, class _Cp, class _A1> 217struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> 218 : public __binary_function<volatile _Cp*, _A1, _Rp> 219{ 220}; 221 222template <class _Rp, class _Cp, class _A1> 223struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> 224 : public __binary_function<const volatile _Cp*, _A1, _Rp> 225{ 226}; 227 228// 3 or more arguments 229 230template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> 231struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> 232{ 233#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 234 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 235#endif 236}; 237 238template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> 239struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> 240{ 241#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 242 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 243#endif 244}; 245 246template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> 247struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> 248{ 249#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 250 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 251#endif 252}; 253 254template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 255struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> 256{ 257#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 258 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 259#endif 260}; 261 262template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 263struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> 264{ 265#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 266 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 267#endif 268}; 269 270template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 271struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> 272{ 273#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 274 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 275#endif 276}; 277 278template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 279struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> 280{ 281#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 282 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 283#endif 284}; 285 286template <class _Tp, class ..._Args> 287struct __invoke_return 288{ 289 typedef decltype(_VSTD::__invoke(std::declval<_Tp>(), std::declval<_Args>()...)) type; 290}; 291 292_LIBCPP_END_NAMESPACE_STD 293 294#endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H 295