1
0
Fork 0
mirror of https://github.com/KingDuckZ/dindexer.git synced 2024-11-29 01:33:46 +00:00

Fix sporadic failure in lexical_cast.

This commit is contained in:
King_DuckZ 2016-07-11 16:45:24 +01:00
parent 016f357704
commit e70b137002
2 changed files with 44 additions and 6 deletions

View file

@ -161,17 +161,19 @@ namespace dinhelp {
template <typename T> template <typename T>
template <std::size_t... Powers, std::size_t... Digits> template <std::size_t... Powers, std::size_t... Digits>
std::size_t dec<T>::count_digits_implem (T parValue, dinhelp::bt::index_seq<Powers...>, dinhelp::bt::index_seq<Digits...>) { std::size_t dec<T>::count_digits_implem (T parValue, dinhelp::bt::index_seq<Powers...>, dinhelp::bt::index_seq<Digits...>) {
static T powers[] = { 0, static_cast<T>(dinhelp::implem::power<10, Powers + 1>::value)... }; typedef typename std::make_unsigned<T>::type UT;
static std::size_t maxdigits[] = { count_digits_bt(static_cast<std::size_t>(::pow(2.0, Digits)))... }; static constexpr UT powers[] = { 0, static_cast<UT>(dinhelp::implem::power<10, Powers + 1>::value)... };
const auto bits = sizeof(parValue) * CHAR_BIT - dinhelp::implem::count_leading_zeroes<T>(parValue); static constexpr std::size_t maxdigits[] = { count_digits_bt(static_cast<std::size_t>(::pow(2.0, Digits))) - (std::numeric_limits<T>::is_signed ? 1 : 0)... };
return (parValue < powers[maxdigits[bits] - 1] ? maxdigits[bits] - 1 : maxdigits[bits]) + dinhelp::implem::is_negative<T>::check(parValue); const auto bits = sizeof(parValue) * CHAR_BIT - dinhelp::implem::count_leading_zeroes<T>(dinhelp::implem::abs(parValue));
static_assert(std::is_same<UT, decltype(dinhelp::implem::abs(parValue))>::value, "Unexpected type");
return (dinhelp::implem::abs(parValue) < powers[maxdigits[bits] - 1] ? maxdigits[bits] - 1 : maxdigits[bits]) + dinhelp::implem::is_negative<T>::check(parValue);
} }
template <typename T> template <typename T>
std::size_t dec<T>::count_digits (T parValue) { std::size_t dec<T>::count_digits (T parValue) {
return count_digits_implem( return count_digits_implem(
parValue, parValue,
dinhelp::bt::index_range<0, count_digits_bt(std::numeric_limits<T>::max()) + 1>(), dinhelp::bt::index_range<0, count_digits_bt(std::numeric_limits<T>::max()) - (std::numeric_limits<T>::is_signed ? 1 : 0) - 1>(),
dinhelp::bt::index_range<0, CHAR_BIT * sizeof(T) + 1>() dinhelp::bt::index_range<0, CHAR_BIT * sizeof(T) + 1>()
); );
} }
@ -209,7 +211,7 @@ namespace dinhelp {
template <typename T> template <typename T>
inline int count_leading_zeroes (typename std::enable_if<std::numeric_limits<T>::is_signed, T>::type parValue) { inline int count_leading_zeroes (typename std::enable_if<std::numeric_limits<T>::is_signed, T>::type parValue) {
return count_leading_zeroes<decltype(abs(parValue))>(abs(parValue)); return count_leading_zeroes<decltype(dinhelp::implem::abs(parValue))>(dinhelp::implem::abs(parValue));
} }
template <typename T> template <typename T>

View file

@ -126,4 +126,40 @@ TEST(helpers, lexical_cast) {
const auto bin_str = lexical_cast<std::string, bin>(value); const auto bin_str = lexical_cast<std::string, bin>(value);
EXPECT_EQ("11111111111111111111101010001000", bin_str); EXPECT_EQ("11111111111111111111101010001000", bin_str);
} }
{
const int32_t value = 515;
const auto hex_str = lexical_cast<std::string, hex>(value);
EXPECT_EQ("203", hex_str);
const auto dec_str = lexical_cast<std::string, dec>(value);
EXPECT_EQ("515", dec_str);
const auto bin_str = lexical_cast<std::string, bin>(value);
EXPECT_EQ("1000000011", bin_str);
}
{
const int64_t value = 515;
const auto hex_str = lexical_cast<std::string, hex>(value);
EXPECT_EQ("203", hex_str);
const auto dec_str = lexical_cast<std::string, dec>(value);
EXPECT_EQ("515", dec_str);
const auto bin_str = lexical_cast<std::string, bin>(value);
EXPECT_EQ("1000000011", bin_str);
}
{
const uint32_t value = 515;
const auto hex_str = lexical_cast<std::string, hex>(value);
EXPECT_EQ("203", hex_str);
const auto dec_str = lexical_cast<std::string, dec>(value);
EXPECT_EQ("515", dec_str);
const auto bin_str = lexical_cast<std::string, bin>(value);
EXPECT_EQ("1000000011", bin_str);
}
{
const uint64_t value = 515;
const auto hex_str = lexical_cast<std::string, hex>(value);
EXPECT_EQ("203", hex_str);
const auto dec_str = lexical_cast<std::string, dec>(value);
EXPECT_EQ("515", dec_str);
const auto bin_str = lexical_cast<std::string, bin>(value);
EXPECT_EQ("1000000011", bin_str);
}
} }