Add more tests and static asserts and fix the build.

This commit is contained in:
King_DuckZ 2017-04-12 22:20:33 +01:00
parent b782ebd53c
commit fcb027409d
2 changed files with 53 additions and 13 deletions

View file

@ -24,6 +24,7 @@
#include "sprout/math/log10.hpp" #include "sprout/math/log10.hpp"
#include "sprout/math/log2.hpp" #include "sprout/math/log2.hpp"
#include "sprout/math/pow.hpp" #include "sprout/math/pow.hpp"
#include "sprout/math/abs.hpp"
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <limits> #include <limits>
@ -96,12 +97,13 @@ namespace dhandy {
inline T string_to_int (const F& parFrom) { inline T string_to_int (const F& parFrom) {
T retval(0); T retval(0);
T mul(1); T mul(1);
for (auto it = std::rbegin(parFrom), itEND = std::rend(parFrom); it != itEND; ++it) { const auto sgn = dhandy::customize::char_to_int<typename F::value_type, T>::sgn(parFrom);
for (auto it = std::rbegin(parFrom), itEND = std::rend(parFrom); it + (sgn < 0 ? 1 : 0) != itEND; ++it) {
auto chara = *it; auto chara = *it;
retval += dhandy::customize::char_to_int<decltype(chara), T>::make(chara) * mul; retval += dhandy::customize::char_to_int<decltype(chara), T>::make(chara) * mul;
mul *= Tag<T>::base; mul *= Tag<T>::base;
} }
return retval * dhandy::customize::char_to_int<typename F::value_type, T>::sgn(parFrom); return retval * sgn;
}; };
template <typename T, bool LowerCase> template <typename T, bool LowerCase>
@ -114,8 +116,8 @@ namespace dhandy {
static std::size_t count_digits ( T parValue ) a_pure; static std::size_t count_digits ( T parValue ) a_pure;
static typename std::make_unsigned<T>::type make_unsigned ( T parValue ) a_pure; static typename std::make_unsigned<T>::type make_unsigned ( T parValue ) a_pure;
static constexpr std::size_t count_digits_bt (std::size_t parNum) { static constexpr std::size_t count_digits_bt (T parNum) {
return (parNum == 0 ? 0 : static_cast<std::size_t>(sprout::log10(static_cast<double>(parNum)) / sprout::log10(static_cast<double>(base)))) + 1; return (parNum == 0 ? 0 : static_cast<std::size_t>(sprout::log10(sprout::abs(static_cast<long double>(parNum))) / sprout::log10(static_cast<double>(base)))) + 1;
} }
}; };
} //namespace implem } //namespace implem
@ -135,8 +137,8 @@ namespace dhandy {
static std::size_t count_digits (T parValue) a_pure; static std::size_t count_digits (T parValue) a_pure;
static typename std::make_unsigned<T>::type make_unsigned ( T parValue ) a_pure; static typename std::make_unsigned<T>::type make_unsigned ( T parValue ) a_pure;
static constexpr std::size_t count_digits_bt (std::size_t parNum) { static constexpr std::size_t count_digits_bt (T parNum) {
return (parNum == 0 ? 0 : static_cast<std::size_t>(sprout::log10(static_cast<double>(parNum)))) + 1 + (std::numeric_limits<T>::is_signed ? 1 : 0); return (parNum == 0 ? 0 : static_cast<std::size_t>(sprout::log10(sprout::abs(static_cast<long double>(parNum))))) + 1 + (std::numeric_limits<T>::is_signed ? 1 : 0);
} }
}; };
@ -155,8 +157,8 @@ namespace dhandy {
static std::size_t count_digits ( T parValue ) a_pure; static std::size_t count_digits ( T parValue ) a_pure;
static typename std::make_unsigned<T>::type make_unsigned ( T parValue ) a_pure; static typename std::make_unsigned<T>::type make_unsigned ( T parValue ) a_pure;
static constexpr std::size_t count_digits_bt (std::size_t parNum) { static constexpr std::size_t count_digits_bt (T parNum) {
return (parNum == 0 ? 0 : static_cast<std::size_t>(sprout::log2(static_cast<double>(parNum)))) + 1; return (parNum == 0 ? 0 : static_cast<std::size_t>(sprout::log2(sprout::abs(static_cast<long double>(parNum))))) + 1;
} }
}; };
@ -297,7 +299,7 @@ namespace dhandy {
template <typename Container> template <typename Container>
static T sgn (const Container& parString) { static T sgn (const Container& parString) {
return static_cast<T>(std::numeric_limits<T>::is_signed and parString.begin() != parString.end() and *parString.begin() == '-' ? -1 : 1); return static_cast<T>(std::numeric_limits<T>::is_signed and std::begin(parString) != std::end(parString) and *std::begin(parString) == '-' ? -1 : 1);
} }
}; };
} //namespace customize } //namespace customize

View file

@ -19,9 +19,47 @@
#include "duckhandy/lexical_cast.hpp" #include "duckhandy/lexical_cast.hpp"
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <cstddef>
#include <climits>
template <std::size_t C, std::size_t E, bool B=static_cast<bool>(C==E)>
struct CountDigitsDebugger { static constexpr const bool value = true; };
template <std::size_t C, std::size_t E>
struct CountDigitsDebugger<C, E, false> {};
TEST_CASE ("Check string to int conversions", "[s2i][lexical_cast]") { TEST_CASE ("Check string to int conversions", "[s2i][lexical_cast]") {
using dhandy::lexical_cast; using dhandy::lexical_cast;
using dhandy::tags::dec;
using dhandy::tags::hex;
using dhandy::tags::bin;
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(0), 1>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(1), 1>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(2), 2>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(3), 2>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(4), 3>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(5), 3>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(6), 3>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(7), 3>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(8), 4>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(9), 4>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(255), 8>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int32_t>::count_digits_bt(256), 9>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<uint32_t>::count_digits_bt(255), 8>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<uint32_t>::count_digits_bt(256), 9>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<uint16_t>::count_digits_bt(255), 8>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<uint16_t>::count_digits_bt(256), 9>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<uint8_t>::count_digits_bt(255), 8>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<bin<int64_t>::count_digits_bt(255), 8>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<dec<int64_t>::count_digits_bt(-1), 2>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<dec<int64_t>::count_digits_bt(-2), 2>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<dec<int64_t>::count_digits_bt(-10), 3>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<dec<int64_t>::count_digits_bt(-99), 3>::value, "Wrong digits count");
static_assert(static_cast<std::size_t>(sprout::log10(sprout::abs(-10000000.0))) == 7, "Wrong log10");
static_assert(CountDigitsDebugger<dec<int64_t>::count_digits_bt(-10000000), 9>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<dec<int64_t>::count_digits_bt(-123456789), 10>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<dec<int32_t>::count_digits_bt(INT_MAX), 11>::value, "Wrong digits count");
static_assert(CountDigitsDebugger<dec<int32_t>::count_digits_bt(INT_MIN), 11>::value, "Wrong digits count");
CHECK(lexical_cast<uint16_t>(std::string("0")) == 0); CHECK(lexical_cast<uint16_t>(std::string("0")) == 0);
CHECK(lexical_cast<uint16_t>(std::string("1")) == 1); CHECK(lexical_cast<uint16_t>(std::string("1")) == 1);
@ -33,10 +71,10 @@ TEST_CASE ("Check string to int conversions", "[s2i][lexical_cast]") {
CHECK(lexical_cast<uint16_t>(std::string("513")) == 513); CHECK(lexical_cast<uint16_t>(std::string("513")) == 513);
CHECK(lexical_cast<uint16_t>(std::string("15000")) == 15000); CHECK(lexical_cast<uint16_t>(std::string("15000")) == 15000);
CHECK(lexical_cast<uint32_t>(std::string("-1")) == -1); CHECK(lexical_cast<int32_t>(std::string("-1")) == -1);
CHECK(lexical_cast<uint32_t>(std::string("-2")) == -2); CHECK(lexical_cast<int32_t>(std::string("-2")) == -2);
CHECK(lexical_cast<uint32_t>(std::string("-10")) == -10); CHECK(lexical_cast<int32_t>(std::string("-10")) == -10);
CHECK(lexical_cast<uint32_t>(std::string("-100000")) == -100000); CHECK(lexical_cast<int32_t>(std::string("-100000")) == -100000);
} }
TEST_CASE ("Check int to string conversions", "[i2s][lexical_cast]") { TEST_CASE ("Check int to string conversions", "[i2s][lexical_cast]") {