Skip to content

Commit 8b0efbe

Browse files
authored
Merge pull request #584 from JohanMabille/logical
Implemented operator&& and operator|| for batch
2 parents 9836406 + cda063e commit 8b0efbe

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

include/xsimd/arch/generic/xsimd_generic_logical.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ namespace xsimd {
7777
template<class A, class T> batch_bool<T, A> neq(batch<T, A> const& self, batch<T, A> const& other, requires_arch<generic>) {
7878
return !(other == self);
7979
}
80+
81+
// logical_and
82+
template <class A, class T>
83+
batch<T, A> logical_and(batch<T, A> const& self, batch<T, A> const& other, requires_arch<generic>) {
84+
return detail::apply([](T x, T y) { return x && y;}, self, other);
85+
}
86+
87+
// logical_or
88+
template <class A, class T>
89+
batch<T, A> logical_or(batch<T, A> const& self, batch<T, A> const& other, requires_arch<generic>) {
90+
return detail::apply([](T x, T y) { return x || y;}, self, other);
91+
}
8092
}
8193
}
8294

include/xsimd/types/xsimd_batch.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ struct batch : types::simd_register<T, A> {
124124
return batch(self) <<= other;
125125
}
126126

127+
friend batch operator&&(batch const& self, batch const& other) {
128+
return batch(self).logical_and(other);
129+
}
130+
131+
friend batch operator||(batch const& self, batch const& other) {
132+
return batch(self).logical_or(other);
133+
}
134+
127135
// Update operators
128136
batch& operator+=(batch const& other);
129137
batch& operator-=(batch const& other);
@@ -147,6 +155,9 @@ struct batch : types::simd_register<T, A> {
147155
private:
148156
template<size_t... Is>
149157
batch(T const* data, detail::index_sequence<Is...>);
158+
159+
batch logical_and(batch const& other) const;
160+
batch logical_or(batch const& other) const;
150161
};
151162

152163
template <class T, class A>
@@ -431,6 +442,16 @@ batch_bool<T, A> batch<T, A>::operator>(batch<T, A> const& other) const { return
431442
template<class T, class A>
432443
batch_bool<T, A> batch<T, A>::operator<(batch<T, A> const& other) const { return kernel::lt<A>(*this, other, A{}); }
433444

445+
template<class T, class A>
446+
batch<T, A> batch<T, A>::logical_and(batch<T, A> const& other) const {
447+
return kernel::logical_and<A>(*this, other, A());
448+
}
449+
450+
template<class T, class A>
451+
batch<T, A> batch<T, A>::logical_or(batch<T, A> const& other) const {
452+
return kernel::logical_or<A>(*this, other, A());
453+
}
454+
434455
template<class T, class A>
435456
batch<T, A>& batch<T, A>::operator+=(batch<T, A> const& other) { return *this = kernel::add<A>(*this, other, A{}); }
436457

test/test_batch.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,42 @@ class batch_test : public testing::Test
408408
}
409409
}
410410

411+
void test_logical() const
412+
{
413+
// batch && batch
414+
{
415+
array_type expected;
416+
std::transform(lhs.cbegin(), lhs.cend(), rhs.cbegin(), expected.begin(), std::logical_and<value_type>());
417+
batch_type res = batch_lhs() && batch_rhs();
418+
EXPECT_BATCH_EQ(res, expected) << print_function_name("batch && batch");
419+
}
420+
// batch && scalar
421+
{
422+
array_type expected;
423+
std::transform(lhs.cbegin(), lhs.cend(), expected.begin(), std::bind(std::logical_and<value_type>(), _1, scalar));
424+
batch_type lres = batch_lhs() && scalar;
425+
EXPECT_BATCH_EQ(lres, expected) << print_function_name("batch && scalar");
426+
batch_type rres = scalar && batch_lhs();
427+
EXPECT_BATCH_EQ(rres, expected) << print_function_name("scalar && batch");
428+
}
429+
// batch || batch
430+
{
431+
array_type expected;
432+
std::transform(lhs.cbegin(), lhs.cend(), rhs.cbegin(), expected.begin(), std::logical_or<value_type>());
433+
batch_type res = batch_lhs() || batch_rhs();
434+
EXPECT_BATCH_EQ(res, expected) << print_function_name("batch && batch");
435+
}
436+
// batch || scalar
437+
{
438+
array_type expected;
439+
std::transform(lhs.cbegin(), lhs.cend(), expected.begin(), std::bind(std::logical_or<value_type>(), _1, scalar));
440+
batch_type lres = batch_lhs() || scalar;
441+
EXPECT_BATCH_EQ(lres, expected) << print_function_name("batch || scalar");
442+
batch_type rres = scalar || batch_lhs();
443+
EXPECT_BATCH_EQ(rres, expected) << print_function_name("scalar || batch");
444+
}
445+
}
446+
411447
void test_min_max() const
412448
{
413449
// min
@@ -688,6 +724,10 @@ TYPED_TEST(batch_test, comparison)
688724
{
689725
this->test_comparison();
690726
}
727+
TYPED_TEST(batch_test, logical)
728+
{
729+
this->test_logical();
730+
}
691731

692732
TYPED_TEST(batch_test, min_max)
693733
{

0 commit comments

Comments
 (0)