From 1b14ec50568549b060a0bdb27463d9ea6aa56605 Mon Sep 17 00:00:00 2001 From: Marco Bubke <marco.bubke@qt.io> Date: Mon, 31 Jul 2017 16:08:35 +0200 Subject: [PATCH] Utils: Add number to string conversion We use std::to_string except for integer where we want a low overhead solution. Change-Id: I16ce7d575d83ff56e61a5038aa7f9a1febfaf34f Reviewed-by: Tim Jenssen <tim.jenssen@qt.io> Reviewed-by: Orgad Shaneh <orgads@gmail.com> --- src/libs/utils/smallstring.h | 69 ++++++++++++++++++++++++ tests/unit/unittest/smallstring-test.cpp | 13 +++++ 2 files changed, 82 insertions(+) diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h index eb301586915..3614bee0a83 100644 --- a/src/libs/utils/smallstring.h +++ b/src/libs/utils/smallstring.h @@ -547,6 +547,30 @@ public: return joinedString; } + static + BasicSmallString number(int number) + { + char buffer[12]; + std::size_t size = itoa(number, buffer, 10); + + return BasicSmallString(buffer, size); + } + + static + BasicSmallString number(long long int number) + { + char buffer[22]; + std::size_t size = itoa(number, buffer, 10); + + return BasicSmallString(buffer, size); + } + + static + BasicSmallString number(double number) + { + return std::to_string(number); + } + char &operator[](std::size_t index) { return *(data() + index); @@ -849,6 +873,51 @@ private: m_data.allocated.data.size = size; } + static + std::size_t itoa(long long int number, char* string, uint base) + { + using llint = long long int; + using lluint = long long unsigned int; + std::size_t size = 0; + bool isNegative = false; + lluint unsignedNumber = 0; + + if (number == 0) + { + string[size] = '0'; + string[++size] = '\0'; + + return size; + } + + if (number < 0 && base == 10) + { + isNegative = true; + if (number == std::numeric_limits<llint>::min()) + unsignedNumber = lluint(std::numeric_limits<llint>::max()) + 1; + else + unsignedNumber = lluint(-number); + } else { + unsignedNumber = lluint(number); + } + + while (unsignedNumber != 0) + { + int remainder = int(unsignedNumber % base); + string[size++] = (remainder > 9) ? char((remainder - 10) + 'a') : char(remainder + '0'); + unsignedNumber /= base; + } + + if (isNegative) + string[size++] = '-'; + + string[size] = '\0'; + + std::reverse(string, string+size); + + return size; + } + private: Internal::StringDataLayout<Size> m_data; }; diff --git a/tests/unit/unittest/smallstring-test.cpp b/tests/unit/unittest/smallstring-test.cpp index 29c40635421..e555a8fabd1 100644 --- a/tests/unit/unittest/smallstring-test.cpp +++ b/tests/unit/unittest/smallstring-test.cpp @@ -1256,3 +1256,16 @@ TEST(SmallString, InitializerListNullTerminated) ASSERT_THAT(end, '\0'); } + +TEST(SmallString, NumberToString) +{ + ASSERT_THAT(SmallString::number(-0), "0"); + ASSERT_THAT(SmallString::number(1), "1"); + ASSERT_THAT(SmallString::number(-1), "-1"); + ASSERT_THAT(SmallString::number(std::numeric_limits<int>::max()), "2147483647"); + ASSERT_THAT(SmallString::number(std::numeric_limits<int>::min()), "-2147483648"); + ASSERT_THAT(SmallString::number(std::numeric_limits<long long int>::max()), "9223372036854775807"); + ASSERT_THAT(SmallString::number(std::numeric_limits<long long int>::min()), "-9223372036854775808"); + ASSERT_THAT(SmallString::number(1.2), "1.200000"); + ASSERT_THAT(SmallString::number(-1.2), "-1.200000"); +} -- GitLab