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> 16*0fca6ea1SDimitry Andric #include <__type_traits/desugars_to.h> 17fe6060f1SDimitry Andric #include <__utility/forward.h> 18fe6060f1SDimitry Andric 19fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20fe6060f1SDimitry Andric # pragma GCC system_header 21fe6060f1SDimitry Andric #endif 22fe6060f1SDimitry Andric 23fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 24fe6060f1SDimitry Andric 25fe6060f1SDimitry Andric // Arithmetic operations 26fe6060f1SDimitry Andric 2706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 28fe6060f1SDimitry Andric template <class _Tp = void> 29fe6060f1SDimitry Andric #else 30fe6060f1SDimitry Andric template <class _Tp> 31fe6060f1SDimitry Andric #endif 32cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS plus : __binary_function<_Tp, _Tp, _Tp> { 33fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 34cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 35cb14a3feSDimitry Andric return __x + __y; 36cb14a3feSDimitry Andric } 37fe6060f1SDimitry Andric }; 38bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus); 39fe6060f1SDimitry Andric 405f757f3fSDimitry Andric // The non-transparent std::plus specialization is only equivalent to a raw plus 415f757f3fSDimitry Andric // operator when we don't perform an implicit conversion when calling it. 4206c3fb27SDimitry Andric template <class _Tp> 43*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__plus_tag, plus<_Tp>, _Tp, _Tp> = true; 4406c3fb27SDimitry Andric 4506c3fb27SDimitry Andric template <class _Tp, class _Up> 46*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__plus_tag, plus<void>, _Tp, _Up> = true; 4706c3fb27SDimitry Andric 4806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 49fe6060f1SDimitry Andric template <> 50cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS plus<void> { 51fe6060f1SDimitry Andric template <class _T1, class _T2> 52cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 53*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) // 54cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) + std::forward<_T2>(__u)) { 55cb14a3feSDimitry Andric return std::forward<_T1>(__t) + std::forward<_T2>(__u); 56cb14a3feSDimitry Andric } 57fe6060f1SDimitry Andric typedef void is_transparent; 58fe6060f1SDimitry Andric }; 59fe6060f1SDimitry Andric #endif 60fe6060f1SDimitry Andric 6106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 62fe6060f1SDimitry Andric template <class _Tp = void> 63fe6060f1SDimitry Andric #else 64fe6060f1SDimitry Andric template <class _Tp> 65fe6060f1SDimitry Andric #endif 66cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS minus : __binary_function<_Tp, _Tp, _Tp> { 67fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 68cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 69cb14a3feSDimitry Andric return __x - __y; 70cb14a3feSDimitry Andric } 71fe6060f1SDimitry Andric }; 72bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus); 73fe6060f1SDimitry Andric 7406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 75fe6060f1SDimitry Andric template <> 76cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS minus<void> { 77fe6060f1SDimitry Andric template <class _T1, class _T2> 78cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 79*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) // 80cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) - std::forward<_T2>(__u)) { 81cb14a3feSDimitry Andric return std::forward<_T1>(__t) - std::forward<_T2>(__u); 82cb14a3feSDimitry Andric } 83fe6060f1SDimitry Andric typedef void is_transparent; 84fe6060f1SDimitry Andric }; 85fe6060f1SDimitry Andric #endif 86fe6060f1SDimitry Andric 8706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 88fe6060f1SDimitry Andric template <class _Tp = void> 89fe6060f1SDimitry Andric #else 90fe6060f1SDimitry Andric template <class _Tp> 91fe6060f1SDimitry Andric #endif 92cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS multiplies : __binary_function<_Tp, _Tp, _Tp> { 93fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 94cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 95cb14a3feSDimitry Andric return __x * __y; 96cb14a3feSDimitry Andric } 97fe6060f1SDimitry Andric }; 98bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies); 99fe6060f1SDimitry Andric 10006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 101fe6060f1SDimitry Andric template <> 102cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS multiplies<void> { 103fe6060f1SDimitry Andric template <class _T1, class _T2> 104cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 105*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) // 106cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) * std::forward<_T2>(__u)) { 107cb14a3feSDimitry Andric return std::forward<_T1>(__t) * std::forward<_T2>(__u); 108cb14a3feSDimitry Andric } 109fe6060f1SDimitry Andric typedef void is_transparent; 110fe6060f1SDimitry Andric }; 111fe6060f1SDimitry Andric #endif 112fe6060f1SDimitry Andric 11306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 114fe6060f1SDimitry Andric template <class _Tp = void> 115fe6060f1SDimitry Andric #else 116fe6060f1SDimitry Andric template <class _Tp> 117fe6060f1SDimitry Andric #endif 118cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS divides : __binary_function<_Tp, _Tp, _Tp> { 119fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 120cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 121cb14a3feSDimitry Andric return __x / __y; 122cb14a3feSDimitry Andric } 123fe6060f1SDimitry Andric }; 124bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides); 125fe6060f1SDimitry Andric 12606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 127fe6060f1SDimitry Andric template <> 128cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS divides<void> { 129fe6060f1SDimitry Andric template <class _T1, class _T2> 130cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 131*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) // 132cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) / std::forward<_T2>(__u)) { 133cb14a3feSDimitry Andric return std::forward<_T1>(__t) / std::forward<_T2>(__u); 134cb14a3feSDimitry Andric } 135fe6060f1SDimitry Andric typedef void is_transparent; 136fe6060f1SDimitry Andric }; 137fe6060f1SDimitry Andric #endif 138fe6060f1SDimitry Andric 13906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 140fe6060f1SDimitry Andric template <class _Tp = void> 141fe6060f1SDimitry Andric #else 142fe6060f1SDimitry Andric template <class _Tp> 143fe6060f1SDimitry Andric #endif 144cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS modulus : __binary_function<_Tp, _Tp, _Tp> { 145fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 146cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 147cb14a3feSDimitry Andric return __x % __y; 148cb14a3feSDimitry Andric } 149fe6060f1SDimitry Andric }; 150bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus); 151fe6060f1SDimitry Andric 15206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 153fe6060f1SDimitry Andric template <> 154cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS modulus<void> { 155fe6060f1SDimitry Andric template <class _T1, class _T2> 156cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 157*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) // 158cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) % std::forward<_T2>(__u)) { 159cb14a3feSDimitry Andric return std::forward<_T1>(__t) % std::forward<_T2>(__u); 160cb14a3feSDimitry Andric } 161fe6060f1SDimitry Andric typedef void is_transparent; 162fe6060f1SDimitry Andric }; 163fe6060f1SDimitry Andric #endif 164fe6060f1SDimitry Andric 16506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 166fe6060f1SDimitry Andric template <class _Tp = void> 167fe6060f1SDimitry Andric #else 168fe6060f1SDimitry Andric template <class _Tp> 169fe6060f1SDimitry Andric #endif 170cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS negate : __unary_function<_Tp, _Tp> { 171fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 172cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return -__x; } 173fe6060f1SDimitry Andric }; 174bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate); 175fe6060f1SDimitry Andric 17606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 177fe6060f1SDimitry Andric template <> 178cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS negate<void> { 179fe6060f1SDimitry Andric template <class _Tp> 180cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const 181*0fca6ea1SDimitry Andric noexcept(noexcept(-std::forward<_Tp>(__x))) // 182*0fca6ea1SDimitry Andric -> decltype(-std::forward<_Tp>(__x)) { 183cb14a3feSDimitry Andric return -std::forward<_Tp>(__x); 184cb14a3feSDimitry 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 196cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_and : __binary_function<_Tp, _Tp, _Tp> { 197fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 198cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 199cb14a3feSDimitry Andric return __x & __y; 200cb14a3feSDimitry Andric } 201fe6060f1SDimitry Andric }; 202bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and); 203fe6060f1SDimitry Andric 20406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 205fe6060f1SDimitry Andric template <> 206cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_and<void> { 207fe6060f1SDimitry Andric template <class _T1, class _T2> 208cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 209*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) & 210*0fca6ea1SDimitry Andric std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) { 211cb14a3feSDimitry Andric return std::forward<_T1>(__t) & std::forward<_T2>(__u); 212cb14a3feSDimitry 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> 219cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_not : __unary_function<_Tp, _Tp> { 220cb14a3feSDimitry 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 <> 225cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_not<void> { 226fe6060f1SDimitry Andric template <class _Tp> 227cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const 228*0fca6ea1SDimitry Andric noexcept(noexcept(~std::forward<_Tp>(__x))) // 229*0fca6ea1SDimitry Andric -> decltype(~std::forward<_Tp>(__x)) { 230cb14a3feSDimitry Andric return ~std::forward<_Tp>(__x); 231cb14a3feSDimitry Andric } 232fe6060f1SDimitry Andric typedef void is_transparent; 233fe6060f1SDimitry Andric }; 234fe6060f1SDimitry Andric #endif 235fe6060f1SDimitry Andric 23606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 237fe6060f1SDimitry Andric template <class _Tp = void> 238fe6060f1SDimitry Andric #else 239fe6060f1SDimitry Andric template <class _Tp> 240fe6060f1SDimitry Andric #endif 241cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_or : __binary_function<_Tp, _Tp, _Tp> { 242fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 243cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 244cb14a3feSDimitry Andric return __x | __y; 245cb14a3feSDimitry Andric } 246fe6060f1SDimitry Andric }; 247bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or); 248fe6060f1SDimitry Andric 24906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 250fe6060f1SDimitry Andric template <> 251cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_or<void> { 252fe6060f1SDimitry Andric template <class _T1, class _T2> 253cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 254*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) | std::forward<_T2>(__u))) // 255cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) | std::forward<_T2>(__u)) { 256cb14a3feSDimitry Andric return std::forward<_T1>(__t) | std::forward<_T2>(__u); 257cb14a3feSDimitry Andric } 258fe6060f1SDimitry Andric typedef void is_transparent; 259fe6060f1SDimitry Andric }; 260fe6060f1SDimitry Andric #endif 261fe6060f1SDimitry Andric 26206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 263fe6060f1SDimitry Andric template <class _Tp = void> 264fe6060f1SDimitry Andric #else 265fe6060f1SDimitry Andric template <class _Tp> 266fe6060f1SDimitry Andric #endif 267cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_xor : __binary_function<_Tp, _Tp, _Tp> { 268fe6060f1SDimitry Andric typedef _Tp __result_type; // used by valarray 269cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { 270cb14a3feSDimitry Andric return __x ^ __y; 271cb14a3feSDimitry Andric } 272fe6060f1SDimitry Andric }; 273bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor); 274fe6060f1SDimitry Andric 27506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 276fe6060f1SDimitry Andric template <> 277cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_xor<void> { 278fe6060f1SDimitry Andric template <class _T1, class _T2> 279cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 280*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) ^ std::forward<_T2>(__u))) // 281cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) ^ std::forward<_T2>(__u)) { 282cb14a3feSDimitry Andric return std::forward<_T1>(__t) ^ std::forward<_T2>(__u); 283cb14a3feSDimitry Andric } 284fe6060f1SDimitry Andric typedef void is_transparent; 285fe6060f1SDimitry Andric }; 286fe6060f1SDimitry Andric #endif 287fe6060f1SDimitry Andric 288fe6060f1SDimitry Andric // Comparison operations 289fe6060f1SDimitry Andric 29006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 291fe6060f1SDimitry Andric template <class _Tp = void> 292fe6060f1SDimitry Andric #else 293fe6060f1SDimitry Andric template <class _Tp> 294fe6060f1SDimitry Andric #endif 295cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS equal_to : __binary_function<_Tp, _Tp, bool> { 296fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 297cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 298cb14a3feSDimitry Andric return __x == __y; 299cb14a3feSDimitry Andric } 300fe6060f1SDimitry Andric }; 301bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to); 302fe6060f1SDimitry Andric 30306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 304fe6060f1SDimitry Andric template <> 305cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS equal_to<void> { 306fe6060f1SDimitry Andric template <class _T1, class _T2> 307cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 308*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) == std::forward<_T2>(__u))) // 309cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) == std::forward<_T2>(__u)) { 310cb14a3feSDimitry Andric return std::forward<_T1>(__t) == std::forward<_T2>(__u); 311cb14a3feSDimitry Andric } 312fe6060f1SDimitry Andric typedef void is_transparent; 313fe6060f1SDimitry Andric }; 314fe6060f1SDimitry Andric #endif 315fe6060f1SDimitry Andric 3165f757f3fSDimitry Andric // The non-transparent std::equal_to specialization is only equivalent to a raw equality 3175f757f3fSDimitry Andric // comparison when we don't perform an implicit conversion when calling it. 31806c3fb27SDimitry Andric template <class _Tp> 319*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__equal_tag, equal_to<_Tp>, _Tp, _Tp> = true; 32006c3fb27SDimitry Andric 3215f757f3fSDimitry Andric // In the transparent case, we do not enforce that 3225f757f3fSDimitry Andric template <class _Tp, class _Up> 323*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__equal_tag, equal_to<void>, _Tp, _Up> = true; 32406c3fb27SDimitry Andric 32506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 326fe6060f1SDimitry Andric template <class _Tp = void> 327fe6060f1SDimitry Andric #else 328fe6060f1SDimitry Andric template <class _Tp> 329fe6060f1SDimitry Andric #endif 330cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS not_equal_to : __binary_function<_Tp, _Tp, bool> { 331fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 332cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 333cb14a3feSDimitry Andric return __x != __y; 334cb14a3feSDimitry Andric } 335fe6060f1SDimitry Andric }; 336bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to); 337fe6060f1SDimitry Andric 33806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 339fe6060f1SDimitry Andric template <> 340cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS not_equal_to<void> { 341fe6060f1SDimitry Andric template <class _T1, class _T2> 342cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 343*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) != std::forward<_T2>(__u))) // 344cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) != std::forward<_T2>(__u)) { 345cb14a3feSDimitry Andric return std::forward<_T1>(__t) != std::forward<_T2>(__u); 346cb14a3feSDimitry Andric } 347fe6060f1SDimitry Andric typedef void is_transparent; 348fe6060f1SDimitry Andric }; 349fe6060f1SDimitry Andric #endif 350fe6060f1SDimitry Andric 35106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 352fe6060f1SDimitry Andric template <class _Tp = void> 353fe6060f1SDimitry Andric #else 354fe6060f1SDimitry Andric template <class _Tp> 355fe6060f1SDimitry Andric #endif 356cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less : __binary_function<_Tp, _Tp, bool> { 357fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 358cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 359cb14a3feSDimitry Andric return __x < __y; 360cb14a3feSDimitry Andric } 361fe6060f1SDimitry Andric }; 362bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less); 363fe6060f1SDimitry Andric 364*0fca6ea1SDimitry Andric template <class _Tp> 365*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__less_tag, less<_Tp>, _Tp, _Tp> = true; 366*0fca6ea1SDimitry Andric 36706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 368fe6060f1SDimitry Andric template <> 369cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less<void> { 370fe6060f1SDimitry Andric template <class _T1, class _T2> 371cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 372*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) // 373cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) { 374cb14a3feSDimitry Andric return std::forward<_T1>(__t) < std::forward<_T2>(__u); 375cb14a3feSDimitry Andric } 376fe6060f1SDimitry Andric typedef void is_transparent; 377fe6060f1SDimitry Andric }; 378*0fca6ea1SDimitry Andric 379*0fca6ea1SDimitry Andric template <class _Tp> 380*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__less_tag, less<>, _Tp, _Tp> = true; 381fe6060f1SDimitry Andric #endif 382fe6060f1SDimitry Andric 38306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 384fe6060f1SDimitry Andric template <class _Tp = void> 385fe6060f1SDimitry Andric #else 386fe6060f1SDimitry Andric template <class _Tp> 387fe6060f1SDimitry Andric #endif 388cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less_equal : __binary_function<_Tp, _Tp, bool> { 389fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 390cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 391cb14a3feSDimitry Andric return __x <= __y; 392cb14a3feSDimitry Andric } 393fe6060f1SDimitry Andric }; 394bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal); 395fe6060f1SDimitry Andric 39606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 397fe6060f1SDimitry Andric template <> 398cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less_equal<void> { 399fe6060f1SDimitry Andric template <class _T1, class _T2> 400cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 401*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) <= std::forward<_T2>(__u))) // 402cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) <= std::forward<_T2>(__u)) { 403cb14a3feSDimitry Andric return std::forward<_T1>(__t) <= std::forward<_T2>(__u); 404cb14a3feSDimitry Andric } 405fe6060f1SDimitry Andric typedef void is_transparent; 406fe6060f1SDimitry Andric }; 407fe6060f1SDimitry Andric #endif 408fe6060f1SDimitry Andric 40906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 410fe6060f1SDimitry Andric template <class _Tp = void> 411fe6060f1SDimitry Andric #else 412fe6060f1SDimitry Andric template <class _Tp> 413fe6060f1SDimitry Andric #endif 414cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater_equal : __binary_function<_Tp, _Tp, bool> { 415fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 416cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 417cb14a3feSDimitry Andric return __x >= __y; 418cb14a3feSDimitry Andric } 419fe6060f1SDimitry Andric }; 420bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal); 421fe6060f1SDimitry Andric 42206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 423fe6060f1SDimitry Andric template <> 424cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater_equal<void> { 425fe6060f1SDimitry Andric template <class _T1, class _T2> 426cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 427*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) >= 428*0fca6ea1SDimitry Andric std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) { 429cb14a3feSDimitry Andric return std::forward<_T1>(__t) >= std::forward<_T2>(__u); 430cb14a3feSDimitry Andric } 431fe6060f1SDimitry Andric typedef void is_transparent; 432fe6060f1SDimitry Andric }; 433fe6060f1SDimitry Andric #endif 434fe6060f1SDimitry Andric 43506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 436fe6060f1SDimitry Andric template <class _Tp = void> 437fe6060f1SDimitry Andric #else 438fe6060f1SDimitry Andric template <class _Tp> 439fe6060f1SDimitry Andric #endif 440cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater : __binary_function<_Tp, _Tp, bool> { 441fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 442cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 443cb14a3feSDimitry Andric return __x > __y; 444cb14a3feSDimitry Andric } 445fe6060f1SDimitry Andric }; 446bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater); 447fe6060f1SDimitry Andric 44806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 449fe6060f1SDimitry Andric template <> 450cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater<void> { 451fe6060f1SDimitry Andric template <class _T1, class _T2> 452cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 453*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) > std::forward<_T2>(__u))) // 454cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) > std::forward<_T2>(__u)) { 455cb14a3feSDimitry Andric return std::forward<_T1>(__t) > std::forward<_T2>(__u); 456cb14a3feSDimitry Andric } 457fe6060f1SDimitry Andric typedef void is_transparent; 458fe6060f1SDimitry Andric }; 459fe6060f1SDimitry Andric #endif 460fe6060f1SDimitry Andric 461fe6060f1SDimitry Andric // Logical operations 462fe6060f1SDimitry Andric 46306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 464fe6060f1SDimitry Andric template <class _Tp = void> 465fe6060f1SDimitry Andric #else 466fe6060f1SDimitry Andric template <class _Tp> 467fe6060f1SDimitry Andric #endif 468cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_and : __binary_function<_Tp, _Tp, bool> { 469fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 470cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 471cb14a3feSDimitry Andric return __x && __y; 472cb14a3feSDimitry Andric } 473fe6060f1SDimitry Andric }; 474bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and); 475fe6060f1SDimitry Andric 47606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 477fe6060f1SDimitry Andric template <> 478cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_and<void> { 479fe6060f1SDimitry Andric template <class _T1, class _T2> 480cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 481*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) && std::forward<_T2>(__u))) // 482cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) && std::forward<_T2>(__u)) { 483cb14a3feSDimitry Andric return std::forward<_T1>(__t) && std::forward<_T2>(__u); 484cb14a3feSDimitry Andric } 485fe6060f1SDimitry Andric typedef void is_transparent; 486fe6060f1SDimitry Andric }; 487fe6060f1SDimitry Andric #endif 488fe6060f1SDimitry Andric 48906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 490fe6060f1SDimitry Andric template <class _Tp = void> 491fe6060f1SDimitry Andric #else 492fe6060f1SDimitry Andric template <class _Tp> 493fe6060f1SDimitry Andric #endif 494cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_not : __unary_function<_Tp, bool> { 495fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 496cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const { return !__x; } 497fe6060f1SDimitry Andric }; 498bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not); 499fe6060f1SDimitry Andric 50006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 501fe6060f1SDimitry Andric template <> 502cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_not<void> { 503fe6060f1SDimitry Andric template <class _Tp> 504cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const 505*0fca6ea1SDimitry Andric noexcept(noexcept(!std::forward<_Tp>(__x))) // 506*0fca6ea1SDimitry Andric -> decltype(!std::forward<_Tp>(__x)) { 507cb14a3feSDimitry Andric return !std::forward<_Tp>(__x); 508cb14a3feSDimitry Andric } 509fe6060f1SDimitry Andric typedef void is_transparent; 510fe6060f1SDimitry Andric }; 511fe6060f1SDimitry Andric #endif 512fe6060f1SDimitry Andric 51306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 514fe6060f1SDimitry Andric template <class _Tp = void> 515fe6060f1SDimitry Andric #else 516fe6060f1SDimitry Andric template <class _Tp> 517fe6060f1SDimitry Andric #endif 518cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_or : __binary_function<_Tp, _Tp, bool> { 519fe6060f1SDimitry Andric typedef bool __result_type; // used by valarray 520cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 521cb14a3feSDimitry Andric return __x || __y; 522cb14a3feSDimitry Andric } 523fe6060f1SDimitry Andric }; 524bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or); 525fe6060f1SDimitry Andric 52606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 527fe6060f1SDimitry Andric template <> 528cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_or<void> { 529fe6060f1SDimitry Andric template <class _T1, class _T2> 530cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const 531*0fca6ea1SDimitry Andric noexcept(noexcept(std::forward<_T1>(__t) || std::forward<_T2>(__u))) // 532cb14a3feSDimitry Andric -> decltype(std::forward<_T1>(__t) || std::forward<_T2>(__u)) { 533cb14a3feSDimitry Andric return std::forward<_T1>(__t) || std::forward<_T2>(__u); 534cb14a3feSDimitry Andric } 535fe6060f1SDimitry Andric typedef void is_transparent; 536fe6060f1SDimitry Andric }; 537fe6060f1SDimitry Andric #endif 538fe6060f1SDimitry Andric 539fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 540fe6060f1SDimitry Andric 541fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_OPERATIONS_H 542