E.V.E  0.1-beta

◆ if_else

eve::if_else = {}
inlineconstexpr

Callable object computing the if_else operation.

Required header: #include <eve/function/if_else.hpp>

Members Functions

Member Effect
operator() the if_else operation

template< value T, value U, value V > auto operator()( T x, U y, V z ) const noexcept
requires compatible< U, V >;

Parameters

x, y, z: values

Return value

The call if_else(x, y, z) performs a choice between the elements of y and z according to the truth value of the elements of x.

Let UV be the compatibility result of U and V. The call auto r = if_else(x, y, z) is semantically equivalent to:

if constexpr(scalar_value< T >)
{
return x ? UV(x) : UV(y);
}
else if constexpr(scalar_value< U > && scalar_value< V >)
{
for(int i=0; i < cardinal_v< T >; ++i)
{
r[i] = (xx[i]) ? y : z;
}
}
else
{
using C = wide< element_t< T >, cardinal_t< UV >>;
auto xx = C(x);
UV r;
for(int i=0; i<cardinal_v< UV >; ++i)
{
r[i] = (xx[i]) ? y[i] : z[i];
}
}
Specify that a type represents a scalar value.
Definition: vectorizable.hpp:70

if U, V and T are scalar or if U or V are simd_values the result is of type UV, otherwise it is of type wide< UV, cardinal_t< T >>.

Possible optimizations

The following calls where x, y and z are values can be optimized:

  • if_else(x, y, allbits< T >()) writing: if_else(x, y, eve::allbits_)
  • if_else(x, y, one< T >() ) writing: if_else(x, y, eve::one_ )
  • if_else(x, y, mone< T >() ) writing: if_else(x, y, eve::mone_ )
  • if_else(x, y, zero< T >() ) writing: if_else(x, y, eve::zero_ )
  • if_else(x, allbits< T >(), z) writing: if_else(x, eve::allbits_, z)
  • if_else(x, one< T >(), z ) writing: if_else(x, eve::one_, z )
  • if_else(x, mone< T >(), z ) writing: if_else(x, eve::mone_, z )
  • if_else(x, zero< T >(), z ) writing: if_else(x, eve::zero_, z )

Supported decorators

no decorators are supported

Example

See it live on Compiler Explorer

#include <eve/function/logical.hpp>
#include <eve/wide.hpp>
#include <iostream>
using iT = std::int32_t;
using wide_it = eve::wide<iT, eve::fixed<4>>;
using wide_lt = eve::as_logical_t<wide_it>;
int main()
{
wide_it pi = {3, -2, -10, 0};
wide_it qi = {4, -1, 0, 5};
wide_it si = {2, -3, 0, 4};
wide_lt lsi = {true, false, false, true};
std::cout << "---- simd" << '\n'
<< " <- si = " << si << '\n'
<< " <- lsi = " << lsi << '\n'
<< " <- pi = " << pi << '\n'
<< " <- qi = " << qi << '\n'
<< " -> eve::if_else(si, pi, qi) = " << eve::if_else(si, pi, qi) << '\n'
<< " -> eve::if_else(lsi, pi, qi) = " << eve::if_else(lsi, pi, qi) << '\n';
iT ssi = 3, xi = 3, yi = 4;
eve::logical<iT> lssi = false;
std::cout << "---- scalar" << '\n'
<< " ssi = = " << ssi << '\n'
<< " lssi = = " << lssi << '\n'
<< " xi = = " << xi << '\n'
<< " yi = = " << yi << '\n'
<< " -> eve::if_else(ssi, xi, yi) = " << eve::if_else(ssi, xi, yi) << '\n'
<< " -> eve::if_else(lssi, xi, yi) = " << eve::if_else(lssi, xi, yi) << '\n';
return 0;
}
constexpr callable_pi_ pi
Callable object computing the value.
Definition: pi.hpp:54
constexpr callable_if_else_ if_else
Callable object computing the if_else operation.
Definition: if_else.hpp:99
Wrapper for SIMD compatible logical types.
Definition: logical.hpp:36
Wrapper for SIMD registers.
Definition: wide.hpp:65