Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some other callable conversion #1801

Merged
merged 8 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions include/eve/detail/function/bit_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,24 @@
#pragma once

#include <eve/arch.hpp>
#include <eve/detail/overload.hpp>
#include <eve/traits/overload.hpp>

namespace eve
{
EVE_MAKE_CALLABLE(bit_cast_, bit_cast);
template<typename Options>
struct bit_cast_t : callable<bit_cast_t, Options>
{
template<typename T, typename Target>
requires (sizeof(T) == sizeof(Target))
EVE_FORCEINLINE Target operator()(T const& a, as<Target> const& tgt) const noexcept
{
return EVE_DISPATCH_CALL(a,tgt);
}

EVE_CALLABLE_OBJECT(bit_cast_t, bit_cast_);
};

inline constexpr auto bit_cast = functor<bit_cast_t>;
}

#include <eve/detail/function/simd/common/bit_cast.hpp>
Expand Down
63 changes: 31 additions & 32 deletions include/eve/detail/function/simd/arm/sve/bit_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,40 @@

namespace eve::detail
{
template<scalar_value T, typename N, scalar_value U, typename M>
EVE_FORCEINLINE wide<U, M>
bit_cast_(EVE_SUPPORTS(sve_), wide<T, N> const& x, as<wide<U, M>> const&) noexcept
requires(sizeof(wide<T, N>) == sizeof(wide<U, M>) && (sve_abi<abi_t<T, N>>))
{
if constexpr( std::is_same_v<wide<T, N>, wide<U, M>> ) { return x; }
else
template<callable_options O, scalar_value T, typename N, scalar_value U, typename M>
requires( sve_abi<abi_t<T, N>> )
EVE_FORCEINLINE wide<U, M> bit_cast_(EVE_REQUIRES(sve_), O const&, wide<T,N> x, as<wide<U,M>> const&) noexcept
{
auto as_byte = [](auto v)
if constexpr( std::is_same_v<wide<T, N>, wide<U, M>> ) return x;
else
{
constexpr auto c = categorize<eve::wide<T,N>>();
if constexpr(match(c, category::float64)) return svreinterpret_u8_f64(v);
else if constexpr(match(c, category::float32)) return svreinterpret_u8_f32(v);
else if constexpr(match(c, category::int64) ) return svreinterpret_u8_s64(v);
else if constexpr(match(c, category::uint64) ) return svreinterpret_u8_u64(v);
else if constexpr(match(c, category::int32) ) return svreinterpret_u8_s32(v);
else if constexpr(match(c, category::uint32) ) return svreinterpret_u8_u32(v);
else if constexpr(match(c, category::int16) ) return svreinterpret_u8_s16(v);
else if constexpr(match(c, category::uint16) ) return svreinterpret_u8_u16(v);
else if constexpr(match(c, category::int8) ) return svreinterpret_u8_s8 (v);
else if constexpr(match(c, category::uint8) ) return v.storage();
}(x);
auto as_byte = [](auto v)
{
constexpr auto c = categorize<eve::wide<T,N>>();
if constexpr(match(c, category::float64)) return svreinterpret_u8_f64(v);
else if constexpr(match(c, category::float32)) return svreinterpret_u8_f32(v);
else if constexpr(match(c, category::int64) ) return svreinterpret_u8_s64(v);
else if constexpr(match(c, category::uint64) ) return svreinterpret_u8_u64(v);
else if constexpr(match(c, category::int32) ) return svreinterpret_u8_s32(v);
else if constexpr(match(c, category::uint32) ) return svreinterpret_u8_u32(v);
else if constexpr(match(c, category::int16) ) return svreinterpret_u8_s16(v);
else if constexpr(match(c, category::uint16) ) return svreinterpret_u8_u16(v);
else if constexpr(match(c, category::int8) ) return svreinterpret_u8_s8 (v);
else if constexpr(match(c, category::uint8) ) return v.storage();
}(x);

constexpr auto d = categorize<wide<U, M>>();
constexpr auto d = categorize<wide<U, M>>();

if constexpr(match(d, category::float64)) return svreinterpret_f64_u8(as_byte);
else if constexpr(match(d, category::float32)) return svreinterpret_f32_u8(as_byte);
else if constexpr(match(d, category::int64) ) return svreinterpret_s64_u8(as_byte);
else if constexpr(match(d, category::uint64) ) return svreinterpret_u64_u8(as_byte);
else if constexpr(match(d, category::int32) ) return svreinterpret_s32_u8(as_byte);
else if constexpr(match(d, category::uint32) ) return svreinterpret_u32_u8(as_byte);
else if constexpr(match(d, category::int16) ) return svreinterpret_s16_u8(as_byte);
else if constexpr(match(d, category::uint16) ) return svreinterpret_u16_u8(as_byte);
else if constexpr(match(d, category::int8) ) return svreinterpret_s8_u8 (as_byte);
else if constexpr(match(d, category::uint8) ) return as_byte;
if constexpr(match(d, category::float64)) return svreinterpret_f64_u8(as_byte);
else if constexpr(match(d, category::float32)) return svreinterpret_f32_u8(as_byte);
else if constexpr(match(d, category::int64) ) return svreinterpret_s64_u8(as_byte);
else if constexpr(match(d, category::uint64) ) return svreinterpret_u64_u8(as_byte);
else if constexpr(match(d, category::int32) ) return svreinterpret_s32_u8(as_byte);
else if constexpr(match(d, category::uint32) ) return svreinterpret_u32_u8(as_byte);
else if constexpr(match(d, category::int16) ) return svreinterpret_s16_u8(as_byte);
else if constexpr(match(d, category::uint16) ) return svreinterpret_u16_u8(as_byte);
else if constexpr(match(d, category::int8) ) return svreinterpret_s8_u8 (as_byte);
else if constexpr(match(d, category::uint8) ) return as_byte;
}
}
}
}
10 changes: 3 additions & 7 deletions include/eve/detail/function/simd/common/bit_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@

namespace eve::detail
{
template<typename T, typename Target>
EVE_FORCEINLINE auto bit_cast_(EVE_SUPPORTS(cpu_), T const &a, as<Target> const &) noexcept
requires (sizeof(T) == sizeof(Target))
template<callable_options O, typename T, typename Target>
EVE_FORCEINLINE auto bit_cast_(EVE_REQUIRES(cpu_), O const&, T const &a, as<Target> const &) noexcept
{
if constexpr(std::is_same_v<T, Target>)
{
return a;
}
if constexpr(std::is_same_v<T, Target>) return a;
else
{
[[maybe_unused]] Target that;
Expand Down
6 changes: 3 additions & 3 deletions include/eve/detail/function/simd/ppc/bit_compounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ namespace eve::detail

if constexpr( element_bit_compatible_to<U,type> )
{
auto bit_other = detail::bit_cast_(EVE_RETARGET(cpu_), other , as<T>{});
auto bit_other = bit_cast(other , as<T>{});
self = vec_and(self.storage(), type{bit_other}.storage());
}
else if constexpr( simd_value<U> && sizeof(self) == sizeof(other) )
Expand All @@ -94,7 +94,7 @@ namespace eve::detail

if constexpr( element_bit_compatible_to<U,type> )
{
auto bit_other = detail::bit_cast_(EVE_RETARGET(cpu_), other , as<T>{});
auto bit_other = bit_cast(other , as<T>{});
self = vec_or(self.storage(), type{bit_other}.storage());
}
else if constexpr( simd_value<U> && sizeof(self) == sizeof(other) )
Expand All @@ -116,7 +116,7 @@ namespace eve::detail

if constexpr( element_bit_compatible_to<U,type> )
{
auto bit_other = detail::bit_cast_(EVE_RETARGET(cpu_), other , as<T>{});
auto bit_other = bit_cast(other , as<T>{});
self = vec_xor(self.storage(), type{bit_other}.storage());
}
else if constexpr( simd_value<U> && sizeof(self) == sizeof(other) )
Expand Down
8 changes: 4 additions & 4 deletions include/eve/detail/function/simd/x86/bit_compounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,12 @@ namespace eve::detail

if constexpr( scalar_value<U> )
{
auto bit_other = detail::bit_cast_(EVE_RETARGET(cpu_), other, as<T> {});
auto bit_other = bit_cast(other, as<T> {});
return self_bitor(self, type {bit_other});
}
else if constexpr( simd_value<U> && sizeof(self) == sizeof(other) )
{
auto bits = detail::bit_cast_(EVE_RETARGET(cpu_), other, as<type> {});
auto bits = bit_cast(other, as<type> {});
constexpr auto c = categorize<type>();
constexpr bool i = match(c, category::integer_);

Expand Down Expand Up @@ -294,12 +294,12 @@ namespace eve::detail

if constexpr( scalar_value<U> )
{
auto bit_other = detail::bit_cast_(EVE_RETARGET(cpu_), other, as<T> {});
auto bit_other = bit_cast(other, as<T> {});
return self_bitxor(self, type {bit_other});
}
else if constexpr( simd_value<U> && sizeof(self) == sizeof(other) )
{
auto bits = detail::bit_cast_(EVE_RETARGET(cpu_), other, as<type> {});
auto bits = bit_cast(other, as<type> {});
constexpr auto c = categorize<type>();
constexpr bool i = match(c, category::integer_);

Expand Down
5 changes: 1 addition & 4 deletions include/eve/module/algo/algo/views/backward.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,7 @@ namespace eve::algo::views
return eve::read(unalign(self.base) - 1);
}

EVE_FORCEINLINE friend void tagged_dispatch(eve::tag::write_, value_type v, backward_iterator self)
{
return eve::write(v, unalign(self.base) - 1);
}
EVE_FORCEINLINE void write(value_type v) const noexcept { eve::write(v, unalign(base) - 1); }

template <relaxed_sentinel_for<I> I1>
EVE_FORCEINLINE bool operator==(backward_iterator<I1> y) const
Expand Down
4 changes: 2 additions & 2 deletions include/eve/module/algo/algo/views/convert.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ namespace eve::algo::views
return eve::convert(eve::read(self.base), eve::as<T>{});
}

EVE_FORCEINLINE friend void tagged_dispatch(eve::tag::write_, T v, converting_iterator self)
EVE_FORCEINLINE void write(T v) const noexcept
{
eve::write(eve::convert(v, eve::as<value_type_t<I>>{}),self.base);
eve::write(eve::convert(v, eve::as<value_type_t<I>>{}),base);
}

template <relaxed_sentinel_for<I> I1>
Expand Down
6 changes: 3 additions & 3 deletions include/eve/module/algo/algo/views/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,10 @@ namespace eve::algo::views
return self.load_op(eve::read(self.base));
}

EVE_FORCEINLINE friend void tagged_dispatch(eve::tag::write_, auto v, map_iterator self)
requires (!std::same_as<StoreOp, nothing_t>)
EVE_FORCEINLINE void write(value_type v) const noexcept
requires (!std::same_as<StoreOp, nothing_t>)
{
eve::write(detail::bind_store_op<I>(self.store_op)(v),self.base);
eve::write(detail::bind_store_op<I>(store_op)(v),base);
}

template <relaxed_sentinel_for<I> I1>
Expand Down
5 changes: 1 addition & 4 deletions include/eve/module/algo/algo/views/reverse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,7 @@ namespace eve::algo::views
return eve::read(unalign(self.base) - 1);
}

EVE_FORCEINLINE friend void tagged_dispatch(eve::tag::write_, value_type v, reverse_iterator self)
{
return eve::write(v,unalign(self.base) - 1);
}
EVE_FORCEINLINE void write(value_type v) const noexcept { return eve::write(v,unalign(base) - 1); }

template <relaxed_sentinel_for<I> I1>
EVE_FORCEINLINE bool operator==(reverse_iterator<I1> y) const
Expand Down
5 changes: 1 addition & 4 deletions include/eve/module/algo/algo/views/zip_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,7 @@ namespace eve::algo::views
return kumi::map(eve::read, self.storage);
}

EVE_FORCEINLINE friend auto tagged_dispatch(eve::tag::write_, value_type v, zip_iterator<Is...> self)
{
kumi::for_each(eve::write, v, self.storage);
}
EVE_FORCEINLINE void write(value_type v) const noexcept { kumi::for_each(eve::write, v, storage); }

EVE_FORCEINLINE operator zip_iterator<unaligned_t<Is>...>() const
{
Expand Down
104 changes: 52 additions & 52 deletions include/eve/module/core/regular/bit_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,61 +7,61 @@
#pragma once

#if defined(EVE_DOXYGEN_INVOKED)
# include <eve/detail/overload.hpp>
#include <eve/traits/overload.hpp>

namespace eve
{
//================================================================================================
//! @addtogroup core_bitops
//! @{
//! @var bit_cast
//! @brief Computes a a bitwise reinterpretation of an object.
//!
//! **Defined in Header**
//!
//! @code
//! #include <eve/module/core.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace eve
//! {
//! { template<value From, scalar_value To>
//! To bit_cast operator()(From x, as<To> t) noexcept;
//! }
//! @endcode
//!
//! **Parameters**
//!
//! * `x` : [argument](@ref eve::value).
//! * `t` : [Type wrapper](@ref eve::as) instance embedding the type of the result.
//!
//! **Template parameters**
//!
//! * To: scalar type to which each element of `x` is casted
//!
//! **Return value**
//!
//! The bits of x of type From reinterpreted as being those of a variable of type To
//! is returned.
//!
//! Every bit in the value representation of the returned To object is equal to the
//! corresponding bit in the object representation of from.
//! The values of padding bits in the returned To object are unspecified.
//!
//! If there is no value of type To corresponding to the value
//! representation produced, the behavior is undefined. If there are multiple
//! such values, which value is produced is unspecified.
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/core/bit_cast.cpp}
//!
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(bit_cast_, bit_cast);
//================================================================================================
//! @addtogroup core_bitops
//! @{
//! @var bit_cast
//! @brief Computes a a bitwise reinterpretation of an object.
//!
//! **Defined in Header**
//!
//! @code
//! #include <eve/module/core.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace eve
//! {
//! { template<value From, scalar_value To>
//! To bit_cast operator()(From x, as<To> t) noexcept;
//! }
//! @endcode
//!
//! **Parameters**
//!
//! * `x` : [argument](@ref eve::value).
//! * `t` : [Type wrapper](@ref eve::as) instance embedding the type of the result.
//!
//! **Template parameters**
//!
//! * To: scalar type to which each element of `x` is casted
//!
//! **Return value**
//!
//! The bits of x of type From reinterpreted as being those of a variable of type To
//! is returned.
//!
//! Every bit in the value representation of the returned To object is equal to the
//! corresponding bit in the object representation of from.
//! The values of padding bits in the returned To object are unspecified.
//!
//! If there is no value of type To corresponding to the value
//! representation produced, the behavior is undefined. If there are multiple
//! such values, which value is produced is unspecified.
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/core/bit_cast.cpp}
//!
//! @}
//================================================================================================
inline constexpr auto bit_cast = functor<bit_cast_t>;
}
#endif

Expand Down
Loading