1fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric
9fe6060f1SDimitry Andric #ifndef _LIBCPP___UTILITY_CMP_H
10fe6060f1SDimitry Andric #define _LIBCPP___UTILITY_CMP_H
11fe6060f1SDimitry Andric
12*7a6dacacSDimitry Andric #include <__concepts/arithmetic.h>
13fe6060f1SDimitry Andric #include <__config>
14bdd1243dSDimitry Andric #include <__type_traits/is_signed.h>
15bdd1243dSDimitry Andric #include <__type_traits/make_unsigned.h>
16fe6060f1SDimitry Andric #include <limits>
17fe6060f1SDimitry Andric
18fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19fe6060f1SDimitry Andric # pragma GCC system_header
20fe6060f1SDimitry Andric #endif
21fe6060f1SDimitry Andric
22fe6060f1SDimitry Andric _LIBCPP_PUSH_MACROS
23fe6060f1SDimitry Andric #include <__undef_macros>
24fe6060f1SDimitry Andric
25fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
26fe6060f1SDimitry Andric
2706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
28fe6060f1SDimitry Andric
29*7a6dacacSDimitry Andric template <__libcpp_integer _Tp, __libcpp_integer _Up>
cmp_equal(_Tp __t,_Up __u)30cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
31fe6060f1SDimitry Andric if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
32fe6060f1SDimitry Andric return __t == __u;
33fe6060f1SDimitry Andric else if constexpr (is_signed_v<_Tp>)
34fe6060f1SDimitry Andric return __t < 0 ? false : make_unsigned_t<_Tp>(__t) == __u;
35fe6060f1SDimitry Andric else
36fe6060f1SDimitry Andric return __u < 0 ? false : __t == make_unsigned_t<_Up>(__u);
37fe6060f1SDimitry Andric }
38fe6060f1SDimitry Andric
39*7a6dacacSDimitry Andric template <__libcpp_integer _Tp, __libcpp_integer _Up>
cmp_not_equal(_Tp __t,_Up __u)40cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept {
415f757f3fSDimitry Andric return !std::cmp_equal(__t, __u);
42fe6060f1SDimitry Andric }
43fe6060f1SDimitry Andric
44*7a6dacacSDimitry Andric template <__libcpp_integer _Tp, __libcpp_integer _Up>
cmp_less(_Tp __t,_Up __u)45cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
46fe6060f1SDimitry Andric if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
47fe6060f1SDimitry Andric return __t < __u;
48fe6060f1SDimitry Andric else if constexpr (is_signed_v<_Tp>)
49fe6060f1SDimitry Andric return __t < 0 ? true : make_unsigned_t<_Tp>(__t) < __u;
50fe6060f1SDimitry Andric else
51fe6060f1SDimitry Andric return __u < 0 ? false : __t < make_unsigned_t<_Up>(__u);
52fe6060f1SDimitry Andric }
53fe6060f1SDimitry Andric
54*7a6dacacSDimitry Andric template <__libcpp_integer _Tp, __libcpp_integer _Up>
cmp_greater(_Tp __t,_Up __u)55cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept {
565f757f3fSDimitry Andric return std::cmp_less(__u, __t);
57fe6060f1SDimitry Andric }
58fe6060f1SDimitry Andric
59*7a6dacacSDimitry Andric template <__libcpp_integer _Tp, __libcpp_integer _Up>
cmp_less_equal(_Tp __t,_Up __u)60cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept {
615f757f3fSDimitry Andric return !std::cmp_greater(__t, __u);
62fe6060f1SDimitry Andric }
63fe6060f1SDimitry Andric
64*7a6dacacSDimitry Andric template <__libcpp_integer _Tp, __libcpp_integer _Up>
cmp_greater_equal(_Tp __t,_Up __u)65cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept {
665f757f3fSDimitry Andric return !std::cmp_less(__t, __u);
67fe6060f1SDimitry Andric }
68fe6060f1SDimitry Andric
69*7a6dacacSDimitry Andric template <__libcpp_integer _Tp, __libcpp_integer _Up>
in_range(_Up __u)70cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool in_range(_Up __u) noexcept {
715f757f3fSDimitry Andric return std::cmp_less_equal(__u, numeric_limits<_Tp>::max()) &&
725f757f3fSDimitry Andric std::cmp_greater_equal(__u, numeric_limits<_Tp>::min());
73fe6060f1SDimitry Andric }
74*7a6dacacSDimitry Andric
7506c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20
76fe6060f1SDimitry Andric
77fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD
78fe6060f1SDimitry Andric
79fe6060f1SDimitry Andric _LIBCPP_POP_MACROS
80fe6060f1SDimitry Andric
81fe6060f1SDimitry Andric #endif // _LIBCPP___UTILITY_CMP_H
82