38 template <
typename Type>
41 operator Type()
const {
return simd.get (idx); }
58 template <
typename Scalar>
61 using vSIMDType =
typename SIMDNativeOps<Scalar>::vSIMDType;
63 static inline vSIMDType JUCE_VECTOR_CALLTYPE load (
const Scalar* a) noexcept
65 return SIMDNativeOps<Scalar>::load (a);
68 static inline void JUCE_VECTOR_CALLTYPE store (
vSIMDType value, Scalar* dest) noexcept
70 SIMDNativeOps<Scalar>::store (value, dest);
75 return SIMDNativeOps<Scalar>::expand (s);
78 static inline Scalar JUCE_VECTOR_CALLTYPE
get (
vSIMDType v, std::size_t i) noexcept
80 return SIMDNativeOps<Scalar>::get (v, i);
83 static inline vSIMDType JUCE_VECTOR_CALLTYPE
set (
vSIMDType v, std::size_t i, Scalar s) noexcept
85 return SIMDNativeOps<Scalar>::set (v, i, s);
88 static inline Scalar JUCE_VECTOR_CALLTYPE
sum (
vSIMDType a) noexcept
90 return SIMDNativeOps<Scalar>::sum (a);
95 return SIMDNativeOps<Scalar>::mul (a, b);
100 return SIMDNativeOps<Scalar>::multiplyAdd (a, b, c);
105 template <
typename Scalar>
106 struct CmplxSIMDOps<std::complex<Scalar>>
108 using vSIMDType =
typename SIMDNativeOps<Scalar>::vSIMDType;
110 static inline vSIMDType JUCE_VECTOR_CALLTYPE load (
const std::complex<Scalar>* a) noexcept
112 return SIMDNativeOps<Scalar>::load (reinterpret_cast<const Scalar*> (a));
115 static inline void JUCE_VECTOR_CALLTYPE store (vSIMDType value, std::complex<Scalar>* dest) noexcept
117 SIMDNativeOps<Scalar>::store (value, reinterpret_cast<Scalar*> (dest));
120 static inline vSIMDType JUCE_VECTOR_CALLTYPE
expand (std::complex<Scalar> s) noexcept
122 const int n =
sizeof (
vSIMDType) /
sizeof (Scalar);
127 Scalar floats[(size_t) n];
130 for (
int i = 0; i < n; ++i)
131 u.floats[i] = (i & 1) == 0 ? s.real() : s.imag();
136 static inline std::complex<Scalar> JUCE_VECTOR_CALLTYPE
get (vSIMDType v, std::size_t i) noexcept
139 return std::complex<Scalar> (SIMDNativeOps<Scalar>::get (v, j), SIMDNativeOps<Scalar>::get (v, j + 1));
142 static inline vSIMDType JUCE_VECTOR_CALLTYPE
set (vSIMDType v, std::size_t i, std::complex<Scalar> s) noexcept
145 return SIMDNativeOps<Scalar>::set (SIMDNativeOps<Scalar>::set (v, j, s.real()), j + 1, s.imag());
148 static inline std::complex<Scalar> JUCE_VECTOR_CALLTYPE
sum (vSIMDType a) noexcept
150 vSIMDType result = SIMDNativeOps<Scalar>::oddevensum (a);
151 auto* ptr =
reinterpret_cast<const Scalar*
> (&result);
152 return std::complex<Scalar> (ptr[0], ptr[1]);
155 static inline vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
157 return SIMDNativeOps<Scalar>::cmplxmul (a, b);
160 static inline vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept
162 return SIMDNativeOps<Scalar>::add (a, SIMDNativeOps<Scalar>::cmplxmul (b, c));
170 template <
typename Type>
177 template <
typename Type>
179 template <
typename Type>
ElementType sum() const noexcept
Returns a scalar which is the sum of all elements of the receiver.
static SIMDRegister JUCE_VECTOR_CALLTYPE min(SIMDRegister a, SIMDRegister b) noexcept
Returns a new vector where each element is the minimum of the corresponding element of a and b...
A wrapper around the platform's native SIMD register type.
static SIMDRegister JUCE_VECTOR_CALLTYPE expand(ElementType s) noexcept
Creates a new SIMDRegister from the corresponding scalar primitive.
SIMDRegister &JUCE_VECTOR_CALLTYPE operator=(ElementType s) noexcept
Broadcasts the scalar to all elements of the receiver.
void JUCE_VECTOR_CALLTYPE set(size_t idx, ElementType v) noexcept
Sets the idx-th element of the receiver.
typename NativeOps::vSIMDType vSIMDType
The native type (used internally).
static SIMDRegister JUCE_VECTOR_CALLTYPE max(SIMDRegister a, SIMDRegister b) noexcept
Returns a new vector where each element is the maximum of the corresponding element of a and b...