1fe6060f1SDimitry Andric // -*- C++ -*- 2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 3fe6060f1SDimitry Andric // 4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7fe6060f1SDimitry Andric // 8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9fe6060f1SDimitry Andric 10fe6060f1SDimitry Andric #ifndef _LIBCPP___FUNCTIONAL_OPERATIONS_H 11fe6060f1SDimitry Andric #define _LIBCPP___FUNCTIONAL_OPERATIONS_H 12fe6060f1SDimitry Andric 13fe6060f1SDimitry Andric #include <__config> 14fe6060f1SDimitry Andric #include <__functional/binary_function.h> 15fe6060f1SDimitry Andric #include <__functional/unary_function.h> 1606c3fb27SDimitry Andric #include <__type_traits/integral_constant.h> 1706c3fb27SDimitry Andric #include <__type_traits/operation_traits.h> 18fe6060f1SDimitry Andric #include <__utility/forward.h> 19fe6060f1SDimitry Andric 20fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21fe6060f1SDimitry Andric # pragma GCC system_header 22fe6060f1SDimitry Andric #endif 23fe6060f1SDimitry Andric 24fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 25fe6060f1SDimitry Andric 26fe6060f1SDimitry Andric // Arithmetic operations 27fe6060f1SDimitry Andric 2806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 29fe6060f1SDimitry Andric template <class _Tp = void> 30fe6060f1SDimitry Andric #else 31fe6060f1SDimitry Andric template <class _Tp> 32fe6060f1SDimitry Andric #endif 33*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS plus : __binary_function<_Tp, _Tp, _Tp> { 34fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 35*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 36*cb14a3feSDimitry Andric return __x + __y; 37*cb14a3feSDimitry Andric } 38fe6060f1SDimitry Andric }; 39bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus); 40fe6060f1SDimitry Andric 415f757f3fSDimitry Andric // The non-transparent std::plus specialization is only equivalent to a raw plus 425f757f3fSDimitry Andric // operator when we don't perform an implicit conversion when calling it. 4306c3fb27SDimitry Andric template <class _Tp> 445f757f3fSDimitry Andric struct __desugars_to<__plus_tag, plus<_Tp>, _Tp, _Tp> : true_type {}; 4506c3fb27SDimitry Andric 4606c3fb27SDimitry Andric template <class _Tp, class _Up> 475f757f3fSDimitry Andric struct __desugars_to<__plus_tag, plus<void>, _Tp, _Up> : true_type {}; 4806c3fb27SDimitry Andric 4906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 50fe6060f1SDimitry Andric template <> 51*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS plus<void> { 52fe6060f1SDimitry Andric template <class _T1, class _T2> 53*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 545f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) 55*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) + std::forward<_T2>(__u)) { 56*cb14a3feSDimitry Andric return std::forward<_T1>(__t) + std::forward<_T2>(__u); 57*cb14a3feSDimitry Andric } 58fe6060f1SDimitry Andric typedef void is_transparent; 59fe6060f1SDimitry Andric }; 60fe6060f1SDimitry Andric #endif 61fe6060f1SDimitry Andric 6206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 63fe6060f1SDimitry Andric template <class _Tp = void> 64fe6060f1SDimitry Andric #else 65fe6060f1SDimitry Andric template <class _Tp> 66fe6060f1SDimitry Andric #endif 67*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS minus : __binary_function<_Tp, _Tp, _Tp> { 68fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 69*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 70*cb14a3feSDimitry Andric return __x - __y; 71*cb14a3feSDimitry Andric } 72fe6060f1SDimitry Andric }; 73bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus); 74fe6060f1SDimitry Andric 7506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 76fe6060f1SDimitry Andric template <> 77*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS minus<void> { 78fe6060f1SDimitry Andric template <class _T1, class _T2> 79*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 805f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) 81*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) - std::forward<_T2>(__u)) { 82*cb14a3feSDimitry Andric return std::forward<_T1>(__t) - std::forward<_T2>(__u); 83*cb14a3feSDimitry Andric } 84fe6060f1SDimitry Andric typedef void is_transparent; 85fe6060f1SDimitry Andric }; 86fe6060f1SDimitry Andric #endif 87fe6060f1SDimitry Andric 8806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 89fe6060f1SDimitry Andric template <class _Tp = void> 90fe6060f1SDimitry Andric #else 91fe6060f1SDimitry Andric template <class _Tp> 92fe6060f1SDimitry Andric #endif 93*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS multiplies : __binary_function<_Tp, _Tp, _Tp> { 94fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 95*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 96*cb14a3feSDimitry Andric return __x * __y; 97*cb14a3feSDimitry Andric } 98fe6060f1SDimitry Andric }; 99bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies); 100fe6060f1SDimitry Andric 10106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 102fe6060f1SDimitry Andric template <> 103*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS multiplies<void> { 104fe6060f1SDimitry Andric template <class _T1, class _T2> 105*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 1065f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) 107*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) * std::forward<_T2>(__u)) { 108*cb14a3feSDimitry Andric return std::forward<_T1>(__t) * std::forward<_T2>(__u); 109*cb14a3feSDimitry Andric } 110fe6060f1SDimitry Andric typedef void is_transparent; 111fe6060f1SDimitry Andric }; 112fe6060f1SDimitry Andric #endif 113fe6060f1SDimitry Andric 11406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 115fe6060f1SDimitry Andric template <class _Tp = void> 116fe6060f1SDimitry Andric #else 117fe6060f1SDimitry Andric template <class _Tp> 118fe6060f1SDimitry Andric #endif 119*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS divides : __binary_function<_Tp, _Tp, _Tp> { 120fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 121*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 122*cb14a3feSDimitry Andric return __x / __y; 123*cb14a3feSDimitry Andric } 124fe6060f1SDimitry Andric }; 125bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides); 126fe6060f1SDimitry Andric 12706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 128fe6060f1SDimitry Andric template <> 129*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS divides<void> { 130fe6060f1SDimitry Andric template <class _T1, class _T2> 131*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 1325f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) 133*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) / std::forward<_T2>(__u)) { 134*cb14a3feSDimitry Andric return std::forward<_T1>(__t) / std::forward<_T2>(__u); 135*cb14a3feSDimitry Andric } 136fe6060f1SDimitry Andric typedef void is_transparent; 137fe6060f1SDimitry Andric }; 138fe6060f1SDimitry Andric #endif 139fe6060f1SDimitry Andric 14006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 141fe6060f1SDimitry Andric template <class _Tp = void> 142fe6060f1SDimitry Andric #else 143fe6060f1SDimitry Andric template <class _Tp> 144fe6060f1SDimitry Andric #endif 145*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS modulus : __binary_function<_Tp, _Tp, _Tp> { 146fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 147*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 148*cb14a3feSDimitry Andric return __x % __y; 149*cb14a3feSDimitry Andric } 150fe6060f1SDimitry Andric }; 151bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus); 152fe6060f1SDimitry Andric 15306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 154fe6060f1SDimitry Andric template <> 155*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS modulus<void> { 156fe6060f1SDimitry Andric template <class _T1, class _T2> 157*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 1585f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) 159*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) % std::forward<_T2>(__u)) { 160*cb14a3feSDimitry Andric return std::forward<_T1>(__t) % std::forward<_T2>(__u); 161*cb14a3feSDimitry Andric } 162fe6060f1SDimitry Andric typedef void is_transparent; 163fe6060f1SDimitry Andric }; 164fe6060f1SDimitry Andric #endif 165fe6060f1SDimitry Andric 16606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 167fe6060f1SDimitry Andric template <class _Tp = void> 168fe6060f1SDimitry Andric #else 169fe6060f1SDimitry Andric template <class _Tp> 170fe6060f1SDimitry Andric #endif 171*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS negate : __unary_function<_Tp, _Tp> { 172fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 173*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return -__x; } 174fe6060f1SDimitry Andric }; 175bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate); 176fe6060f1SDimitry Andric 17706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 178fe6060f1SDimitry Andric template <> 179*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS negate<void> { 180fe6060f1SDimitry Andric template <class _Tp> 181*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const 182*cb14a3feSDimitry Andric noexcept(noexcept(-std::forward<_Tp>(__x))) -> decltype(-std::forward<_Tp>(__x)) { 183*cb14a3feSDimitry Andric return -std::forward<_Tp>(__x); 184*cb14a3feSDimitry Andric } 185fe6060f1SDimitry Andric typedef void is_transparent; 186fe6060f1SDimitry Andric }; 187fe6060f1SDimitry Andric #endif 188fe6060f1SDimitry Andric 189fe6060f1SDimitry Andric // Bitwise operations 190fe6060f1SDimitry Andric 19106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 192fe6060f1SDimitry Andric template <class _Tp = void> 193fe6060f1SDimitry Andric #else 194fe6060f1SDimitry Andric template <class _Tp> 195fe6060f1SDimitry Andric #endif 196*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_and : __binary_function<_Tp, _Tp, _Tp> { 197fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 198*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 199*cb14a3feSDimitry Andric return __x & __y; 200*cb14a3feSDimitry Andric } 201fe6060f1SDimitry Andric }; 202bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and); 203fe6060f1SDimitry Andric 20406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 205fe6060f1SDimitry Andric template <> 206*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_and<void> { 207fe6060f1SDimitry Andric template <class _T1, class _T2> 208*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 2095f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) & std::forward<_T2>(__u))) 210*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) { 211*cb14a3feSDimitry Andric return std::forward<_T1>(__t) & std::forward<_T2>(__u); 212*cb14a3feSDimitry Andric } 213fe6060f1SDimitry Andric typedef void is_transparent; 214fe6060f1SDimitry Andric }; 215fe6060f1SDimitry Andric #endif 216fe6060f1SDimitry Andric 21706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 218fe6060f1SDimitry Andric template <class _Tp = void> 219*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_not : __unary_function<_Tp, _Tp> { 220*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return ~__x; } 221fe6060f1SDimitry Andric }; 222bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_not); 223fe6060f1SDimitry Andric 224fe6060f1SDimitry Andric template <> 225*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_not<void> { 226fe6060f1SDimitry Andric template <class _Tp> 227*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const 228*cb14a3feSDimitry Andric noexcept(noexcept(~std::forward<_Tp>(__x))) -> decltype(~std::forward<_Tp>(__x)) { 229*cb14a3feSDimitry Andric return ~std::forward<_Tp>(__x); 230*cb14a3feSDimitry Andric } 231fe6060f1SDimitry Andric typedef void is_transparent; 232fe6060f1SDimitry Andric }; 233fe6060f1SDimitry Andric #endif 234fe6060f1SDimitry Andric 23506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 236fe6060f1SDimitry Andric template <class _Tp = void> 237fe6060f1SDimitry Andric #else 238fe6060f1SDimitry Andric template <class _Tp> 239fe6060f1SDimitry Andric #endif 240*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_or : __binary_function<_Tp, _Tp, _Tp> { 241fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 242*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 243*cb14a3feSDimitry Andric return __x | __y; 244*cb14a3feSDimitry Andric } 245fe6060f1SDimitry Andric }; 246bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or); 247fe6060f1SDimitry Andric 24806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 249fe6060f1SDimitry Andric template <> 250*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_or<void> { 251fe6060f1SDimitry Andric template <class _T1, class _T2> 252*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 2535f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) | std::forward<_T2>(__u))) 254*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) | std::forward<_T2>(__u)) { 255*cb14a3feSDimitry Andric return std::forward<_T1>(__t) | std::forward<_T2>(__u); 256*cb14a3feSDimitry Andric } 257fe6060f1SDimitry Andric typedef void is_transparent; 258fe6060f1SDimitry Andric }; 259fe6060f1SDimitry Andric #endif 260fe6060f1SDimitry Andric 26106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 262fe6060f1SDimitry Andric template <class _Tp = void> 263fe6060f1SDimitry Andric #else 264fe6060f1SDimitry Andric template <class _Tp> 265fe6060f1SDimitry Andric #endif 266*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_xor : __binary_function<_Tp, _Tp, _Tp> { 267fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 268*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 269*cb14a3feSDimitry Andric return __x ^ __y; 270*cb14a3feSDimitry Andric } 271fe6060f1SDimitry Andric }; 272bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor); 273fe6060f1SDimitry Andric 27406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 275fe6060f1SDimitry Andric template <> 276*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_xor<void> { 277fe6060f1SDimitry Andric template <class _T1, class _T2> 278*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 2795f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) ^ std::forward<_T2>(__u))) 280*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) ^ std::forward<_T2>(__u)) { 281*cb14a3feSDimitry Andric return std::forward<_T1>(__t) ^ std::forward<_T2>(__u); 282*cb14a3feSDimitry Andric } 283fe6060f1SDimitry Andric typedef void is_transparent; 284fe6060f1SDimitry Andric }; 285fe6060f1SDimitry Andric #endif 286fe6060f1SDimitry Andric 287fe6060f1SDimitry Andric // Comparison operations 288fe6060f1SDimitry Andric 28906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 290fe6060f1SDimitry Andric template <class _Tp = void> 291fe6060f1SDimitry Andric #else 292fe6060f1SDimitry Andric template <class _Tp> 293fe6060f1SDimitry Andric #endif 294*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS equal_to : __binary_function<_Tp, _Tp, bool> { 295fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 296*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 297*cb14a3feSDimitry Andric return __x == __y; 298*cb14a3feSDimitry Andric } 299fe6060f1SDimitry Andric }; 300bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to); 301fe6060f1SDimitry Andric 30206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 303fe6060f1SDimitry Andric template <> 304*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS equal_to<void> { 305fe6060f1SDimitry Andric template <class _T1, class _T2> 306*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 3075f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) == std::forward<_T2>(__u))) 308*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) == std::forward<_T2>(__u)) { 309*cb14a3feSDimitry Andric return std::forward<_T1>(__t) == std::forward<_T2>(__u); 310*cb14a3feSDimitry Andric } 311fe6060f1SDimitry Andric typedef void is_transparent; 312fe6060f1SDimitry Andric }; 313fe6060f1SDimitry Andric #endif 314fe6060f1SDimitry Andric 3155f757f3fSDimitry Andric // The non-transparent std::equal_to specialization is only equivalent to a raw equality 3165f757f3fSDimitry Andric // comparison when we don't perform an implicit conversion when calling it. 31706c3fb27SDimitry Andric template <class _Tp> 3185f757f3fSDimitry Andric struct __desugars_to<__equal_tag, equal_to<_Tp>, _Tp, _Tp> : true_type {}; 31906c3fb27SDimitry Andric 3205f757f3fSDimitry Andric // In the transparent case, we do not enforce that 3215f757f3fSDimitry Andric template <class _Tp, class _Up> 3225f757f3fSDimitry Andric struct __desugars_to<__equal_tag, equal_to<void>, _Tp, _Up> : true_type {}; 32306c3fb27SDimitry Andric 32406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 325fe6060f1SDimitry Andric template <class _Tp = void> 326fe6060f1SDimitry Andric #else 327fe6060f1SDimitry Andric template <class _Tp> 328fe6060f1SDimitry Andric #endif 329*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS not_equal_to : __binary_function<_Tp, _Tp, bool> { 330fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 331*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 332*cb14a3feSDimitry Andric return __x != __y; 333*cb14a3feSDimitry Andric } 334fe6060f1SDimitry Andric }; 335bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to); 336fe6060f1SDimitry Andric 33706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 338fe6060f1SDimitry Andric template <> 339*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS not_equal_to<void> { 340fe6060f1SDimitry Andric template <class _T1, class _T2> 341*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 3425f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) != std::forward<_T2>(__u))) 343*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) != std::forward<_T2>(__u)) { 344*cb14a3feSDimitry Andric return std::forward<_T1>(__t) != std::forward<_T2>(__u); 345*cb14a3feSDimitry Andric } 346fe6060f1SDimitry Andric typedef void is_transparent; 347fe6060f1SDimitry Andric }; 348fe6060f1SDimitry Andric #endif 349fe6060f1SDimitry Andric 35006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 351fe6060f1SDimitry Andric template <class _Tp = void> 352fe6060f1SDimitry Andric #else 353fe6060f1SDimitry Andric template <class _Tp> 354fe6060f1SDimitry Andric #endif 355*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less : __binary_function<_Tp, _Tp, bool> { 356fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 357*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 358*cb14a3feSDimitry Andric return __x < __y; 359*cb14a3feSDimitry Andric } 360fe6060f1SDimitry Andric }; 361bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less); 362fe6060f1SDimitry Andric 36306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 364fe6060f1SDimitry Andric template <> 365*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less<void> { 366fe6060f1SDimitry Andric template <class _T1, class _T2> 367*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 3685f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) 369*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) { 370*cb14a3feSDimitry Andric return std::forward<_T1>(__t) < std::forward<_T2>(__u); 371*cb14a3feSDimitry Andric } 372fe6060f1SDimitry Andric typedef void is_transparent; 373fe6060f1SDimitry Andric }; 374fe6060f1SDimitry Andric #endif 375fe6060f1SDimitry Andric 37606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 377fe6060f1SDimitry Andric template <class _Tp = void> 378fe6060f1SDimitry Andric #else 379fe6060f1SDimitry Andric template <class _Tp> 380fe6060f1SDimitry Andric #endif 381*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less_equal : __binary_function<_Tp, _Tp, bool> { 382fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 383*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 384*cb14a3feSDimitry Andric return __x <= __y; 385*cb14a3feSDimitry Andric } 386fe6060f1SDimitry Andric }; 387bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal); 388fe6060f1SDimitry Andric 38906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 390fe6060f1SDimitry Andric template <> 391*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less_equal<void> { 392fe6060f1SDimitry Andric template <class _T1, class _T2> 393*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 3945f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) <= std::forward<_T2>(__u))) 395*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) <= std::forward<_T2>(__u)) { 396*cb14a3feSDimitry Andric return std::forward<_T1>(__t) <= std::forward<_T2>(__u); 397*cb14a3feSDimitry Andric } 398fe6060f1SDimitry Andric typedef void is_transparent; 399fe6060f1SDimitry Andric }; 400fe6060f1SDimitry Andric #endif 401fe6060f1SDimitry Andric 40206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 403fe6060f1SDimitry Andric template <class _Tp = void> 404fe6060f1SDimitry Andric #else 405fe6060f1SDimitry Andric template <class _Tp> 406fe6060f1SDimitry Andric #endif 407*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater_equal : __binary_function<_Tp, _Tp, bool> { 408fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 409*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 410*cb14a3feSDimitry Andric return __x >= __y; 411*cb14a3feSDimitry Andric } 412fe6060f1SDimitry Andric }; 413bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal); 414fe6060f1SDimitry Andric 41506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 416fe6060f1SDimitry Andric template <> 417*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater_equal<void> { 418fe6060f1SDimitry Andric template <class _T1, class _T2> 419*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 4205f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) >= std::forward<_T2>(__u))) 421*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) { 422*cb14a3feSDimitry Andric return std::forward<_T1>(__t) >= std::forward<_T2>(__u); 423*cb14a3feSDimitry Andric } 424fe6060f1SDimitry Andric typedef void is_transparent; 425fe6060f1SDimitry Andric }; 426fe6060f1SDimitry Andric #endif 427fe6060f1SDimitry Andric 42806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 429fe6060f1SDimitry Andric template <class _Tp = void> 430fe6060f1SDimitry Andric #else 431fe6060f1SDimitry Andric template <class _Tp> 432fe6060f1SDimitry Andric #endif 433*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater : __binary_function<_Tp, _Tp, bool> { 434fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 435*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 436*cb14a3feSDimitry Andric return __x > __y; 437*cb14a3feSDimitry Andric } 438fe6060f1SDimitry Andric }; 439bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater); 440fe6060f1SDimitry Andric 44106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 442fe6060f1SDimitry Andric template <> 443*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater<void> { 444fe6060f1SDimitry Andric template <class _T1, class _T2> 445*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 4465f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) > std::forward<_T2>(__u))) 447*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) > std::forward<_T2>(__u)) { 448*cb14a3feSDimitry Andric return std::forward<_T1>(__t) > std::forward<_T2>(__u); 449*cb14a3feSDimitry Andric } 450fe6060f1SDimitry Andric typedef void is_transparent; 451fe6060f1SDimitry Andric }; 452fe6060f1SDimitry Andric #endif 453fe6060f1SDimitry Andric 454fe6060f1SDimitry Andric // Logical operations 455fe6060f1SDimitry Andric 45606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 457fe6060f1SDimitry Andric template <class _Tp = void> 458fe6060f1SDimitry Andric #else 459fe6060f1SDimitry Andric template <class _Tp> 460fe6060f1SDimitry Andric #endif 461*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_and : __binary_function<_Tp, _Tp, bool> { 462fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 463*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 464*cb14a3feSDimitry Andric return __x && __y; 465*cb14a3feSDimitry Andric } 466fe6060f1SDimitry Andric }; 467bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and); 468fe6060f1SDimitry Andric 46906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 470fe6060f1SDimitry Andric template <> 471*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_and<void> { 472fe6060f1SDimitry Andric template <class _T1, class _T2> 473*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 4745f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) && std::forward<_T2>(__u))) 475*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) && std::forward<_T2>(__u)) { 476*cb14a3feSDimitry Andric return std::forward<_T1>(__t) && std::forward<_T2>(__u); 477*cb14a3feSDimitry Andric } 478fe6060f1SDimitry Andric typedef void is_transparent; 479fe6060f1SDimitry Andric }; 480fe6060f1SDimitry Andric #endif 481fe6060f1SDimitry Andric 48206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 483fe6060f1SDimitry Andric template <class _Tp = void> 484fe6060f1SDimitry Andric #else 485fe6060f1SDimitry Andric template <class _Tp> 486fe6060f1SDimitry Andric #endif 487*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_not : __unary_function<_Tp, bool> { 488fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 489*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const { return !__x; } 490fe6060f1SDimitry Andric }; 491bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not); 492fe6060f1SDimitry Andric 49306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 494fe6060f1SDimitry Andric template <> 495*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_not<void> { 496fe6060f1SDimitry Andric template <class _Tp> 497*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const 498*cb14a3feSDimitry Andric noexcept(noexcept(!std::forward<_Tp>(__x))) -> decltype(!std::forward<_Tp>(__x)) { 499*cb14a3feSDimitry Andric return !std::forward<_Tp>(__x); 500*cb14a3feSDimitry Andric } 501fe6060f1SDimitry Andric typedef void is_transparent; 502fe6060f1SDimitry Andric }; 503fe6060f1SDimitry Andric #endif 504fe6060f1SDimitry Andric 50506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 506fe6060f1SDimitry Andric template <class _Tp = void> 507fe6060f1SDimitry Andric #else 508fe6060f1SDimitry Andric template <class _Tp> 509fe6060f1SDimitry Andric #endif 510*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_or : __binary_function<_Tp, _Tp, bool> { 511fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 512*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 513*cb14a3feSDimitry Andric return __x || __y; 514*cb14a3feSDimitry Andric } 515fe6060f1SDimitry Andric }; 516bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or); 517fe6060f1SDimitry Andric 51806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 519fe6060f1SDimitry Andric template <> 520*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_or<void> { 521fe6060f1SDimitry Andric template <class _T1, class _T2> 522*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 5235f757f3fSDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) || std::forward<_T2>(__u))) 524*cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) || std::forward<_T2>(__u)) { 525*cb14a3feSDimitry Andric return std::forward<_T1>(__t) || std::forward<_T2>(__u); 526*cb14a3feSDimitry Andric } 527fe6060f1SDimitry Andric typedef void is_transparent; 528fe6060f1SDimitry Andric }; 529fe6060f1SDimitry Andric #endif 530fe6060f1SDimitry Andric 531fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 532fe6060f1SDimitry Andric 533fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_OPERATIONS_H 534