diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2022-03-02 00:36:10 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2022-03-02 06:22:22 +0100 |
commit | 5b03e07dd21b56e99d6b6b60edec1ed2f388bfc2 (patch) | |
tree | 1ba18dc2d7221bba3b72121aeb8cd61178ef6cbd /sal | |
parent | b7f654a406b704f469d1df424d83a3d98ae46432 (diff) |
Unify and deduplicate to[U]Int[_WithLength]
Change-Id: I05e71b36030da0a91c24b3926ee1d069912849f4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130815
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'sal')
-rw-r--r-- | sal/rtl/strtmpl.hxx | 145 |
1 files changed, 56 insertions, 89 deletions
diff --git a/sal/rtl/strtmpl.hxx b/sal/rtl/strtmpl.hxx index 78375ae07e26..a6b06ad0256e 100644 --- a/sal/rtl/strtmpl.hxx +++ b/sal/rtl/strtmpl.hxx @@ -761,58 +761,63 @@ template <typename IMPL_RTL_STRCODE> sal_Bool toBoolean( const IMPL_RTL_STRCODE* } /* ----------------------------------------------------------------------- */ -template <typename T, typename U, typename IMPL_RTL_STRCODE> -T toInt_WithLength ( const IMPL_RTL_STRCODE* pStr, - sal_Int16 nRadix, - sal_Int32 nStrLength ) + +template <typename T, class Iter> inline bool HandleSignChar(Iter& iter) +{ + if constexpr (std::numeric_limits<T>::is_signed) + { + if (*iter == '-') + { + ++iter; + return true; + } + } + if (*iter == '+') + ++iter; + return false; +} + +template <typename T> std::pair<T, sal_Int16> DivMod(sal_Int16 nRadix, [[maybe_unused]] bool bNeg) +{ + if constexpr (std::numeric_limits<T>::is_signed) + if (bNeg) + return { -(std::numeric_limits<T>::min() / nRadix), + -(std::numeric_limits<T>::min() % nRadix) }; + return { std::numeric_limits<T>::max() / nRadix, std::numeric_limits<T>::max() % nRadix }; +} + +template <class SV> auto getIter(const SV& sv) { return sv.begin(); } +template <typename C> auto getIter(const C* pStr) { return pStr; } + +template <class SV> auto good(typename SV::iterator iter, const SV& sv) { return iter != sv.end(); } +template <typename C> auto good(const C* pStr, const C*) { return *pStr != 0; } + +template <typename T, class S> T toInt(S str, sal_Int16 nRadix) { - static_assert(std::numeric_limits<T>::is_signed, "is signed"); assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); - assert( nStrLength >= 0 ); - bool bNeg; - sal_Int16 nDigit; - U n = 0; - const IMPL_RTL_STRCODE* pEnd = pStr + nStrLength; if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) nRadix = 10; + auto pStr = getIter(str); + /* Skip whitespaces */ - while ( pStr != pEnd && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) ) + while (good(pStr, str) && rtl_ImplIsWhitespace(IMPL_RTL_USTRCODE(*pStr))) pStr++; + if (!good(pStr, str)) + return 0; - if ( *pStr == '-' ) - { - bNeg = true; - pStr++; - } - else - { - if ( *pStr == '+' ) - pStr++; - bNeg = false; - } - - T nDiv; - sal_Int16 nMod; - if ( bNeg ) - { - nDiv = -(std::numeric_limits<T>::min() / nRadix); - nMod = -(std::numeric_limits<T>::min() % nRadix); - } - else - { - nDiv = std::numeric_limits<T>::max() / nRadix; - nMod = std::numeric_limits<T>::max() % nRadix; - } + const bool bNeg = HandleSignChar<T>(pStr); + const auto& [nDiv, nMod] = DivMod<T>(nRadix, bNeg); + assert(nDiv > 0); - while ( pStr != pEnd ) + std::make_unsigned_t<T> n = 0; + while (good(pStr, str)) { - nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); + sal_Int16 nDigit = rtl_ImplGetDigit(IMPL_RTL_USTRCODE(*pStr), nRadix); if ( nDigit < 0 ) break; - assert(nDiv > 0); - if( static_cast<U>( nMod < nDigit ? nDiv-1 : nDiv ) < n ) + if (static_cast<std::make_unsigned_t<T>>(nMod < nDigit ? nDiv - 1 : nDiv) < n) return 0; n *= nRadix; @@ -821,11 +826,12 @@ T toInt_WithLength ( const IMPL_RTL pStr++; } - if ( bNeg ) - return n == static_cast<U>(std::numeric_limits<T>::min()) - ? std::numeric_limits<T>::min() : -static_cast<T>(n); - else - return static_cast<T>(n); + if constexpr (std::numeric_limits<T>::is_signed) + if (bNeg) + return n == static_cast<std::make_unsigned_t<T>>(std::numeric_limits<T>::min()) + ? std::numeric_limits<T>::min() + : -static_cast<T>(n); + return static_cast<T>(n); } template <typename IMPL_RTL_STRCODE> @@ -833,7 +839,7 @@ sal_Int32 toInt32 ( const IMPL_RTL_STRCODE* pStr, sal_Int16 nRadix ) { assert(pStr); - return toInt_WithLength<sal_Int32, sal_uInt32>(pStr, nRadix, getLength(pStr)); + return toInt<sal_Int32>(pStr, nRadix); } template <typename IMPL_RTL_STRCODE> @@ -843,7 +849,7 @@ sal_Int32 toInt32_WithLength ( const IMPL_RTL_STRCODE* pStr, { assert(pStr); - return toInt_WithLength<sal_Int32, sal_uInt32>(pStr, nRadix, nStrLength); + return toInt<sal_Int32>(std::basic_string_view(pStr, nStrLength), nRadix); } template <typename IMPL_RTL_STRCODE> @@ -851,7 +857,7 @@ sal_Int64 toInt64 ( const IMPL_RTL_STRCODE* pStr, sal_Int16 nRadix ) { assert(pStr); - return toInt_WithLength<sal_Int64, sal_uInt64>(pStr, nRadix, getLength(pStr)); + return toInt<sal_Int64>(pStr, nRadix); } template <typename IMPL_RTL_STRCODE> @@ -861,46 +867,7 @@ sal_Int64 toInt64_WithLength ( const IMPL_RTL_STRCODE* pStr, { assert(pStr); - return toInt_WithLength<sal_Int64, sal_uInt64>(pStr, nRadix, nStrLength); -} - -/* ----------------------------------------------------------------------- */ -template <typename T, typename IMPL_RTL_STRCODE> T toUInt( const IMPL_RTL_STRCODE* pStr, - sal_Int16 nRadix ) -{ - static_assert(!std::numeric_limits<T>::is_signed, "is not signed"); - assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); - sal_Int16 nDigit; - T n = 0; - - if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) - nRadix = 10; - - /* Skip whitespaces */ - while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) ) - ++pStr; - - // skip optional explicit sign - if ( *pStr == '+' ) - ++pStr; - - T nDiv = std::numeric_limits<T>::max() / nRadix; - sal_Int16 nMod = std::numeric_limits<T>::max() % nRadix; - while ( *pStr ) - { - nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); - if ( nDigit < 0 ) - break; - if( ( nMod < nDigit ? nDiv-1 : nDiv ) < n ) - return 0; - - n *= nRadix; - n += nDigit; - - ++pStr; - } - - return n; + return toInt<sal_Int64>(std::basic_string_view(pStr, nStrLength), nRadix); } template <typename IMPL_RTL_STRCODE> @@ -908,7 +875,7 @@ sal_uInt32 toUInt32 ( const IMPL_RTL_STRCODE* pStr, sal_Int16 nRadix ) { assert(pStr); - return toUInt<sal_uInt32>(pStr, nRadix); + return toInt<sal_uInt32>(pStr, nRadix); } template <typename IMPL_RTL_STRCODE> @@ -916,7 +883,7 @@ sal_uInt64 toUInt64 ( const IMPL_RTL_STRCODE* pStr, sal_Int16 nRadix ) { assert(pStr); - return toUInt<sal_uInt64>(pStr, nRadix); + return toInt<sal_uInt64>(pStr, nRadix); } /* ======================================================================= */ |