blob: 438ab55b43230094384ca54c0592a0c6e1be4f4f [file] [log] [blame]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___UTILITY_DEFAULT_THREE_WAY_COMPARATOR_H
#define _LIBCPP___UTILITY_DEFAULT_THREE_WAY_COMPARATOR_H
#include <__config>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_arithmetic.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
// This struct can be specialized to provide a three way comparator between _LHS and _RHS.
// The return value should be
// - less than zero if (lhs_val < rhs_val)
// - greater than zero if (rhs_val < lhs_val)
// - zero otherwise
template <class _LHS, class _RHS, class = void>
struct __default_three_way_comparator;
template <class _LHS, class _RHS>
struct __default_three_way_comparator<_LHS,
_RHS,
__enable_if_t<is_arithmetic<_LHS>::value && is_arithmetic<_RHS>::value> > {
_LIBCPP_HIDE_FROM_ABI static int operator()(_LHS __lhs, _RHS __rhs) {
if (__lhs < __rhs)
return -1;
if (__lhs > __rhs)
return 1;
return 0;
}
};
#if _LIBCPP_STD_VER >= 20 && __has_builtin(__builtin_lt_synthesises_from_spaceship)
template <class _LHS, class _RHS>
struct __default_three_way_comparator<
_LHS,
_RHS,
__enable_if_t<!(is_arithmetic<_LHS>::value && is_arithmetic<_RHS>::value) &&
__builtin_lt_synthesises_from_spaceship(const _LHS&, const _RHS&)>> {
_LIBCPP_HIDE_FROM_ABI static int operator()(const _LHS& __lhs, const _RHS& __rhs) {
auto __res = __lhs <=> __rhs;
if (__res < 0)
return -1;
if (__res > 0)
return 1;
return 0;
}
};
#endif
template <class _LHS, class _RHS, bool = true>
struct __has_default_three_way_comparator : false_type {};
template <class _LHS, class _RHS>
struct __has_default_three_way_comparator<_LHS, _RHS, sizeof(__default_three_way_comparator<_LHS, _RHS>) >= 0>
: true_type {};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___UTILITY_DEFAULT_THREE_WAY_COMPARATOR_H