From 5baf5d3daeece33e0767a1c8fbd1b85daa84f45e Mon Sep 17 00:00:00 2001 From: EnilPajic Date: Fri, 26 Jun 2020 21:25:39 +0200 Subject: [PATCH 1/3] Fixed potential bug with -MINIMUM_VALUE Original code had something like `N < 0 ? -N : N` which could fail if `N` has minimum value of appropriate type. For example, in original code this could fail: ```cpp const long long int LL_MIN = std::numeric_limits::min(); //probably: -9223372036854775808 static const char *number = to_string; ``` Also note that this code relies on "modulo on negative first operands" which was implementation defined in C++03 and before, but with C++11 and later it is defined by standard (see `ISO14882:2011(e)`), and this code anyway targets C++17 so we're safe here. --- to_string.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/to_string.hpp b/to_string.hpp index 116cdd8..6117258 100644 --- a/to_string.hpp +++ b/to_string.hpp @@ -23,7 +23,7 @@ struct to_string_t { // fits to the number perfectly. char buf[([] { unsigned int len = N >= 0 ? 1 : 2; - for (auto n = N < 0 ? -N : N; n; len++, n /= base); + for (auto n = N; n; len++, n /= base); return len; }())]; @@ -33,8 +33,8 @@ struct to_string_t { constexpr to_string_t() { auto ptr = buf + sizeof(buf) / sizeof(buf[0]); *--ptr = '\0'; - for (auto n = N < 0 ? -N : N; n; n /= base) - *--ptr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n % base]; + for (auto n = N; n; n /= base) + *--ptr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[(N < 0 ? -1 : 1) * (n % base)]; if (N < 0) *--ptr = '-'; } From 6e7939000f22dbc955d5aa7feff4db5541205e98 Mon Sep 17 00:00:00 2001 From: clyne Date: Sat, 27 Jun 2020 19:08:48 -0400 Subject: [PATCH 2/3] Change base from unsigned to signed --- to_string.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/to_string.hpp b/to_string.hpp index bf724cd..e7eef93 100644 --- a/to_string.hpp +++ b/to_string.hpp @@ -15,7 +15,7 @@ * @tparam N Number to convert * @tparam base Desired base, can be from 2 to 36 */ -template, int> = 0, std::enable_if_t<(base > 1 && base < 37), int> = 0> class to_string_t { @@ -35,7 +35,7 @@ class to_string_t { auto ptr = end(); *--ptr = '\0'; if (N != 0) { - for (auto n = N < 0 ? -N : N; n; n /= base) + for (auto n = N; n; n /= base) *--ptr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[(N < 0 ? -1 : 1) * (n % base)]; if (N < 0) *--ptr = '-'; From 56692725154d1e4ff2ef4786107cfda81c44b192 Mon Sep 17 00:00:00 2001 From: clyne Date: Sat, 27 Jun 2020 19:13:18 -0400 Subject: [PATCH 3/3] Changed other base instance to signed --- to_string.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/to_string.hpp b/to_string.hpp index e7eef93..eb363f0 100644 --- a/to_string.hpp +++ b/to_string.hpp @@ -68,7 +68,7 @@ class to_string_t { /** * Simplifies use of `to_string_t` from `to_string_t()` to `to_string`. */ -template +template constexpr to_string_t to_string; #endif // TCSULLIVAN_TO_STRING_HPP_