From fcb027409d823006dd586235a73e13685d1ed529 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 12 Apr 2017 22:20:33 +0100 Subject: [PATCH] Add more tests and static asserts and fix the build. --- include/duckhandy/lexical_cast.hpp | 20 +++++++------ test/unit/lexical_cast_test.cpp | 46 +++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/include/duckhandy/lexical_cast.hpp b/include/duckhandy/lexical_cast.hpp index af83db2..a8d8e34 100644 --- a/include/duckhandy/lexical_cast.hpp +++ b/include/duckhandy/lexical_cast.hpp @@ -24,6 +24,7 @@ #include "sprout/math/log10.hpp" #include "sprout/math/log2.hpp" #include "sprout/math/pow.hpp" +#include "sprout/math/abs.hpp" #include #include #include @@ -96,12 +97,13 @@ namespace dhandy { inline T string_to_int (const F& parFrom) { T retval(0); T mul(1); - for (auto it = std::rbegin(parFrom), itEND = std::rend(parFrom); it != itEND; ++it) { + const auto sgn = dhandy::customize::char_to_int::sgn(parFrom); + for (auto it = std::rbegin(parFrom), itEND = std::rend(parFrom); it + (sgn < 0 ? 1 : 0) != itEND; ++it) { auto chara = *it; retval += dhandy::customize::char_to_int::make(chara) * mul; mul *= Tag::base; } - return retval * dhandy::customize::char_to_int::sgn(parFrom); + return retval * sgn; }; template @@ -114,8 +116,8 @@ namespace dhandy { static std::size_t count_digits ( T parValue ) a_pure; static typename std::make_unsigned::type make_unsigned ( T parValue ) a_pure; - static constexpr std::size_t count_digits_bt (std::size_t parNum) { - return (parNum == 0 ? 0 : static_cast(sprout::log10(static_cast(parNum)) / sprout::log10(static_cast(base)))) + 1; + static constexpr std::size_t count_digits_bt (T parNum) { + return (parNum == 0 ? 0 : static_cast(sprout::log10(sprout::abs(static_cast(parNum))) / sprout::log10(static_cast(base)))) + 1; } }; } //namespace implem @@ -135,8 +137,8 @@ namespace dhandy { static std::size_t count_digits (T parValue) a_pure; static typename std::make_unsigned::type make_unsigned ( T parValue ) a_pure; - static constexpr std::size_t count_digits_bt (std::size_t parNum) { - return (parNum == 0 ? 0 : static_cast(sprout::log10(static_cast(parNum)))) + 1 + (std::numeric_limits::is_signed ? 1 : 0); + static constexpr std::size_t count_digits_bt (T parNum) { + return (parNum == 0 ? 0 : static_cast(sprout::log10(sprout::abs(static_cast(parNum))))) + 1 + (std::numeric_limits::is_signed ? 1 : 0); } }; @@ -155,8 +157,8 @@ namespace dhandy { static std::size_t count_digits ( T parValue ) a_pure; static typename std::make_unsigned::type make_unsigned ( T parValue ) a_pure; - static constexpr std::size_t count_digits_bt (std::size_t parNum) { - return (parNum == 0 ? 0 : static_cast(sprout::log2(static_cast(parNum)))) + 1; + static constexpr std::size_t count_digits_bt (T parNum) { + return (parNum == 0 ? 0 : static_cast(sprout::log2(sprout::abs(static_cast(parNum))))) + 1; } }; @@ -297,7 +299,7 @@ namespace dhandy { template static T sgn (const Container& parString) { - return static_cast(std::numeric_limits::is_signed and parString.begin() != parString.end() and *parString.begin() == '-' ? -1 : 1); + return static_cast(std::numeric_limits::is_signed and std::begin(parString) != std::end(parString) and *std::begin(parString) == '-' ? -1 : 1); } }; } //namespace customize diff --git a/test/unit/lexical_cast_test.cpp b/test/unit/lexical_cast_test.cpp index a24370c..98dc0b6 100644 --- a/test/unit/lexical_cast_test.cpp +++ b/test/unit/lexical_cast_test.cpp @@ -19,9 +19,47 @@ #include "duckhandy/lexical_cast.hpp" #include #include +#include +#include + +template (C==E)> +struct CountDigitsDebugger { static constexpr const bool value = true; }; +template +struct CountDigitsDebugger {}; TEST_CASE ("Check string to int conversions", "[s2i][lexical_cast]") { using dhandy::lexical_cast; + using dhandy::tags::dec; + using dhandy::tags::hex; + using dhandy::tags::bin; + + static_assert(CountDigitsDebugger::count_digits_bt(0), 1>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(1), 1>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(2), 2>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(3), 2>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(4), 3>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(5), 3>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(6), 3>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(7), 3>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(8), 4>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(9), 4>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(255), 8>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(256), 9>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(255), 8>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(256), 9>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(255), 8>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(256), 9>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(255), 8>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(255), 8>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(-1), 2>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(-2), 2>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(-10), 3>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(-99), 3>::value, "Wrong digits count"); + static_assert(static_cast(sprout::log10(sprout::abs(-10000000.0))) == 7, "Wrong log10"); + static_assert(CountDigitsDebugger::count_digits_bt(-10000000), 9>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(-123456789), 10>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(INT_MAX), 11>::value, "Wrong digits count"); + static_assert(CountDigitsDebugger::count_digits_bt(INT_MIN), 11>::value, "Wrong digits count"); CHECK(lexical_cast(std::string("0")) == 0); CHECK(lexical_cast(std::string("1")) == 1); @@ -33,10 +71,10 @@ TEST_CASE ("Check string to int conversions", "[s2i][lexical_cast]") { CHECK(lexical_cast(std::string("513")) == 513); CHECK(lexical_cast(std::string("15000")) == 15000); - CHECK(lexical_cast(std::string("-1")) == -1); - CHECK(lexical_cast(std::string("-2")) == -2); - CHECK(lexical_cast(std::string("-10")) == -10); - CHECK(lexical_cast(std::string("-100000")) == -100000); + CHECK(lexical_cast(std::string("-1")) == -1); + CHECK(lexical_cast(std::string("-2")) == -2); + CHECK(lexical_cast(std::string("-10")) == -10); + CHECK(lexical_cast(std::string("-100000")) == -100000); } TEST_CASE ("Check int to string conversions", "[i2s][lexical_cast]") {