diff --git a/include/xsimd/arch/generic/xsimd_generic_memory.hpp b/include/xsimd/arch/generic/xsimd_generic_memory.hpp index 01aa48c65..badd0e384 100644 --- a/include/xsimd/arch/generic/xsimd_generic_memory.hpp +++ b/include/xsimd/arch/generic/xsimd_generic_memory.hpp @@ -32,6 +32,32 @@ namespace xsimd using namespace types; + // broadcast + namespace detail + { + template + struct broadcaster + { + using return_type = batch; + + static XSIMD_INLINE return_type run(T v) noexcept + { + return return_type::broadcast(v); + } + }; + + template + struct broadcaster + { + using return_type = batch_bool, A>; + + static XSIMD_INLINE return_type run(bool b) noexcept + { + return return_type(b); + } + }; + } + // compress namespace detail { diff --git a/include/xsimd/types/xsimd_api.hpp b/include/xsimd/types/xsimd_api.hpp index a9c61244c..7cecb6ca1 100644 --- a/include/xsimd/types/xsimd_api.hpp +++ b/include/xsimd/types/xsimd_api.hpp @@ -486,15 +486,17 @@ namespace xsimd /** * @ingroup batch_data_transfer * - * Creates a batch from the single value \c v. + * Creates a batch from the single value \c v. If \c v is a boolean, + * this function returns a batch_bool. If you need another type + * of batch_bool, please use \c broadcast_as instead. * @param v the value used to initialize the batch * @return a new batch instance */ template - XSIMD_INLINE batch broadcast(T v) noexcept + XSIMD_INLINE typename kernel::detail::broadcaster::return_type broadcast(T v) noexcept { detail::static_check_supported_config(); - return batch::broadcast(v); + return kernel::detail::broadcaster::run(v); } /** diff --git a/include/xsimd/types/xsimd_traits.hpp b/include/xsimd/types/xsimd_traits.hpp index c6436aef7..0d5565b78 100644 --- a/include/xsimd/types/xsimd_traits.hpp +++ b/include/xsimd/types/xsimd_traits.hpp @@ -77,6 +77,11 @@ namespace xsimd "usage of batch type with unsupported type"); }; + template + struct static_check_supported_config_emitter : static_check_supported_config_emitter, A> + { + }; + template struct static_check_supported_config_emitter, A> : static_check_supported_config_emitter { diff --git a/include/xsimd/types/xsimd_utils.hpp b/include/xsimd/types/xsimd_utils.hpp index aa890f241..0aec70c1d 100644 --- a/include/xsimd/types/xsimd_utils.hpp +++ b/include/xsimd/types/xsimd_utils.hpp @@ -77,6 +77,12 @@ namespace xsimd { }; + template <> + struct as_unsigned_integer + { + using type = uint8_t; + }; + template <> struct as_unsigned_integer { diff --git a/test/test_api.cpp b/test/test_api.cpp index 9a32db2eb..a5e933f4a 100644 --- a/test/test_api.cpp +++ b/test/test_api.cpp @@ -23,6 +23,7 @@ struct xsimd_api_test { using batch_type = B; using batch_bool_type = typename B::batch_bool_type; + using arch_type = typename B::arch_type; using value_type = typename B::value_type; static constexpr size_t size = B::size; using array_type = std::array; @@ -100,6 +101,7 @@ struct xsimd_api_test void test_set() { + test_set_bool("set bool"); test_set_impl("set int8_t"); test_set_impl("set uint8_t"); test_set_impl("set int16_t"); @@ -171,6 +173,15 @@ struct xsimd_api_test CHECK_BATCH_EQ(res, expected); } + void test_set_bool(const std::string& name) + { + bool v = true; + xsimd::batch_bool expected(v); + xsimd::batch_bool res = xsimd::broadcast(v); + INFO(name); + CHECK_BATCH_EQ(res, expected); + } + template void init_test_vector(V& vec) {