1212#define XSIMD_BASIC_TEST_HPP
1313
1414#include < algorithm>
15+ #include < functional>
1516#include < numeric>
1617#include < random>
1718#include < limits>
1819#include < climits>
20+ #include < vector>
1921
2022#include " xsimd/xsimd.hpp"
2123#include " xsimd_test_utils.hpp"
@@ -356,11 +358,45 @@ namespace xsimd
356358 }
357359 }
358360
361+
362+ template <class T , std::size_t N>
363+ struct get_bool_base {
364+ using vector_type = std::array<bool , N>;
365+
366+ std::vector<vector_type> almost_all_false () {
367+ std::vector<vector_type> vectors;
368+ vectors.reserve (N);
369+ for (size_t i = 0 ; i < N; ++i) {
370+ vector_type v;
371+ v.fill (false );
372+ v[i] = true ;
373+ vectors.push_back (std::move (v));
374+ }
375+ return vectors;
376+ }
377+
378+ std::vector<vector_type> almost_all_true () {
379+ auto vectors = almost_all_false ();
380+ flip (vectors);
381+ return vectors;
382+ }
383+
384+ void flip (vector_type& vec) {
385+ std::transform (vec.begin (), vec.end (), vec.begin (), std::logical_not<bool >{});
386+ }
387+
388+ void flip (std::vector<vector_type>& vectors) {
389+ for (auto & vec : vectors) {
390+ flip (vec);
391+ }
392+ }
393+ };
394+
359395 template <class T >
360396 struct get_bool ;
361397
362398 template <class T >
363- struct get_bool <batch_bool<T, 2 >>
399+ struct get_bool <batch_bool<T, 2 >> : public get_bool_base<T, 2 >
364400 {
365401 using type = batch_bool<T, 2 >;
366402 type all_true = type(true );
@@ -375,7 +411,7 @@ namespace xsimd
375411 };
376412
377413 template <class T , std::size_t N>
378- struct get_bool <batch_bool<T, N>>
414+ struct get_bool <batch_bool<T, N>> : public get_bool_base<T, N>
379415 {
380416 // Expect this to be the fallback
381417 using type = batch_bool<T, 10 >;
@@ -391,7 +427,7 @@ namespace xsimd
391427 };
392428
393429 template <class T >
394- struct get_bool <batch_bool<T, 4 >>
430+ struct get_bool <batch_bool<T, 4 >> : public get_bool_base<T, 4 >
395431 {
396432 using type = batch_bool<T, 4 >;
397433
@@ -407,7 +443,7 @@ namespace xsimd
407443 };
408444
409445 template <class T >
410- struct get_bool <batch_bool<T, 8 >>
446+ struct get_bool <batch_bool<T, 8 >> : public get_bool_base<T, 8 >
411447 {
412448 using type = batch_bool<T, 8 >;
413449 type all_true = type(true );
@@ -422,7 +458,7 @@ namespace xsimd
422458 };
423459
424460 template <class T >
425- struct get_bool <batch_bool<T, 16 >>
461+ struct get_bool <batch_bool<T, 16 >> : public get_bool_base<T, 16 >
426462 {
427463 using type = batch_bool<T, 16 >;
428464 type all_true = type(true );
@@ -437,7 +473,7 @@ namespace xsimd
437473 };
438474
439475 template <class T >
440- struct get_bool <batch_bool<T, 32 >>
476+ struct get_bool <batch_bool<T, 32 >> : public get_bool_base<T, 32 >
441477 {
442478 using type = batch_bool<T, 32 >;
443479 type all_true = type(true );
@@ -454,7 +490,7 @@ namespace xsimd
454490 };
455491
456492 template <class T >
457- struct get_bool <batch_bool<T, 64 >>
493+ struct get_bool <batch_bool<T, 64 >> : public get_bool_base<T, 64 >
458494 {
459495 using type = batch_bool<T, 64 >;
460496 type all_true = type(true );
@@ -674,8 +710,10 @@ namespace xsimd
674710 template <class I , std::size_t N, class S >
675711 bool test_simd_bool (const batch<I, N>& /* empty*/ , S& stream)
676712 {
713+ using type = typename simd_batch_traits<batch<I, N>>::batch_bool_type;
714+
677715 bool success = true ;
678- auto bool_g = get_bool<typename simd_batch_traits<batch<I, N>>::batch_bool_type >{};
716+ auto bool_g = get_bool<type >{};
679717 success = success && all (bool_g.half != bool_g.ihalf );
680718 if (!success)
681719 stream << " test_simd_bool != failed." << std::endl;
@@ -694,6 +732,35 @@ namespace xsimd
694732 return success;
695733 }
696734
735+ template <class I , std::size_t N, class S >
736+ bool test_simd_int_bool (const batch<I, N>& /* empty*/ , S& stream)
737+ {
738+ using type = typename simd_batch_traits<batch<I, N>>::batch_bool_type;
739+
740+ bool success_any = true ;
741+ bool success_all = true ;
742+ auto bool_g = get_bool<type>{};
743+
744+ // Reductions
745+ for (const auto vec : bool_g.almost_all_false ()) {
746+ type b;
747+ detail::load_vec (b, vec);
748+ success_any = success_any && any (b);
749+ success_all = success_all && !all (b);
750+ }
751+ for (const auto vec : bool_g.almost_all_true ()) {
752+ type b;
753+ detail::load_vec (b, vec);
754+ success_any = success_any && any (b);
755+ success_all = success_all && !all (b);
756+ }
757+ if (!success_any)
758+ stream << " test_simd_int_bool any() failed." << std::endl;
759+ if (!success_all)
760+ stream << " test_simd_int_bool all() failed." << std::endl;
761+ return success_any && success_all;
762+ }
763+
697764 namespace detail
698765 {
699766 template <class I , std::size_t N, class S >
@@ -1614,6 +1681,7 @@ namespace xsimd
16141681
16151682 success = success && test_simd_int_shift (vector_type (value_type (0 )), out);
16161683 success = success && test_simd_bool (vector_type (value_type (0 )), out);
1684+ success = success && test_simd_int_bool (vector_type (value_type (0 )), out);
16171685 success = success && test_simd_bool_buffer (vector_type (value_type (0 )), out);
16181686 success = success && test_char_loading<vector_type::size>(value_type (), out);
16191687 success = success && test_lt_underflow<vector_type, value_type>();
0 commit comments