diff --git a/include/kyosu/types/impl/arithmetic.hpp b/include/kyosu/types/impl/arithmetic.hpp index 66dd6695..dc064d57 100644 --- a/include/kyosu/types/impl/arithmetic.hpp +++ b/include/kyosu/types/impl/arithmetic.hpp @@ -39,11 +39,14 @@ namespace kyosu::_ { if constexpr(concepts::cayley_dickson && concepts::cayley_dickson) { - using type = as_cayley_dickson_t; - auto parts = kumi::map([&](auto const& v, auto const& w) { return eve::if_else(m, v, w); }, t, f); - - if constexpr(eve::simd_value) return eve::as_wide_as_t{parts}; - else return type{parts}; + using type = as_cayley_dickson_t; + using ret_t = std::conditional_t, eve::as_wide_as_t, type>; + constexpr eve::as> tgt = {}; + + return ret_t{ kumi::map ( [&](auto const& v, auto const& w) { return eve::if_else(m, v, w); } + , kyosu::convert(t, tgt), kyosu::convert(f, tgt) + ) + }; } else if constexpr(concepts::cayley_dickson && !concepts::cayley_dickson) { diff --git a/test/unit/function/if_else.cpp b/test/unit/function/if_else.cpp new file mode 100644 index 00000000..bb55e6e6 --- /dev/null +++ b/test/unit/function/if_else.cpp @@ -0,0 +1,64 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include + +TTS_CASE_WITH ( "Check behavior of if_else on scalar cayley-dickson" + , tts::bunch + , tts::generate(tts::randoms(-100,+100)) + ) +(T const& a0 ) +{ + using e_t = typename T::value_type; + for(auto e : a0) + { + auto m = eve::is_odd(e); + TTS_EQUAL ( kyosu::if_else( m, kyosu::complex(0,-e), kyosu::complex(0, e)) + , kyosu::complex(0,m ? -e : e) + ); + + TTS_EQUAL ( kyosu::if_else(m, kyosu::quaternion(0,-e,1,-2), kyosu::quaternion(0,e,-1, 2)) + , kyosu::quaternion(0,m ? -e : e,m ? 1 : -1,m ? -2 : 2) + ); + + TTS_EQUAL ( kyosu::if_else( eve::is_odd(e) + , kyosu::complex(0,-e) + , kyosu::quaternion(0, e,-1, 2) + ) + , kyosu::quaternion(0,m ? -e : e,m ? 0 : -1,m ? 0 : 2) + ); + TTS_EQUAL ( kyosu::if_else( eve::is_odd(e) + , kyosu::quaternion(0,-e, 1, -2) + , kyosu::complex(0, e) + ) + , kyosu::quaternion(0,m ? -e : e,m ? 1 : 0,m ? -2 : 0) + ); + } +}; + +TTS_CASE_WITH ( "Check behavior of if_else on SIMD cayley-dickson" + , tts::bunch + , tts::generate(tts::randoms(-100,+100)) + ) +(T const& a0 ) +{ + using e_t = typename T::value_type; + using c_t = kyosu::complex; + using q_t = kyosu::quaternion; + using wc_t = eve::wide; + using wq_t = eve::wide; + + for(auto e : a0) + { + auto m = eve::is_odd(e); + TTS_EQUAL(kyosu::if_else(m, wc_t(c_t(0,-e)) , wc_t(c_t(0,e))) , wc_t(c_t(0,m ? -e : e))); + TTS_EQUAL(kyosu::if_else(m, wq_t(q_t(0,-e,1,-2)), wq_t(q_t(0,e,-1,2))), wq_t(q_t(0,m ? -e : e,m ? 1 : -1,m ? -2 : 2))); + TTS_EQUAL(kyosu::if_else(m, wc_t(c_t(0,-e)) , wq_t(q_t(0,e,-1,2))), wq_t(q_t(0,m ? -e : e,m ? 0 : -1,m ? 0 : 2))); + TTS_EQUAL(kyosu::if_else(m, wq_t(q_t(0,-e,1,-2)), wc_t(c_t(0, e))) , wq_t(q_t(0,m ? -e : e,m ? 1 : 0,m ? -2 : 0))); + } +};