Skip to content

Commit

Permalink
Merge pull request #905 from xtensor-stack/fast/integr-signed-conversion
Browse files Browse the repository at this point in the history
Provide generic signed /unsigned type conversion
  • Loading branch information
JohanMabille committed Mar 8, 2023
2 parents 291315f + b8e6ce2 commit 9876975
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
45 changes: 45 additions & 0 deletions include/xsimd/arch/generic/xsimd_generic_details.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,51 @@ namespace xsimd
}
}

// some generic fast_cast conversion
namespace detail
{
template <class A>
inline batch<uint8_t, A> fast_cast(batch<int8_t, A> const& self, batch<uint8_t, A> const&, requires_arch<generic>) noexcept
{
return bitwise_cast<uint8_t>(self);
}
template <class A>
inline batch<uint16_t, A> fast_cast(batch<int16_t, A> const& self, batch<uint16_t, A> const&, requires_arch<generic>) noexcept
{
return bitwise_cast<uint16_t>(self);
}
template <class A>
inline batch<uint32_t, A> fast_cast(batch<int32_t, A> const& self, batch<uint32_t, A> const&, requires_arch<generic>) noexcept
{
return bitwise_cast<uint32_t>(self);
}
template <class A>
inline batch<uint64_t, A> fast_cast(batch<int64_t, A> const& self, batch<uint64_t, A> const&, requires_arch<generic>) noexcept
{
return bitwise_cast<uint64_t>(self);
}
template <class A>
inline batch<int8_t, A> fast_cast(batch<uint8_t, A> const& self, batch<int8_t, A> const&, requires_arch<generic>) noexcept
{
return bitwise_cast<int8_t>(self);
}
template <class A>
inline batch<int16_t, A> fast_cast(batch<uint16_t, A> const& self, batch<int16_t, A> const&, requires_arch<generic>) noexcept
{
return bitwise_cast<int16_t>(self);
}
template <class A>
inline batch<int32_t, A> fast_cast(batch<uint32_t, A> const& self, batch<int32_t, A> const&, requires_arch<generic>) noexcept
{
return bitwise_cast<int32_t>(self);
}
template <class A>
inline batch<int64_t, A> fast_cast(batch<uint64_t, A> const& self, batch<int64_t, A> const&, requires_arch<generic>) noexcept
{
return bitwise_cast<int64_t>(self);
}
}

namespace detail
{
// Generic conversion handling machinery. Each architecture must define
Expand Down
44 changes: 44 additions & 0 deletions test/test_conversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,5 +200,49 @@ TEST_CASE_TEMPLATE("[conversion]", B, CONVERSION_TYPES)
Test.test_u8_casting();
}
}

template <class T>
struct sign_conversion_test
{

using unsigned_type = T;
using signed_type = typename std::make_signed<T>::type;

void test_to_signed()
{
unsigned_type unsigned_value = 3;
signed_type signed_value = (signed_type)unsigned_value;
xsimd::batch<unsigned_type> unsigned_batch(unsigned_value);
auto signed_batch = xsimd::batch_cast<signed_type>(unsigned_batch);
CHECK_EQ(unsigned_batch.get(0), unsigned_value);
CHECK_EQ(signed_batch.get(0), signed_value);
}

void test_to_unsigned()
{
signed_type signed_value = 3;
unsigned_type unsigned_value = (unsigned_type)signed_value;
xsimd::batch<signed_type> signed_batch(signed_value);
auto unsigned_batch = xsimd::batch_cast<unsigned_type>(signed_batch);
CHECK_EQ(signed_batch.get(0), signed_value);
CHECK_EQ(unsigned_batch.get(0), unsigned_value);
}
};

TEST_CASE_TEMPLATE("[conversion]", T, uint8_t, uint16_t, uint32_t, uint64_t)
{
sign_conversion_test<T> Test;

SUBCASE("to_signed")
{
Test.test_to_signed();
}

SUBCASE("to_unsigned")
{
Test.test_to_unsigned();
}
}

#endif
#endif

0 comments on commit 9876975

Please sign in to comment.