Skip to content

Commit

Permalink
Changed as_value to be a new format callable (#2058)
Browse files Browse the repository at this point in the history
* also prevent `as_value` from hiding narrowing conversion warnings.
  • Loading branch information
SadiinsoSnowfall committed Feb 11, 2025
1 parent d92d693 commit fa50c0c
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 71 deletions.
103 changes: 59 additions & 44 deletions include/eve/module/core/constant/as_value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,59 +10,74 @@
#include <eve/as.hpp>
#include <eve/concept/value.hpp>
#include <eve/concept/invocable.hpp>
#include <eve/concept/generator.hpp>
#include <eve/detail/implementation.hpp>

#include <concepts>

namespace eve
{
//================================================================================================
//! @addtogroup core_conversions
//! @{
//! @var as_value
//! @brief converts eve constant or just a value to a type.
//!
//! **Defined in Header**
//!
//! @code
//! #include <eve/module/core.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace eve
//! {
//! template< eve::value From, eve::value T >
//! T as_value(From x, eve::as<T> t) noexcept;
//! }
//! @endcode
//!
//! **Parameters**
//!
//! * `x`: either something convertible to T or an of eve constant
//! * `t` : [Type wrapper](@ref eve::as) instance embedding the type of the constant.
//!
//! **Return value**
//!
//! The call `eve::as_value(as<T>())` returns a value of type T which is
//! the conversion of `x` to type Target or the the eve constant of type Target.
//!
//! @groupheader{Example}
//! @godbolt{doc/core/constant/as_value.cpp}
//================================================================================================
EVE_MAKE_CALLABLE(as_value_, as_value);

namespace detail
template<typename Options>
struct as_value_t : callable<as_value_t, Options>
{
template<typename From, value T>
EVE_FORCEINLINE constexpr auto as_value_(EVE_SUPPORTS(cpu_), From from, as<T> const& t) noexcept
template<generator From, value T>
EVE_FORCEINLINE constexpr T operator()(From from, as<T> t) const noexcept
{
return from(t);
}

template<arithmetic_value From, value T>
EVE_FORCEINLINE constexpr T operator()(From from, as<T>) const noexcept
{
return T{from};
}

template<relaxed_logical_value From, value T>
EVE_FORCEINLINE constexpr T operator()(From from, as<T>) const noexcept
{
if constexpr( requires { typename From::constant_callable_tag; } ) return from(t);//if constexpr( instance_of<From,functor> ) return from(t);
else if constexpr( scalar_value<T> ) return static_cast<T>(from);
else return T {from};
return T{from};
}
}
};

//================================================================================================
//! @addtogroup core_conversions
//! @{
//! @var as_value
//! @brief converts eve constant or just a value to a type.
//!
//! **Defined in Header**
//!
//! @code
//! #include <eve/module/core.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace eve
//! {
//! template<eve::value From, eve::value T>
//! T as_value(From x, eve::as<T> t) noexcept;
//!
//! template<eve::generator From, eve::value T>
//! T as_value(From from, eve::as<T> t) noexcept;
//! }
//! @endcode
//!
//! **Parameters**
//!
//! * `x`: either something convertible to T or an of eve constant
//! * `t` : [Type wrapper](@ref eve::as) instance embedding the type of the constant.
//!
//! **Return value**
//!
//! The call `eve::as_value(as<T>())` returns a value of type T which is
//! the conversion of `x` to type Target or the the eve constant of type Target.
//!
//! @groupheader{Example}
//! @godbolt{doc/core/constant/as_value.cpp}
//================================================================================================
inline constexpr auto as_value = functor<as_value_t>;
//================================================================================================
//! @}
//================================================================================================
Expand Down
5 changes: 1 addition & 4 deletions test/doc/core/constant/as_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@ int main()
<< "<- as_value(valmax, as<wide_it>()) = " << eve::as_value(eve::valmax, eve::as<wide_it>()) << '\n'
;

double xf = -62768.0f;

std::cout << "---- scalar" << '\n'
<< "<- as_value(xf, as<float>()) = " << eve::as_value(xf, eve::as<float>()) << '\n'
<< "<- as_value(xf, as<int16_t>()) = " << eve::as_value(xf, eve::as<int16_t>()) << '\n';
<< "<- as_value(valmax, as<float>()) = " << eve::as_value(eve::valmax, eve::as<float>()) << '\n';

return 0;
}
45 changes: 22 additions & 23 deletions test/unit/module/core/as_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,33 +48,32 @@ TTS_CASE_TPL("Check behavior of arithmetic as_value", eve::test::simd::all_types
e_t expected {0};
e_t actual = eve::as_value(eve::zero, eve::as<e_t> {});
TTS_EQUAL(expected, actual);
actual = eve::as_value(0, eve::as<e_t> {});
TTS_EQUAL(expected, actual);
actual = eve::as_value(expected, eve::as<e_t> {});
TTS_EQUAL(expected, actual);
}
};

TTS_CASE_TPL("Check behavior of logical as_value", eve::test::simd::all_types)
<typename T>(tts::type<T>) {{using U = eve::logical<T>;
U expected {true};
U actual = eve::as_value(eve::true_, eve::as<U> {});
TTS_EQUAL(expected, actual);
actual = eve::as_value(true, eve::as<U> {});
TTS_EQUAL(expected, actual);
actual = eve::as_value(expected, eve::as<U> {});
TTS_EQUAL(expected, actual);
}
<typename T>(tts::type<T>) {
{
using U = eve::logical<T>;
U expected {true};
U actual = eve::as_value(eve::true_, eve::as<U> {});
TTS_EQUAL(expected, actual);
actual = eve::as_value(true, eve::as<U> {});
TTS_EQUAL(expected, actual);
actual = eve::as_value(expected, eve::as<U> {});
TTS_EQUAL(expected, actual);
}

{
using U = eve::logical<eve::element_type_t<T>>;
U expected {true};
U actual = eve::as_value(eve::true_, eve::as<U> {});
TTS_EQUAL(expected, actual);
actual = eve::as_value(true, eve::as<U> {});
TTS_EQUAL(expected, actual);
actual = eve::as_value(expected, eve::as<U> {});
TTS_EQUAL(expected, actual);
}
}
;
{
using U = eve::logical<eve::element_type_t<T>>;
U expected {true};
U actual = eve::as_value(eve::true_, eve::as<U> {});
TTS_EQUAL(expected, actual);
actual = eve::as_value(true, eve::as<U> {});
TTS_EQUAL(expected, actual);
actual = eve::as_value(expected, eve::as<U> {});
TTS_EQUAL(expected, actual);
}
};

0 comments on commit fa50c0c

Please sign in to comment.