Use parameter instead of assuming 10 numeric digits
This commit is contained in:
parent
199db7640e
commit
420257f578
2 changed files with 31 additions and 12 deletions
|
@ -256,19 +256,19 @@ namespace dhandy {
|
|||
__m128i res = _mm_set1_epi32(0);
|
||||
const __m128i char_0 = _mm_set1_epi32(Tr::FirstDigit);
|
||||
const __m128i char_befo_a = _mm_set1_epi32(Tr::FirstLetter - 1);
|
||||
const __m128i char_past_f = _mm_set1_epi32(Tr::FirstLetter + Base - 10);
|
||||
const __m128i char_past_f = _mm_set1_epi32(Tr::FirstLetter + Base - Tr::DigitCount);
|
||||
std::size_t idx = 0;
|
||||
const std::size_t cap = l bitand -4;
|
||||
do {
|
||||
const __m128i digits = _mm_set_epi32(s[cap - idx - 3 - 1], s[cap - idx - 2 - 1], s[cap - idx - 1 - 1], s[cap - idx - 0 - 1]);
|
||||
__m128i mask = _mm_and_si128(_mm_cmpgt_epi32(digits, char_befo_a), _mm_cmplt_epi32(digits, char_past_f));
|
||||
__m128i offs = _mm_and_si128(mask, _mm_set1_epi32(Tr::FirstLetter - 10));
|
||||
__m128i offs = _mm_and_si128(mask, _mm_set1_epi32(Tr::FirstLetter - Tr::DigitCount));
|
||||
|
||||
if constexpr (HasAltLetterEnum<Tr>::value) {
|
||||
const __m128i char_befo_A = _mm_set1_epi32(g_AltLetterOrZero<Tr> - 1);
|
||||
const __m128i char_past_F = _mm_set1_epi32(g_AltLetterOrZero<Tr> + Base - 10);
|
||||
const __m128i char_past_F = _mm_set1_epi32(g_AltLetterOrZero<Tr> + Base - Tr::DigitCount);
|
||||
const __m128i alt_mask = _mm_and_si128(_mm_cmpgt_epi32(digits, char_befo_A), _mm_cmplt_epi32(digits, char_past_F));
|
||||
const __m128i alt_offs = _mm_and_si128(alt_mask, _mm_set1_epi32(g_AltLetterOrZero<Tr> - 10));
|
||||
const __m128i alt_offs = _mm_and_si128(alt_mask, _mm_set1_epi32(g_AltLetterOrZero<Tr> - Tr::DigitCount));
|
||||
offs = _mm_add_epi32(alt_offs, offs);
|
||||
mask = _mm_or_si128(mask, alt_mask);
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ namespace dhandy {
|
|||
}
|
||||
} //namespace implem
|
||||
|
||||
template <typename C, C FDigit='0', C FLetter='a', C CPlus='+', C CMinus='-', C CNull='\0'>
|
||||
template <typename C, C FDigit='0', C FLetter='a', C CPlus='+', C CMinus='-', C CNull='\0', unsigned int DCount=10>
|
||||
struct ASCIITranslator {
|
||||
typedef C char_type;
|
||||
static const constexpr C FirstDigit = FDigit;
|
||||
|
@ -298,18 +298,19 @@ namespace dhandy {
|
|||
static const constexpr C Plus = CPlus;
|
||||
static const constexpr C Minus = CMinus;
|
||||
static const constexpr C NullChar = CNull;
|
||||
static const constexpr unsigned int DigitCount = DCount;
|
||||
|
||||
static constexpr C to_digit (unsigned int num) {
|
||||
return (num <= 9 ?
|
||||
return (num < DigitCount ?
|
||||
static_cast<C>(num + FirstDigit) :
|
||||
static_cast<C>(num + FirstLetter - 10)
|
||||
static_cast<C>(num + FirstLetter - DigitCount)
|
||||
);
|
||||
}
|
||||
|
||||
static constexpr int from_digit (C dig) {
|
||||
return (dig < FirstLetter ?
|
||||
dig - FirstDigit :
|
||||
dig - FirstLetter + 10
|
||||
dig - FirstLetter + DigitCount
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace {
|
|||
}
|
||||
} //unnamed namespace
|
||||
|
||||
TEST_CASE ("Check int to char array conversions", "[s2i][int_conv]") {
|
||||
TEST_CASE ("Check int to char array conversions", "[i2s][int_conv]") {
|
||||
using dhandy::int_to_ary;
|
||||
using dhandy::bt::string;
|
||||
using dhandy::bt::make_string;
|
||||
|
@ -157,7 +157,7 @@ TEST_CASE ("Check int to char array conversions", "[s2i][int_conv]") {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE ("Check char array to int conversions", "[i2s][int_conv]") {
|
||||
TEST_CASE ("Check char array to int conversions", "[s2i][int_conv]") {
|
||||
AryConversionTestHelper<std::uint32_t, 10>("0", 0, true);
|
||||
AryConversionTestHelper<std::int32_t, 10>("0", 0, true);
|
||||
AryConversionTestHelper<std::int16_t, 10>("0", 0, true);
|
||||
|
@ -200,7 +200,7 @@ TEST_CASE ("Check char array to int conversions", "[i2s][int_conv]") {
|
|||
AryConversionTestHelperIns<std::int32_t, 16>("aAbBc", 0xaabbc, true);
|
||||
}
|
||||
|
||||
TEST_CASE ("Check string_view conversions work as expected", "[i2s][int_conv]") {
|
||||
TEST_CASE ("Check string_view conversions work as expected", "[s2i][int_conv]") {
|
||||
using dhandy::int_conv;
|
||||
using dhandy::int_conv_raw;
|
||||
using std::string_view;
|
||||
|
@ -265,7 +265,7 @@ TEST_CASE ("Check upcase/downcase int to array conversions", "[i2s][int_conv]")
|
|||
CHECK("-256" == int4);
|
||||
}
|
||||
|
||||
TEST_CASE ("Try int conv with non-char", "[i2s][int_conv]") {
|
||||
TEST_CASE ("Try int conv with non-char", "[s2i][int_conv]") {
|
||||
using dhandy::int_to_ary;
|
||||
using dhandy::ASCIITranslator;
|
||||
|
||||
|
@ -273,3 +273,21 @@ TEST_CASE ("Try int conv with non-char", "[i2s][int_conv]") {
|
|||
auto val1 = int_to_ary<int, 10, ASCIITranslator<wchar_t>>(235713).to_string_view();
|
||||
CHECK(exp1 == val1);
|
||||
}
|
||||
|
||||
TEST_CASE ("Check some fancy conversions", "[i2s][int_conv]") {
|
||||
using dhandy::int_to_ary;
|
||||
using std::string;
|
||||
using MyFancyTranslator = dhandy::ASCIITranslator<char, '0', 'a', '+', '-', '\0', 4>;
|
||||
|
||||
string str1 = int_to_ary<int, 10, MyFancyTranslator>(3).to_string();
|
||||
CHECK("3" == str1);
|
||||
|
||||
string str2 = int_to_ary<int, 10, MyFancyTranslator>(5).to_string();
|
||||
CHECK("b" == str2);
|
||||
|
||||
string str3 = int_to_ary<int, 10, MyFancyTranslator>(11).to_string();
|
||||
CHECK("11" == str3);
|
||||
|
||||
string str4 = int_to_ary<int, 10, MyFancyTranslator>(537).to_string();
|
||||
CHECK("b3d" == str4);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue