119#ifndef VSPLINE_SIMD_TYPE_H
120#define VSPLINE_SIMD_TYPE_H
127template <
typename T >
128using is_scalar =
typename std::integral_constant < bool ,
129 std::is_fundamental < T > ::value
130 || std::is_same < T , bool > :: value > :: type ;
144template <
typename _value_type ,
154 _value_type _store [ _vsize ] ;
212 (*
this) [ i ] = rhs ;
247 #define BUILD_FROM_CONTAINER(SIZE_TYPE,VSZ) \
248 template < typename U , template < typename , SIZE_TYPE > class V > \
249 simd_type & operator= ( const V < U , VSZ > & rhs ) \
251 for ( size_type i = 0 ; i < vsize ; i++ ) \
252 (*this) [ i ] = rhs [ i ] ; \
255 template < typename U , template < typename , SIZE_TYPE > class V > \
256 simd_type ( const V < U , VSZ > & ini ) \
264 #undef BUILD_FROM_CONTAINER
277 template <
typename U ,
280 template < typename , std::size_t ,
281 typename , std::size_t >
class W >
285 (*
this) [ i ] = rhs [ i ] ;
291 template <
typename U ,
294 template < typename , std::size_t ,
295 typename , std::size_t >
class W >
315 static const IT ceiling = std::numeric_limits < IT > :: max() ;
316 assert ( (
vsize - 1 ) <= std::size_t ( ceiling ) ) ;
326 std::size_t step = 1 )
329 static const IT ceiling = std::numeric_limits < IT > :: max() ;
330 assert ( start + (
vsize - 1 ) * step <= std::size_t ( ceiling ) ) ;
355 osr << it [ i ] <<
", " ;
356 osr << it [
vsize - 1 ] <<
")" ;
379 (*
this) [ i ] = p_src [ i ] ;
388 template <
typename index_type >
393 (*
this) [ i ] = p_src [ indexes [ i ] ] ;
398 template <
typename index_type >
402 gather ( p_src , indexes ) ;
410 p_trg [ i ] = (*
this) [ i ] ;
415 template <
typename index_type >
420 p_trg [ indexes [ i ] ] = (*
this) [ i ] ;
432 gather ( p_src , indexes ) ;
436 const int & step )
const
445 template <
typename index_type >
450 result [ i ] = (*
this) [ indexes [ i ] ] ;
470 #define BROADCAST_STD_FUNC(FUNC) \
471 friend simd_type FUNC ( simd_type arg ) \
474 for ( size_type i = 0 ; i < vsize ; i++ ) \
475 result [ i ] = std::FUNC ( arg [ i ] ) ; \
495 #undef BROADCAST_STD_FUNC
497 #define BROADCAST_STD_FUNC2(FUNC) \
498 friend simd_type FUNC ( simd_type arg1 , \
502 for ( size_type i = 0 ; i < vsize ; i++ ) \
503 result [ i ] = std::FUNC ( arg1 [ i ] , arg2 [ i ] ) ; \
513 #undef BROADCAST_STD_FUNC2
515 #define BROADCAST_STD_FUNC3(FUNC) \
516 friend simd_type FUNC ( simd_type arg1 , \
521 for ( size_type i = 0 ; i < vsize ; i++ ) \
522 result [ i ] = FUNC ( arg1 [ i ] , arg2 [ i ] , arg3[i] ) ; \
528 #undef BROADCAST_STD_FUNC3
540 #define INTEGRAL_ONLY \
541 static_assert ( std::is_integral < value_type > :: value , \
542 "this operation is only allowed for integral types" ) ;
545 static_assert ( std::is_same < value_type , bool > :: value , \
546 "this operation is only allowed for booleans" ) ;
554 #define OPEQ_FUNC(OPFUNC,OPEQ,CONSTRAINT) \
555 simd_type & OPFUNC ( value_type rhs ) \
558 for ( size_type i = 0 ; i < vsize ; i++ ) \
559 (*this) [ i ] OPEQ rhs ; \
562 simd_type & OPFUNC ( simd_type rhs ) \
565 for ( size_type i = 0 ; i < vsize ; i++ ) \
566 (*this) [ i ] OPEQ rhs [ i ] ; \
591 #define C_PROMOTE(A,B) \
592 typename std::conditional \
593 < std::is_same < A , B > :: value , \
595 decltype ( std::declval < A > () \
596 + std::declval < B > () ) \
602#define OP_FUNC(OPFUNC,OP,CONSTRAINT) \
603 template < typename RHST , \
604 typename = typename std::enable_if \
605 < is_scalar < RHST > :: value \
608 simd_type < C_PROMOTE ( value_type , RHST ) , vsize > \
609 OPFUNC ( simd_type < RHST , vsize > rhs ) const \
612 simd_type < C_PROMOTE ( value_type , RHST ) , vsize > help ( *this ) ; \
613 for ( size_type i = 0 ; i < vsize ; i++ ) \
614 help [ i ] = ( (*this) [ i ] OP rhs [ i ] ) ; \
617 template < typename RHST , \
618 typename = typename std::enable_if \
619 < is_scalar < RHST > :: value \
622 simd_type < C_PROMOTE ( value_type , RHST ) , vsize > \
623 OPFUNC ( RHST rhs ) const \
626 simd_type < C_PROMOTE ( value_type , RHST ) , vsize > help ( *this ) ; \
627 for ( size_type i = 0 ; i < vsize ; i++ ) \
628 help [ i ] = ( (*this) [ i ] OP rhs ) ; \
631 template < typename LHST , \
632 typename = typename std::enable_if \
633 < is_scalar < LHST > :: value \
636 friend simd_type < C_PROMOTE ( LHST , value_type ) , vsize > \
637 OPFUNC ( LHST lhs , simd_type rhs ) \
640 simd_type < C_PROMOTE ( LHST , value_type ) , vsize > help ( lhs ) ; \
641 for ( size_type i = 0 ; i < vsize ; i++ ) \
642 help [ i ] = ( lhs OP rhs [ i ] ) ; \
663 #define OP_FUNC(OPFUNC,OP,CONSTRAINT) \
664 simd_type OPFUNC() const \
667 for ( size_type i = 0 ; i < vsize ; i++ ) \
668 help [ i ] = OP (*this) [ i ] ; \
707#define COMPARE_FUNC(OPFUNC,OP) \
708 template < typename RHST , \
709 typename = typename std::enable_if \
710 < is_scalar < RHST > :: value \
713 mask_type OPFUNC ( simd_type < RHST , vsize > rhs ) const \
716 for ( size_type i = 0 ; i < vsize ; i++ ) \
717 m [ i ] = ( (*this) [ i ] OP rhs [ i ] ) ; \
720 template < typename RHST , \
721 typename = typename std::enable_if \
722 < is_scalar < RHST > :: value \
725 mask_type OPFUNC ( RHST rhs ) const \
728 for ( size_type i = 0 ; i < vsize ; i++ ) \
729 m [ i ] = ( (*this) [ i ] OP rhs ) ; \
732 template < typename LHST , \
733 typename = typename std::enable_if \
734 < is_scalar < LHST > :: value \
737 friend mask_type OPFUNC ( LHST lhs , simd_type rhs ) \
740 for ( size_type i = 0 ; i < vsize ; i++ ) \
741 m [ i ] = ( lhs OP rhs [ i ] ) ; \
786 #define OPEQ_FUNC(OPFUNC,OPEQ,CONSTRAINT) \
787 simd_type & OPFUNC ( value_type rhs ) \
790 for ( size_type i = 0 ; i < vsize ; i++ ) \
792 if ( whether [ i ] ) \
793 whither [ i ] OPEQ rhs ; \
797 simd_type & OPFUNC ( simd_type rhs ) \
800 for ( size_type i = 0 ; i < vsize ; i++ ) \
802 if ( whether [ i ] ) \
803 whither [ i ] OPEQ rhs [ i ] ; \
849 for ( std::size_t i = 0 ; i <
vsize ; i++ )
851 if ( isInf ( rhs[i] ) )
859 for ( std::size_t i = 0 ; i <
vsize ; i++ )
861 if ( isNan ( rhs[i] ) )
873 #define CLAMP(FNAME,REL) \
874 simd_type FNAME ( simd_type threshold ) const \
876 simd_type result ( threshold ) ; \
877 for ( std::size_t i = 0 ; i < vsize ; i++ ) \
879 if ( (*this) [ i ] REL threshold ) \
880 result [ i ] = (*this) [ i ] ; \
897 for ( std::size_t e = 0 ; e <
vsize ; e++ )
909template <
typename T , std::
size_t vsize >
912 bool result = false ;
913 for ( std::size_t i = 0 ; i <
vsize ; i++ )
914 result |=
bool ( arg [ i ] ) ;
918template <
typename T , std::
size_t vsize >
922 for ( std::size_t i = 0 ; i <
vsize ; i++ )
923 result &=
bool ( arg [ i ] ) ;
927template <
typename T , std::
size_t vsize >
931 for ( std::size_t i = 0 ; i <
vsize ; i++ )
932 result &= ( !
bool ( arg [ i ] ) ) ;
938template <
typename T , std::
size_t N >
939struct std::allocator_traits <
vspline::simd_type < T , N > >
941 typedef std::allocator < vspline::simd_type < T , N > >
type ;
class template simd_type provides a fixed-size container type for small sets of fundamentals which ar...
COMPARE_FUNC(operator<,<)
void load(const value_type *const p_src)
COMPARE_FUNC(operator!=,!=)
friend simd_type abs(simd_type arg)
void rscatter(value_type *p_trg, const int &step) const
simd_type< bool, vsize > MaskType
void store(value_type *const p_trg) const
static mask_type isfinite(const simd_type &rhs)
simd_type(const simd_type &)=default
COMPARE_FUNC(operator>,>)
COMPARE_FUNC(operator>=,>=)
COMPARE_FUNC(operator==,==)
friend std::istream & operator>>(std::istream &isr, simd_type it)
void rgather(const value_type *const p_src, const int &step)
static const simd_type Zero()
static constexpr size_type size()
simd_type(const value_type &ini)
static const index_type IndexesFromZero()
void scatter(value_type *const p_trg, const index_type &indexes) const
friend std::ostream & operator<<(std::ostream &osr, simd_type it)
simd_type & operator=(const value_type &rhs)
static const simd_type iota()
simd_type< bool, vsize > mask_type
value_type & operator[](const size_type &i)
static mask_type isnegative(const simd_type &rhs)
simd_type< int, vsize > IndexType
COMPARE_FUNC(operator<=,<=)
static const size_type vsize
simd_type shuffle(index_type indexes)
static mask_type isnan(const simd_type &rhs)
static const index_type IndexesFrom(std::size_t start, std::size_t step=1)
simd_type(const value_type *const p_src, const index_type &indexes)
simd_type< int, vsize > index_type
void gather(const value_type *const p_src, const index_type &indexes)
masked_type operator()(mask_type mask)
static const simd_type One()
bool any_of(simd_type< T, vsize > arg)
bool none_of(simd_type< T, vsize > arg)
bool all_of(simd_type< T, vsize > arg)
typename std::integral_constant< bool, std::is_fundamental< T > ::value||std::is_same< T, bool > ::value > ::type is_scalar
#define BUILD_FROM_CONTAINER(SIZE_TYPE, VSZ)
#define BROADCAST_STD_FUNC3(FUNC)
#define OPEQ_FUNC(OPFUNC, OPEQ, CONSTRAINT)
#define BROADCAST_STD_FUNC(FUNC)
#define OP_FUNC(OPFUNC, OP, CONSTRAINT)
#define CLAMP(FNAME, REL)
#define BROADCAST_STD_FUNC2(FUNC)
std::allocator< vspline::simd_type< T, N > > type
masked_type(mask_type _whether, simd_type &_whither)