From dc68ae3771f36faa3413c65e13243e053ace19ec Mon Sep 17 00:00:00 2001 From: Maxim Pimenov Date: Wed, 15 Jul 2020 00:40:09 +0300 Subject: [PATCH] [base] Add to_uint32 and to_int32. --- base/base_tests/string_utils_test.cpp | 78 +++++++++++++++++++++++++++ base/string_utils.cpp | 28 ++++++++++ base/string_utils.hpp | 11 ++++ 3 files changed, 117 insertions(+) diff --git a/base/base_tests/string_utils_test.cpp b/base/base_tests/string_utils_test.cpp index aee8ed316f..687958fc3d 100644 --- a/base/base_tests/string_utils_test.cpp +++ b/base/base_tests/string_utils_test.cpp @@ -307,6 +307,43 @@ UNIT_TEST(to_uint64) s = "labuda"; TEST(!strings::to_uint64(s, i), ()); + + s = "-1"; + TEST(strings::to_uint64(s, i), ()); + TEST_EQUAL(18446744073709551615ULL, i, ()); +} + +UNIT_TEST(to_uint32) +{ + uint32_t i; + std::string s; + + s = ""; + TEST(!strings::to_uint32(s, i), ()); + + s = "0"; + TEST(strings::to_uint32(s, i), ()); + TEST_EQUAL(0, i, ()); + + s = "123456789101112"; + TEST(!strings::to_uint32(s, i), ()); + + s = "AF"; + TEST(strings::to_uint32(s, i, 16), ()); + TEST_EQUAL(175, i, ()); + + s = "labuda"; + TEST(!strings::to_uint32(s, i), ()); + + s = "-1"; + TEST(!strings::to_uint32(s, i), ()); + + s = "4294967295"; + TEST(strings::to_uint32(s, i), ()); + TEST_EQUAL(4294967295, i, ()); + + s = "4294967296"; + TEST(!strings::to_uint32(s, i), ()); } UNIT_TEST(to_int64) @@ -330,6 +367,47 @@ UNIT_TEST(to_int64) TEST(!strings::to_int64(s, i), ()); } +UNIT_TEST(to_int32) +{ + int32_t i; + std::string s; + + s = "-24567"; + TEST(strings::to_int32(s, i), ()); + TEST_EQUAL(-24567, i, ()); + + s = "0"; + TEST(strings::to_int32(s, i), ()); + TEST_EQUAL(0, i, ()); + + s = "12345678911212"; + TEST(!strings::to_int32(s, i), ()); + + s = "labuda"; + TEST(!strings::to_int32(s, i), ()); + + s = "-1"; + TEST(strings::to_int32(s, i), ()); + TEST_EQUAL(-1, i, ()); + + s = "4294967295"; + TEST(!strings::to_int32(s, i), ()); + + s = "2147483647"; + TEST(strings::to_int32(s, i), ()); + TEST_EQUAL(2147483647, i, ()); + + s = "2147483648"; + TEST(!strings::to_int32(s, i), ()); + + s = "-2147483648"; + TEST(strings::to_int32(s, i), ()); + TEST_EQUAL(-2147483648, i, ()); + + s = "-2147483649"; + TEST(!strings::to_int32(s, i), ()); +} + UNIT_TEST(to_any) { { diff --git a/base/string_utils.cpp b/base/string_utils.cpp index e5276666f0..2bae33cbfe 100644 --- a/base/string_utils.cpp +++ b/base/string_utils.cpp @@ -81,6 +81,34 @@ UniChar LastUniChar(std::string const & s) return *iter; } +bool to_uint32(char const * start, uint32_t & i, int base) +{ + uint64_t num = 0; + if (!to_uint64(start, num, base)) + return false; + + if (num > static_cast(std::numeric_limits::max())) + return false; + + i = static_cast(num); + return true; +} + +bool to_int32(char const * start, int32_t & i) +{ + int64_t num = 0; + if (!to_int64(start, num)) + return false; + + if (num > static_cast(std::numeric_limits::max())) + return false; + if (num < static_cast(std::numeric_limits::min())) + return false; + + i = static_cast(num); + return true; +} + bool to_size_t(char const * start, size_t & i, int base) { uint64_t num = 0; diff --git a/base/string_utils.hpp b/base/string_utils.hpp index 94b6be8d1e..04611b7538 100644 --- a/base/string_utils.hpp +++ b/base/string_utils.hpp @@ -458,6 +458,9 @@ WARN_UNUSED_RESULT inline bool to_int64(char const * s, int64_t & i) return internal::ToInteger(s, i); } +// Unlike the 64-bit version, to_uint32 will not convert negative values. +WARN_UNUSED_RESULT bool to_uint32(char const * s, uint32_t & i, int base = 10); +WARN_UNUSED_RESULT bool to_int32(char const * s, int32_t & i); WARN_UNUSED_RESULT bool to_size_t(char const * s, size_t & i, int base = 10); WARN_UNUSED_RESULT bool to_float(char const * s, float & f); WARN_UNUSED_RESULT bool to_double(char const * s, double & d); @@ -487,6 +490,14 @@ WARN_UNUSED_RESULT inline bool to_int64(std::string const & s, int64_t & i) { return to_int64(s.c_str(), i); } +WARN_UNUSED_RESULT inline bool to_uint32(std::string const & s, uint32_t & i, int base = 10) +{ + return to_uint32(s.c_str(), i, base); +} +WARN_UNUSED_RESULT inline bool to_int32(std::string const & s, int32_t & i) +{ + return to_int32(s.c_str(), i); +} WARN_UNUSED_RESULT inline bool to_size_t(std::string const & s, size_t & i) { return to_size_t(s.c_str(), i);