diff options
author | vng <viktor.govako@gmail.com> | 2013-04-25 18:41:56 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:53:49 +0300 |
commit | cd607c778008b2fd1e3e070563731ffe8812c473 (patch) | |
tree | dff8648effe91fb5160657847f94e848edf03b58 /base | |
parent | 585d9e3ad340345568eaedafc0c3b7fc0db8c6b3 (diff) |
Custom overload for to_string(uint64_t) - speedup feature reading.
Diffstat (limited to 'base')
-rw-r--r-- | base/base_tests/string_utils_test.cpp | 13 | ||||
-rw-r--r-- | base/string_utils.hpp | 80 |
2 files changed, 86 insertions, 7 deletions
diff --git a/base/base_tests/string_utils_test.cpp b/base/base_tests/string_utils_test.cpp index b42d9bf70d..be6d3cbfef 100644 --- a/base/base_tests/string_utils_test.cpp +++ b/base/base_tests/string_utils_test.cpp @@ -218,10 +218,23 @@ UNIT_TEST(to_int64) UNIT_TEST(to_string) { + TEST_EQUAL(strings::to_string(0), "0", ()); + TEST_EQUAL(strings::to_string(-0), "0", ()); + TEST_EQUAL(strings::to_string(1), "1", ()); TEST_EQUAL(strings::to_string(-1), "-1", ()); TEST_EQUAL(strings::to_string(1234567890), "1234567890", ()); + TEST_EQUAL(strings::to_string(-987654321), "-987654321", ()); TEST_EQUAL(strings::to_string(0.56), "0.56", ()); TEST_EQUAL(strings::to_string(-100.2), "-100.2", ()); + + // 6 digits after the comma with rounding - it's a default behavior + TEST_EQUAL(strings::to_string(-0.66666666), "-0.666667", ()); + + TEST_EQUAL(strings::to_string(-1.0E2), "-100", ()); + TEST_EQUAL(strings::to_string(1.0E-2), "0.01", ()); + + TEST_EQUAL(strings::to_string(123456789123456789ULL), "123456789123456789", ()); + TEST_EQUAL(strings::to_string(-987654321987654321LL), "-987654321987654321", ()); } struct FunctorTester diff --git a/base/string_utils.hpp b/base/string_utils.hpp index 474b186cb9..98dd14544e 100644 --- a/base/string_utils.hpp +++ b/base/string_utils.hpp @@ -5,6 +5,7 @@ #include "../std/string.hpp" #include "../std/stdint.hpp" #include "../std/sstream.hpp" +#include "../std/limits.hpp" #include "../3party/utfcpp/source/utf8/unchecked.h" @@ -154,23 +155,88 @@ template <class T, size_t N, class TT> bool IsInArray(T (&arr) [N], TT const & t return false; } +/// @name From string to numeric. +//@{ bool to_int(char const * s, int & i); bool to_uint64(char const * s, uint64_t & i); bool to_int64(char const * s, int64_t & i); bool to_double(char const * s, double & d); -template <class T> -string to_string(T i) +inline bool to_int(string const & s, int & i) { return to_int(s.c_str(), i); } +inline bool to_uint64(string const & s, uint64_t & i) { return to_uint64(s.c_str(), i); } +inline bool to_int64(string const & s, int64_t & i) { return to_int64(s.c_str(), i); } +inline bool to_double(string const & s, double & d) { return to_double(s.c_str(), d); } +//@} + +/// @name From numeric to string. +//@{ +inline string to_string(string const & s) +{ + return s; +} + +inline string to_string(char const * s) +{ + return s; +} + +template <typename T> string to_string(T t) { ostringstream ss; - ss << i; + ss << t; return ss.str(); } -inline bool to_int(string const & s, int & i) { return to_int(s.c_str(), i); } -inline bool to_uint64(string const & s, uint64_t & i) { return to_uint64(s.c_str(), i); } -inline bool to_int64(string const & s, int64_t & i) { return to_int64(s.c_str(), i); } -inline bool to_double(string const & s, double & d) { return to_double(s.c_str(), d); } +namespace impl +{ + +template <typename T> char * to_string_digits(char * buf, T i) +{ + do + { + --buf; + *buf = static_cast<char>(i % 10) + '0'; + i = i / 10; + } while (i != 0); + return buf; +} + +template <typename T> string to_string_signed(T i) +{ + bool const negative = i < 0; + int const sz = numeric_limits<T>::digits10 + 1; + char buf[sz]; + char * end = buf + sz; + char * beg = to_string_digits(end, negative ? -i : i); + if (negative) + { + --beg; + *beg = '-'; + } + return string(beg, end - beg); +} + +template <typename T> string to_string_unsigned(T i) +{ + int const sz = numeric_limits<T>::digits10; + char buf[sz]; + char * end = buf + sz; + char * beg = to_string_digits(end, i); + return string(beg, end - beg); +} + +} + +inline string to_string(int64_t i) +{ + return impl::to_string_signed(i); +} + +inline string to_string(uint64_t i) +{ + return impl::to_string_unsigned(i); +} +//@} /* template <typename ItT, typename DelimiterT> |