LibreOffice Module o3tl (master) 1
intcmp.hxx
Go to the documentation of this file.
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.
4 *
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 */
9
10#pragma once
11
12#include <sal/config.h>
13
14#include <type_traits>
15#include <utility>
16
17#include <o3tl/safeint.hxx>
18
19namespace o3tl
20{
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"):
24#if defined __cpp_lib_integer_comparison_functions
25
26using std::cmp_equal;
28using std::cmp_less;
32
33#else
34
35template <typename T1, typename T2> constexpr bool cmp_equal(T1 value1, T2 value2) noexcept
36{
37 // coverity[same_on_both_sides: FALSE]
38 if constexpr (std::is_signed_v<T1> == std::is_signed_v<T2>)
39 {
40 return value1 == value2;
41 }
42 else if constexpr (std::is_signed_v<T1>)
43 {
44 return value1 >= 0 && o3tl::make_unsigned(value1) == value2;
45 }
46 else
47 {
48 return value2 >= 0 && value1 == o3tl::make_unsigned(value2);
49 }
50}
51
52template <typename T1, typename T2> constexpr bool cmp_not_equal(T1 value1, T2 value2) noexcept
53{
54 return !cmp_equal(value1, value2);
55}
56
57template <typename T1, typename T2> constexpr bool cmp_less(T1 value1, T2 value2) noexcept
58{
59 if constexpr (std::is_signed_v<T1> == std::is_signed_v<T2>)
60 {
61 return value1 < value2;
62 }
63 else if constexpr (std::is_signed_v<T1>)
64 {
65 return value1 < 0 || o3tl::make_unsigned(value1) < value2;
66 }
67 else
68 {
69 return value2 >= 0 && value1 < o3tl::make_unsigned(value2);
70 }
71}
72
73template <typename T1, typename T2> constexpr bool cmp_greater(T1 value1, T2 value2) noexcept
74{
75 return cmp_less(value2, value1);
76}
77
78template <typename T1, typename T2> constexpr bool cmp_less_equal(T1 value1, T2 value2) noexcept
79{
80 return !cmp_greater(value1, value2);
81}
82
83template <typename T1, typename T2> constexpr bool cmp_greater_equal(T1 value1, T2 value2) noexcept
84{
85 return !cmp_less(value1, value2);
86}
87
88#endif
89
90// A convenient operator syntax around the standard integer comparison functions:
91template <typename T> struct IntCmp
92{
93 explicit constexpr IntCmp(T theValue)
94 : value(theValue)
95 {
96 }
97
99};
100
101template <typename T1, typename T2> constexpr bool operator==(IntCmp<T1> value1, IntCmp<T2> value2)
102{
103 return o3tl::cmp_equal(value1.value, value2.value);
104}
105
106template <typename T1, typename T2> constexpr bool operator!=(IntCmp<T1> value1, IntCmp<T2> value2)
107{
108 return o3tl::cmp_not_equal(value1.value, value2.value);
109}
110
111template <typename T1, typename T2> constexpr bool operator<(IntCmp<T1> value1, IntCmp<T2> value2)
112{
113 return o3tl::cmp_less(value1.value, value2.value);
114}
115
116template <typename T1, typename T2> constexpr bool operator>(IntCmp<T1> value1, IntCmp<T2> value2)
117{
118 return o3tl::cmp_greater(value1.value, value2.value);
119}
120
121template <typename T1, typename T2> constexpr bool operator<=(IntCmp<T1> value1, IntCmp<T2> value2)
122{
123 return o3tl::cmp_less_equal(value1.value, value2.value);
124}
125
126template <typename T1, typename T2> constexpr bool operator>=(IntCmp<T1> value1, IntCmp<T2> value2)
127{
128 return o3tl::cmp_greater_equal(value1.value, value2.value);
129}
130}
131
132/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
constexpr bool operator>(IntCmp< T1 > value1, IntCmp< T2 > value2)
Definition: intcmp.hxx:116
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
Definition: safeint.hxx:205
constexpr bool operator>=(IntCmp< T1 > value1, IntCmp< T2 > value2)
Definition: intcmp.hxx:126
constexpr bool cmp_equal(T1 value1, T2 value2) noexcept
Definition: intcmp.hxx:35
bool operator==(const cow_wrapper< T, P > &a, const cow_wrapper< T, P > &b)
constexpr bool cmp_greater_equal(T1 value1, T2 value2) noexcept
Definition: intcmp.hxx:83
constexpr bool cmp_greater(T1 value1, T2 value2) noexcept
Definition: intcmp.hxx:73
bool operator<(const cow_wrapper< A, P > &a, const cow_wrapper< B, P > &b)
constexpr bool cmp_less_equal(T1 value1, T2 value2) noexcept
Definition: intcmp.hxx:78
constexpr bool operator<=(IntCmp< T1 > value1, IntCmp< T2 > value2)
Definition: intcmp.hxx:121
bool operator!=(const cow_wrapper< T, P > &a, const cow_wrapper< T, P > &b)
constexpr bool cmp_less(T1 value1, T2 value2) noexcept
Definition: intcmp.hxx:57
constexpr bool cmp_not_equal(T1 value1, T2 value2) noexcept
Definition: intcmp.hxx:52
constexpr IntCmp(T theValue)
Definition: intcmp.hxx:93