diff options
-rw-r--r-- | cppu/source/uno/eq.hxx | 170 | ||||
-rw-r--r-- | include/o3tl/intcmp.hxx | 131 | ||||
-rw-r--r-- | include/o3tl/string_view.hxx | 3 |
3 files changed, 232 insertions, 72 deletions
diff --git a/cppu/source/uno/eq.hxx b/cppu/source/uno/eq.hxx index e81f0972e801..60a372886776 100644 --- a/cppu/source/uno/eq.hxx +++ b/cppu/source/uno/eq.hxx @@ -20,8 +20,8 @@ #include <cmath> #include <string.h> -#include <type_traits> +#include <o3tl/intcmp.hxx> #include <osl/diagnose.h> #include <rtl/ustring.hxx> @@ -260,27 +260,6 @@ inline bool _equalSequence( } } -template<typename T1, typename T2> -std::enable_if_t<std::is_signed_v<T1> && std::is_signed_v<T2>, bool> equal(T1 value1, T2 value2) { - return value1 == value2; -} - -template<typename T1, typename T2> -std::enable_if_t<std::is_signed_v<T1> && std::is_unsigned_v<T2>, bool> equal(T1 value1, T2 value2) { - return value1 >= 0 && static_cast<std::make_unsigned_t<T1>>(value1) == value2; -} - -template<typename T1, typename T2> -std::enable_if_t<std::is_unsigned_v<T1> && std::is_signed_v<T2>, bool> equal(T1 value1, T2 value2) { - return value2 >= 0 && value1 == static_cast<std::make_unsigned_t<T2>>(value2); -} - -template<typename T1, typename T2> -std::enable_if_t<std::is_unsigned_v<T1> && std::is_unsigned_v<T2>, bool> equal(T1 value1, T2 value2) -{ - return value1 == value2; -} - inline bool _equalData( void * pDest, typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr, @@ -316,19 +295,26 @@ inline bool _equalData( switch (eSourceTypeClass) { case typelib_TypeClass_BYTE: - return equal(*static_cast<sal_Int8 *>(pDest), *static_cast<sal_Int8 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int8 *>(pDest), *static_cast<sal_Int8 *>(pSource)); case typelib_TypeClass_SHORT: - return equal(*static_cast<sal_Int8 *>(pDest), *static_cast<sal_Int16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int8 *>(pDest), *static_cast<sal_Int16 *>(pSource)); case typelib_TypeClass_UNSIGNED_SHORT: - return equal(*static_cast<sal_Int8 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int8 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); case typelib_TypeClass_LONG: - return equal(*static_cast<sal_Int8 *>(pDest), *static_cast<sal_Int32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int8 *>(pDest), *static_cast<sal_Int32 *>(pSource)); case typelib_TypeClass_UNSIGNED_LONG: - return equal(*static_cast<sal_Int8 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int8 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); case typelib_TypeClass_HYPER: - return equal(*static_cast<sal_Int8 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int8 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_UNSIGNED_HYPER: - return equal(*static_cast<sal_Int8 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int8 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_FLOAT: return (static_cast<float>(*static_cast<sal_Int8 *>(pDest)) == *static_cast<float *>(pSource)); case typelib_TypeClass_DOUBLE: @@ -340,19 +326,26 @@ inline bool _equalData( switch (eSourceTypeClass) { case typelib_TypeClass_BYTE: - return equal(*static_cast<sal_Int16 *>(pDest), *static_cast<sal_Int8 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int16 *>(pDest), *static_cast<sal_Int8 *>(pSource)); case typelib_TypeClass_SHORT: - return equal(*static_cast<sal_Int16 *>(pDest), *static_cast<sal_Int16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int16 *>(pDest), *static_cast<sal_Int16 *>(pSource)); case typelib_TypeClass_UNSIGNED_SHORT: - return equal(*static_cast<sal_Int16 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int16 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); case typelib_TypeClass_LONG: - return equal(*static_cast<sal_Int16 *>(pDest), *static_cast<sal_Int32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int16 *>(pDest), *static_cast<sal_Int32 *>(pSource)); case typelib_TypeClass_UNSIGNED_LONG: - return equal(*static_cast<sal_Int16 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int16 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); case typelib_TypeClass_HYPER: - return equal(*static_cast<sal_Int16 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int16 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_UNSIGNED_HYPER: - return equal(*static_cast<sal_Int16 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int16 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_FLOAT: return (static_cast<float>(*static_cast<sal_Int16 *>(pDest)) == *static_cast<float *>(pSource)); case typelib_TypeClass_DOUBLE: @@ -364,19 +357,26 @@ inline bool _equalData( switch (eSourceTypeClass) { case typelib_TypeClass_BYTE: - return equal(*static_cast<sal_uInt16 *>(pDest), *static_cast<sal_Int8 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt16 *>(pDest), *static_cast<sal_Int8 *>(pSource)); case typelib_TypeClass_SHORT: - return equal(*static_cast<sal_uInt16 *>(pDest), *static_cast<sal_Int16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt16 *>(pDest), *static_cast<sal_Int16 *>(pSource)); case typelib_TypeClass_UNSIGNED_SHORT: - return equal(*static_cast<sal_uInt16 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt16 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); case typelib_TypeClass_LONG: - return equal(*static_cast<sal_uInt16 *>(pDest), *static_cast<sal_Int32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt16 *>(pDest), *static_cast<sal_Int32 *>(pSource)); case typelib_TypeClass_UNSIGNED_LONG: - return equal(*static_cast<sal_uInt16 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt16 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); case typelib_TypeClass_HYPER: - return equal(*static_cast<sal_uInt16 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt16 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_UNSIGNED_HYPER: - return equal(*static_cast<sal_uInt16 *>(pDest), *static_cast<sal_uInt64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt16 *>(pDest), *static_cast<sal_uInt64 *>(pSource)); case typelib_TypeClass_FLOAT: return (static_cast<float>(*static_cast<sal_uInt16 *>(pDest)) == *static_cast<float *>(pSource)); case typelib_TypeClass_DOUBLE: @@ -388,19 +388,26 @@ inline bool _equalData( switch (eSourceTypeClass) { case typelib_TypeClass_BYTE: - return equal(*static_cast<sal_Int32 *>(pDest), *static_cast<sal_Int8 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int32 *>(pDest), *static_cast<sal_Int8 *>(pSource)); case typelib_TypeClass_SHORT: - return equal(*static_cast<sal_Int32 *>(pDest), *static_cast<sal_Int16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int32 *>(pDest), *static_cast<sal_Int16 *>(pSource)); case typelib_TypeClass_UNSIGNED_SHORT: - return equal(*static_cast<sal_Int32 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int32 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); case typelib_TypeClass_LONG: - return equal(*static_cast<sal_Int32 *>(pDest), *static_cast<sal_Int32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int32 *>(pDest), *static_cast<sal_Int32 *>(pSource)); case typelib_TypeClass_UNSIGNED_LONG: - return equal(*static_cast<sal_Int32 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int32 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); case typelib_TypeClass_HYPER: - return equal(*static_cast<sal_Int32 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int32 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_UNSIGNED_HYPER: - return equal(*static_cast<sal_Int32 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int32 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_FLOAT: return (static_cast<float>(*static_cast<sal_Int32 *>(pDest)) == *static_cast<float *>(pSource)); case typelib_TypeClass_DOUBLE: @@ -412,19 +419,26 @@ inline bool _equalData( switch (eSourceTypeClass) { case typelib_TypeClass_BYTE: - return equal(*static_cast<sal_uInt32 *>(pDest), *static_cast<sal_Int8 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt32 *>(pDest), *static_cast<sal_Int8 *>(pSource)); case typelib_TypeClass_SHORT: - return equal(*static_cast<sal_uInt32 *>(pDest), *static_cast<sal_Int16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt32 *>(pDest), *static_cast<sal_Int16 *>(pSource)); case typelib_TypeClass_UNSIGNED_SHORT: - return equal(*static_cast<sal_uInt32 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt32 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); case typelib_TypeClass_LONG: - return equal(*static_cast<sal_uInt32 *>(pDest), *static_cast<sal_Int32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt32 *>(pDest), *static_cast<sal_Int32 *>(pSource)); case typelib_TypeClass_UNSIGNED_LONG: - return equal(*static_cast<sal_uInt32 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt32 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); case typelib_TypeClass_HYPER: - return equal(*static_cast<sal_uInt32 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt32 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_UNSIGNED_HYPER: - return equal(*static_cast<sal_uInt32 *>(pDest), *static_cast<sal_uInt64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt32 *>(pDest), *static_cast<sal_uInt64 *>(pSource)); case typelib_TypeClass_FLOAT: return (static_cast<float>(*static_cast<sal_uInt32 *>(pDest)) == *static_cast<float *>(pSource)); case typelib_TypeClass_DOUBLE: @@ -436,19 +450,26 @@ inline bool _equalData( switch (eSourceTypeClass) { case typelib_TypeClass_BYTE: - return equal(*static_cast<sal_Int64 *>(pDest), *static_cast<sal_Int8 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int64 *>(pDest), *static_cast<sal_Int8 *>(pSource)); case typelib_TypeClass_SHORT: - return equal(*static_cast<sal_Int64 *>(pDest), *static_cast<sal_Int16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int64 *>(pDest), *static_cast<sal_Int16 *>(pSource)); case typelib_TypeClass_UNSIGNED_SHORT: - return equal(*static_cast<sal_Int64 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int64 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); case typelib_TypeClass_LONG: - return equal(*static_cast<sal_Int64 *>(pDest), *static_cast<sal_Int32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int64 *>(pDest), *static_cast<sal_Int32 *>(pSource)); case typelib_TypeClass_UNSIGNED_LONG: - return equal(*static_cast<sal_Int64 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int64 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); case typelib_TypeClass_HYPER: - return equal(*static_cast<sal_Int64 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int64 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_UNSIGNED_HYPER: - return equal(*static_cast<sal_Int64 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_Int64 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_FLOAT: return (static_cast<float>(*static_cast<sal_Int64 *>(pDest)) == *static_cast<float *>(pSource)); case typelib_TypeClass_DOUBLE: @@ -460,19 +481,26 @@ inline bool _equalData( switch (eSourceTypeClass) { case typelib_TypeClass_BYTE: - return equal(*static_cast<sal_uInt64 *>(pDest), *static_cast<sal_Int8 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt64 *>(pDest), *static_cast<sal_Int8 *>(pSource)); case typelib_TypeClass_SHORT: - return equal(*static_cast<sal_uInt64 *>(pDest), *static_cast<sal_Int16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt64 *>(pDest), *static_cast<sal_Int16 *>(pSource)); case typelib_TypeClass_UNSIGNED_SHORT: - return equal(*static_cast<sal_uInt64 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt64 *>(pDest), *static_cast<sal_uInt16 *>(pSource)); case typelib_TypeClass_LONG: - return equal(*static_cast<sal_uInt64 *>(pDest), *static_cast<sal_Int32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt64 *>(pDest), *static_cast<sal_Int32 *>(pSource)); case typelib_TypeClass_UNSIGNED_LONG: - return equal(*static_cast<sal_uInt64 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt64 *>(pDest), *static_cast<sal_uInt32 *>(pSource)); case typelib_TypeClass_HYPER: - return equal(*static_cast<sal_uInt64 *>(pDest), *static_cast<sal_Int64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt64 *>(pDest), *static_cast<sal_Int64 *>(pSource)); case typelib_TypeClass_UNSIGNED_HYPER: - return equal(*static_cast<sal_uInt64 *>(pDest), *static_cast<sal_uInt64 *>(pSource)); + return o3tl::cmp_equal( + *static_cast<sal_uInt64 *>(pDest), *static_cast<sal_uInt64 *>(pSource)); case typelib_TypeClass_FLOAT: if (::floor( *static_cast<float *>(pSource) ) != *static_cast<float *>(pSource) || *static_cast<float *>(pSource) < 0) return false; diff --git a/include/o3tl/intcmp.hxx b/include/o3tl/intcmp.hxx new file mode 100644 index 000000000000..2af537b1dead --- /dev/null +++ b/include/o3tl/intcmp.hxx @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <sal/config.h> + +#include <type_traits> +#include <utility> + +#include <o3tl/safeint.hxx> + +namespace o3tl +{ +// An implementation of the C++23 integer comparison functions +// (<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0586r2.html> "Safe integral +// comparisons"): +#if defined __cpp_lib_integer_comparison_functions + +using std::cmp_equal; +using std::cmp_not_equal; +using std::cmp_less; +using std::cmp_greater; +using std::cmp_less_equal; +using std::cmp_greater_equal; + +#else + +template <typename T1, typename T2> constexpr bool cmp_equal(T1 value1, T2 value2) noexcept +{ + if constexpr (std::is_signed_v<T1> == std::is_signed_v<T2>) + { + return value1 == value2; + } + else if constexpr (std::is_signed_v<T1>) + { + return value1 >= 0 && o3tl::make_unsigned(value1) == value2; + } + else + { + return value2 >= 0 && value1 == o3tl::make_unsigned(value2); + } +} + +template <typename T1, typename T2> constexpr bool cmp_not_equal(T1 value1, T2 value2) noexcept +{ + return !cmp_equal(value1, value2); +} + +template <typename T1, typename T2> constexpr bool cmp_less(T1 value1, T2 value2) noexcept +{ + if constexpr (std::is_signed_v<T1> == std::is_signed_v<T2>) + { + return value1 < value2; + } + else if constexpr (std::is_signed_v<T1>) + { + return value1 < 0 || o3tl::make_unsigned(value1) < value2; + } + else + { + return value2 >= 0 && value1 < o3tl::make_unsigned(value2); + } +} + +template <typename T1, typename T2> constexpr bool cmp_greater(T1 value1, T2 value2) noexcept +{ + return cmp_less(value2, value1); +} + +template <typename T1, typename T2> constexpr bool cmp_less_equal(T1 value1, T2 value2) noexcept +{ + return !cmp_greater(value1, value2); +} + +template <typename T1, typename T2> constexpr bool cmp_greater_equal(T1 value1, T2 value2) noexcept +{ + return !cmp_less(value1, value2); +} + +#endif + +// A convenient operator syntax around the standard integer comparison functions: +template <typename T> struct IntCmp +{ + explicit constexpr IntCmp(T theValue) + : value(theValue) + { + } + + T value; +}; + +template <typename T1, typename T2> constexpr bool operator==(IntCmp<T1> value1, IntCmp<T2> value2) +{ + return o3tl::cmp_equal(value1.value, value2.value); +} + +template <typename T1, typename T2> constexpr bool operator!=(IntCmp<T1> value1, IntCmp<T2> value2) +{ + return o3tl::cmp_not_equal(value1.value, value2.value); +} + +template <typename T1, typename T2> constexpr bool operator<(IntCmp<T1> value1, IntCmp<T2> value2) +{ + return o3tl::cmp_less(value1.value, value2.value); +} + +template <typename T1, typename T2> constexpr bool operator>(IntCmp<T1> value1, IntCmp<T2> value2) +{ + return o3tl::cmp_greater(value1.value, value2.value); +} + +template <typename T1, typename T2> constexpr bool operator<=(IntCmp<T1> value1, IntCmp<T2> value2) +{ + return o3tl::cmp_less_equal(value1.value, value2.value); +} + +template <typename T1, typename T2> constexpr bool operator>=(IntCmp<T1> value1, IntCmp<T2> value2) +{ + return o3tl::cmp_greater_equal(value1.value, value2.value); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/o3tl/string_view.hxx b/include/o3tl/string_view.hxx index cea4f272b947..f6c2a4aa72b9 100644 --- a/include/o3tl/string_view.hxx +++ b/include/o3tl/string_view.hxx @@ -16,6 +16,7 @@ #include <string> #include <string_view> +#include <o3tl/intcmp.hxx> #include <rtl/ustring.h> #include <rtl/math.h> @@ -121,7 +122,7 @@ inline std::basic_string_view<charT, traits> getToken(std::basic_string_view<cha sal_Int32 nToken, charT cTok, sal_Int32& rnIndex) { - assert(rnIndex <= static_cast<sal_Int32>(pStr.size())); + assert(o3tl::IntCmp(rnIndex) <= o3tl::IntCmp(pStr.size())); // Return an empty string and set rnIndex to -1 if either nToken or rnIndex is // negative: |