Test if conversion is using the sse when possible

This commit is contained in:
King_DuckZ 2021-04-22 13:44:49 +02:00
parent 13bd166827
commit 1f44e74465
2 changed files with 40 additions and 33 deletions

View file

@ -23,6 +23,7 @@
#include <sprout/math/abs.hpp> #include <sprout/math/abs.hpp>
#include <sprout/math/ceil.hpp> #include <sprout/math/ceil.hpp>
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <array> #include <array>
#include <limits> #include <limits>
#include <emmintrin.h> #include <emmintrin.h>
@ -176,6 +177,8 @@ namespace dhandy {
template <typename I, unsigned int Base, typename Tr, bool Constexpr, typename=void> template <typename I, unsigned int Base, typename Tr, bool Constexpr, typename=void>
struct AryConversion { struct AryConversion {
constexpr static const bool is_sse = false;
template <typename C> template <typename C>
constexpr static I from_ary (const C* beg, const C* end) { constexpr static I from_ary (const C* beg, const C* end) {
I retval = 0; I retval = 0;
@ -196,12 +199,14 @@ namespace dhandy {
}; };
template <typename I, unsigned int Base, typename Tr> template <typename I, unsigned int Base, typename Tr>
struct AryConversion<I, Base, Tr, false, typename std::enable_if<Tr::BehavesLikeASCII and std::is_integral<I>::value and not std::is_same<I, bool>::value and sizeof(I) <= sizeof(uint32_t)>::type> { struct AryConversion<I, Base, Tr, false, typename std::enable_if<Tr::BehavesLikeASCII and std::is_integral<I>::value and not std::is_same<I, bool>::value and sizeof(I) <= sizeof(std::uint32_t)>::type> {
constexpr static const bool is_sse = true;
template <typename C> static I from_ary (C* beg, C* end) { return to_integer_sse<I, C, Base, Tr>(beg, end - beg); } template <typename C> static I from_ary (C* beg, C* end) { return to_integer_sse<I, C, Base, Tr>(beg, end - beg); }
}; };
template <unsigned int Base, typename Tr, bool Constexpr> template <unsigned int Base, typename Tr, bool Constexpr>
struct AryConversion<bool, Base, Tr, Constexpr> { struct AryConversion<bool, Base, Tr, Constexpr> {
constexpr static const bool is_sse = false;
template <typename C> constexpr static bool from_ary (C* beg, C* end) { template <typename C> constexpr static bool from_ary (C* beg, C* end) {
if (end == beg) if (end == beg)
return false; return false;

View file

@ -30,14 +30,16 @@ template <typename T> using int_info_2 = dhandy::implem::int_info<T, 2>;
namespace { namespace {
template <typename T, unsigned int Base> template <typename T, unsigned int Base>
void AryConversionTestHelper (const std::string_view& s, T expected) { void AryConversionTestHelper (const std::string_view& s, T expected, bool expect_sse) {
using AryConversion = dhandy::implem::AryConversion<T, Base, dhandy::ASCIITranslator<char>, false>; using AryConversion = dhandy::implem::AryConversion<T, Base, dhandy::ASCIITranslator<char>, false>;
CHECK(AryConversion::is_sse == expect_sse);
CHECK(AryConversion::from_ary(s.data(), s.data() + s.size()) == expected); CHECK(AryConversion::from_ary(s.data(), s.data() + s.size()) == expected);
} }
template <typename T, unsigned int Base> template <typename T, unsigned int Base>
void AryConversionTestHelperUp (const std::string_view& s, T expected) { void AryConversionTestHelperUp (const std::string_view& s, T expected, bool expect_sse) {
using AryConversion = dhandy::implem::AryConversion<T, Base, dhandy::ASCIITranslatorUpcase<char>, false>; using AryConversion = dhandy::implem::AryConversion<T, Base, dhandy::ASCIITranslatorUpcase<char>, false>;
CHECK(AryConversion::is_sse == expect_sse);
CHECK(AryConversion::from_ary(s.data(), s.data() + s.size()) == expected); CHECK(AryConversion::from_ary(s.data(), s.data() + s.size()) == expected);
} }
} //unnamed namespace } //unnamed namespace
@ -137,35 +139,35 @@ 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", "[i2s][int_conv]") {
AryConversionTestHelper<uint32_t, 10>("0", 0); AryConversionTestHelper<std::uint32_t, 10>("0", 0, true);
AryConversionTestHelper<int32_t, 10>("0", 0); AryConversionTestHelper<std::int32_t, 10>("0", 0, true);
AryConversionTestHelper<int16_t, 10>("0", 0); AryConversionTestHelper<std::int16_t, 10>("0", 0, true);
AryConversionTestHelper<int16_t, 16>("ff", 0xff); AryConversionTestHelper<std::int16_t, 16>("ff", 0xff, true);
AryConversionTestHelper<uint8_t, 16>("ff", 0xff); AryConversionTestHelper<std::uint8_t, 16>("ff", 0xff, true);
AryConversionTestHelper<uint32_t, 36>("rs", 1000); AryConversionTestHelper<std::uint32_t, 36>("rs", 1000, true);
AryConversionTestHelper<uint16_t, 8>("20", 16); AryConversionTestHelper<std::uint16_t, 8>("20", 16, true);
AryConversionTestHelper<int32_t, 10>("1", 1); AryConversionTestHelper<std::int32_t, 10>("1", 1, true);
AryConversionTestHelper<int32_t, 10>("10", 10); AryConversionTestHelper<std::int32_t, 10>("10", 10, true);
AryConversionTestHelper<int32_t, 10>("100", 100); AryConversionTestHelper<std::int32_t, 10>("100", 100, true);
AryConversionTestHelper<int32_t, 10>("999", 999); AryConversionTestHelper<std::int32_t, 10>("999", 999, true);
AryConversionTestHelper<int32_t, 10>("1000", 1000); AryConversionTestHelper<std::int32_t, 10>("1000", 1000, true);
AryConversionTestHelper<int32_t, 10>("1001", 1001); AryConversionTestHelper<std::int32_t, 10>("1001", 1001, true);
AryConversionTestHelper<int32_t, 10>("12345", 12345); AryConversionTestHelper<std::int32_t, 10>("12345", 12345, true);
AryConversionTestHelper<int32_t, 10>("123456", 123456); AryConversionTestHelper<std::int32_t, 10>("123456", 123456, true);
AryConversionTestHelper<int32_t, 10>("1234567", 1234567); AryConversionTestHelper<std::int32_t, 10>("1234567", 1234567, true);
AryConversionTestHelper<int32_t, 10>("12345678", 12345678); AryConversionTestHelper<std::int32_t, 10>("12345678", 12345678, true);
AryConversionTestHelper<int32_t, 10>("123456789", 123456789); AryConversionTestHelper<std::int32_t, 10>("123456789", 123456789, true);
AryConversionTestHelper<int32_t, 10>("2147483647", 2147483647); AryConversionTestHelper<std::int32_t, 10>("2147483647", 2147483647, true);
AryConversionTestHelper<uint64_t, 16>("ffffffffffffffff", 0xffffffffffffffff); AryConversionTestHelper<std::uint64_t, 16>("ffffffffffffffff", 0xffffffffffffffff, false);
AryConversionTestHelper<int64_t, 16>("ffffffffffffffff", 0xffffffffffffffff); AryConversionTestHelper<std::int64_t, 16>("ffffffffffffffff", 0xffffffffffffffff, false);
AryConversionTestHelper<int64_t, 16>("7fffffffffffffff", 0x7fffffffffffffff); AryConversionTestHelper<std::int64_t, 16>("7fffffffffffffff", 0x7fffffffffffffff, false);
AryConversionTestHelper<int32_t, 16>("7fffffff", 0x7fffffff); AryConversionTestHelper<std::int32_t, 16>("7fffffff", 0x7fffffff, true);
AryConversionTestHelper<bool, 10>("1", true); AryConversionTestHelper<bool, 10>("1", true, false);
AryConversionTestHelper<bool, 10>("0", false); AryConversionTestHelper<bool, 10>("0", false, false);
AryConversionTestHelperUp<uint64_t, 16>("ABCDEF123456ABCD", 0xabcdef123456abcd); AryConversionTestHelperUp<std::uint64_t, 16>("ABCDEF123456ABCD", 0xabcdef123456abcd, false);
AryConversionTestHelper<signed int, 10>("-1", -1); AryConversionTestHelper<signed int, 10>("-1", -1, sizeof(signed int) <= sizeof(std::uint32_t));
AryConversionTestHelper<signed int, 10>("-50000", -50000); AryConversionTestHelper<signed int, 10>("-50000", -50000, sizeof(signed int) <= sizeof(std::uint32_t));
AryConversionTestHelper<int64_t, 10>("-1", -1); AryConversionTestHelper<std::int64_t, 10>("-1", -1, false);
AryConversionTestHelper<int64_t, 10>("-510123123123", -510123123123); AryConversionTestHelper<std::int64_t, 10>("-510123123123", -510123123123, false);
} }