tdf#162786, tdf#161947: Add support for setuptools and pip
[LibreOffice.git] / include / o3tl / intcmp.hxx
blobdbc10d9052b0c6ea8a19e8fda547413670724ff6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #pragma once
12 #include <sal/config.h>
14 #include <type_traits>
15 #include <utility>
17 #include <o3tl/safeint.hxx>
19 namespace o3tl
21 // An approximation of the C++20 integer comparison functions
22 // (<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0586r2.html> "Safe integral
23 // comparisons"), still missing from LLVM 12 libc++:
24 #if defined __cpp_lib_integer_comparison_functions
26 using std::cmp_equal;
27 using std::cmp_not_equal;
28 using std::cmp_less;
29 using std::cmp_greater;
30 using std::cmp_less_equal;
31 using std::cmp_greater_equal;
33 #else
35 template <typename T1, typename T2> constexpr bool cmp_equal(T1 value1, T2 value2) noexcept
37 // coverity[same_on_both_sides: FALSE]
38 if constexpr (std::is_signed_v<T1> == std::is_signed_v<T2>)
40 return value1 == value2;
42 else if constexpr (std::is_signed_v<T1>)
44 return value1 >= 0 && o3tl::make_unsigned(value1) == value2;
46 else
48 return value2 >= 0 && value1 == o3tl::make_unsigned(value2);
52 template <typename T1, typename T2> constexpr bool cmp_not_equal(T1 value1, T2 value2) noexcept
54 return !cmp_equal(value1, value2);
57 template <typename T1, typename T2> constexpr bool cmp_less(T1 value1, T2 value2) noexcept
59 if constexpr (std::is_signed_v<T1> == std::is_signed_v<T2>)
61 return value1 < value2;
63 else if constexpr (std::is_signed_v<T1>)
65 return value1 < 0 || o3tl::make_unsigned(value1) < value2;
67 else
69 return value2 >= 0 && value1 < o3tl::make_unsigned(value2);
73 template <typename T1, typename T2> constexpr bool cmp_greater(T1 value1, T2 value2) noexcept
75 return cmp_less(value2, value1);
78 template <typename T1, typename T2> constexpr bool cmp_less_equal(T1 value1, T2 value2) noexcept
80 return !cmp_greater(value1, value2);
83 template <typename T1, typename T2> constexpr bool cmp_greater_equal(T1 value1, T2 value2) noexcept
85 return !cmp_less(value1, value2);
88 #endif
90 // A convenient operator syntax around the standard integer comparison functions:
91 template <typename T> struct IntCmp
93 explicit constexpr IntCmp(T theValue)
94 : value(theValue)
98 T value;
101 template <typename T1, typename T2> constexpr bool operator==(IntCmp<T1> value1, IntCmp<T2> value2)
103 return o3tl::cmp_equal(value1.value, value2.value);
106 template <typename T1, typename T2> constexpr bool operator!=(IntCmp<T1> value1, IntCmp<T2> value2)
108 return o3tl::cmp_not_equal(value1.value, value2.value);
111 template <typename T1, typename T2> constexpr bool operator<(IntCmp<T1> value1, IntCmp<T2> value2)
113 return o3tl::cmp_less(value1.value, value2.value);
116 template <typename T1, typename T2> constexpr bool operator>(IntCmp<T1> value1, IntCmp<T2> value2)
118 return o3tl::cmp_greater(value1.value, value2.value);
121 template <typename T1, typename T2> constexpr bool operator<=(IntCmp<T1> value1, IntCmp<T2> value2)
123 return o3tl::cmp_less_equal(value1.value, value2.value);
126 template <typename T1, typename T2> constexpr bool operator>=(IntCmp<T1> value1, IntCmp<T2> value2)
128 return o3tl::cmp_greater_equal(value1.value, value2.value);
132 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */