29 Numerics library [numerics]

29.10 Data-parallel types [simd]

29.10.8 basic_vec non-member operations [simd.nonmembers]

29.10.8.1 basic_vec binary operators [simd.binary]

friend constexpr basic_vec operator+(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec operator-(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec operator*(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec operator/(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec operator%(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec operator&(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec operator|(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec operator^(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec operator<<(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec operator>>(const basic_vec& lhs, const basic_vec& rhs) noexcept;
Let op be the operator.
Constraints: requires (value_type a, value_type b) { a op b; } is true.
Returns: A basic_vec object initialized with the results of applying op to lhs and rhs as a binary element-wise operation.
friend constexpr basic_vec operator<<(const basic_vec& v, simd-size-type n) noexcept; friend constexpr basic_vec operator>>(const basic_vec& v, simd-size-type n) noexcept;
Let op be the operator.
Constraints: requires (value_type a, simd-size-type b) { a op b; } is true.
Returns: A basic_vec object where the element is initialized to the result of applying op to v[i] and n for all i in the range of [0, size()).

29.10.8.2 basic_vec compound assignment [simd.cassign]

friend constexpr basic_vec& operator+=(basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec& operator-=(basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec& operator*=(basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec& operator/=(basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec& operator%=(basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec& operator&=(basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec& operator|=(basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec& operator^=(basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec& operator<<=(basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr basic_vec& operator>>=(basic_vec& lhs, const basic_vec& rhs) noexcept;
Let op be the operator.
Constraints: requires (value_type a, value_type b) { a op b; } is true.
Effects: These operators apply the indicated operator to lhs and rhs as an element-wise operation.
Returns: lhs.
friend constexpr basic_vec& operator<<=(basic_vec& lhs, simd-size-type n) noexcept; friend constexpr basic_vec& operator>>=(basic_vec& lhs, simd-size-type n) noexcept;
Let op be the operator.
Constraints: requires (value_type a, simd-size-type b) { a op b; } is true.
Effects: Equivalent to: return operator op (lhs, basic_vec(n));

29.10.8.3 basic_vec compare operators [simd.comparison]

friend constexpr mask_type operator==(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr mask_type operator!=(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr mask_type operator>=(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr mask_type operator<=(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr mask_type operator>(const basic_vec& lhs, const basic_vec& rhs) noexcept; friend constexpr mask_type operator<(const basic_vec& lhs, const basic_vec& rhs) noexcept;
Let op be the operator.
Constraints: requires (value_type a, value_type b) { a op b; } is true.
Returns: A basic_mask object initialized with the results of applying op to lhs and rhs as a binary element-wise operation.

29.10.8.4 vec complex accessors [simd.complex.access]

constexpr auto real() const noexcept; constexpr auto imag() const noexcept;
Constraints: simd-complex<basic_vec> is modeled.
Returns: An object of type rebind_t<typename T​::​value_type, basic_vec> where the element is initialized to the result of cmplx-func(operator[](i)) for all i in the range [0, size()), where cmplx-func is the corresponding function from <complex>.
template<simd-floating-point V> constexpr void real(const V& v) noexcept; template<simd-floating-point V> constexpr void imag(const V& v) noexcept;
Constraints:
  • simd-complex<basic_vec> is modeled,
  • same_as<typename V​::​value_type, typename T​::​value_type> is modeled, and
  • V​::​size() == size() is true.
Effects: Replaces each element of the basic_vec object such that the element is replaced with value_type(v[i], operator[](i).imag()) or value_type(operator[](i).real(), v[i]) for real and imag respectively, for all i in the range [0, size()).

29.10.8.5 basic_vec exposition only conditional operators [simd.cond]

friend constexpr basic_vec simd-select-impl(const mask_type& mask, const basic_vec& a, const basic_vec& b) noexcept;
Returns: A basic_vec object where the element equals mask[i] ? a[i] : b[i] for all i in the range of [0, size()).

29.10.8.6 basic_vec reductions [simd.reductions]

template<class T, class Abi, class BinaryOperation = plus<>> constexpr T reduce(const basic_vec<T, Abi>& x, BinaryOperation binary_op = {});
Constraints: BinaryOperation models reduction-binary-operation<T>.
Preconditions: binary_op does not modify x.
Returns: GENERALIZED_SUM(binary_op, vec<T, 1>(x[0]), …, vec<T, 1>(x[x.size() - 1]))[​0] ([numerics.defns]).
Throws: Any exception thrown from binary_op.
template<class T, class Abi, class BinaryOperation = plus<>> constexpr T reduce( const basic_vec<T, Abi>& x, const typename basic_vec<T, Abi>::mask_type& mask, BinaryOperation binary_op = {}, type_identity_t<T> identity_element = see below);
Constraints:
  • BinaryOperation models reduction-binary-operation<T>.
  • An argument for identity_element is provided for the invocation, unless BinaryOperation is one of plus<>, multiplies<>, bit_and<>, bit_or<>, or bit_xor<>.
Preconditions:
  • binary_op does not modify x.
  • For all finite values y representable by T, the results of y == binary_op(vec<T, 1>(identity_element), vec<T, 1>(y))[0] and y == binary_op(vec<T, 1>(y), vec<T, 1>(identity_element))[0] are true.
Returns: If none_of(mask) is true, returns identity_element.
Otherwise, returns GENERALIZED_SUM(binary_op, vec<T, 1>(x[]), …, vec<T, 1>(x[]))[0] where are the selected indices of mask.
Throws: Any exception thrown from binary_op.
Remarks: The default argument for identity_element is equal to
  • T() if BinaryOperation is plus<>,
  • T(1) if BinaryOperation is multiplies<>,
  • T(~T()) if BinaryOperation is bit_and<>,
  • T() if BinaryOperation is bit_or<>, or
  • T() if BinaryOperation is bit_xor<>.
template<class T, class Abi> constexpr T reduce_min(const basic_vec<T, Abi>& x) noexcept;
Constraints: T models totally_ordered.
Returns: The value of an element x[j] for which x[i] < x[j] is false for all i in the range of [0, basic_vec<T, Abi>​::​size()).
template<class T, class Abi> constexpr T reduce_min( const basic_vec<T, Abi>&, const typename basic_vec<T, Abi>::mask_type&) noexcept;
Constraints: T models totally_ordered.
Returns: If none_of(mask) is true, returns numeric_limits<T>​::​max().
Otherwise, returns the value of a selected element x[j] for which x[i] < x[j] is false for all selected indices i of mask.
template<class T, class Abi> constexpr T reduce_max(const basic_vec<T, Abi>& x) noexcept;
Constraints: T models totally_ordered.
Returns: The value of an element x[j] for which x[j] < x[i] is false for all i in the range of [0, basic_vec<T, Abi>​::​size()).
template<class T, class Abi> constexpr T reduce_max( const basic_vec<T, Abi>&, const typename basic_vec<T, Abi>::mask_type&) noexcept;
Constraints: T models totally_ordered.
Returns: If none_of(mask) is true, returns numeric_limits<V​::​value_type>​::​lowest().
Otherwise, returns the value of a selected element x[j] for which x[j] < x[i] is false for all selected indices i of mask.

29.10.8.7 basic_vec load and store functions [simd.loadstore]

template<class V = see below, ranges::contiguous_range R, class... Flags> requires ranges::sized_range<R> constexpr V unchecked_load(R&& r, flags<Flags...> f = {}); template<class V = see below, ranges::contiguous_range R, class... Flags> requires ranges::sized_range<R> constexpr V unchecked_load(R&& r, const typename V::mask_type& mask, flags<Flags...> f = {}); template<class V = see below, contiguous_iterator I, class... Flags> constexpr V unchecked_load(I first, iter_difference_t<I> n, flags<Flags...> f = {}); template<class V = see below, contiguous_iterator I, class... Flags> constexpr V unchecked_load(I first, iter_difference_t<I> n, const typename V::mask_type& mask, flags<Flags...> f = {}); template<class V = see below, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags> constexpr V unchecked_load(I first, S last, flags<Flags...> f = {}); template<class V = see below, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags> constexpr V unchecked_load(I first, S last, const typename V::mask_type& mask, flags<Flags...> f = {});
Let
  • mask be V​::​mask_type(true) for the overloads with no mask parameter;
  • R be span<const iter_value_t<I>> for the overloads with no template parameter R;
  • r be R(first, n) for the overloads with an n parameter and R(first, last) for the overloads with a last parameter.
Mandates: If ranges​::​size(r) is a constant expression then ranges​::​size(r)  ≥  V​::​size().
Preconditions:
  • [first, first + n) is a valid range for the overloads with an n parameter.
  • [first, last) is a valid range for the overloads with a last parameter.
  • ranges​::​size(r)  ≥  V​::​size()
Effects: Equivalent to: return partial_load<V>(r, mask, f);
Remarks: The default argument for template parameter V is basic_vec<ranges​::​range_value_t<R>>.
template<class V = see below, ranges::contiguous_range R, class... Flags> requires ranges::sized_range<R> constexpr V partial_load(R&& r, flags<Flags...> f = {}); template<class V = see below, ranges::contiguous_range R, class... Flags> requires ranges::sized_range<R> constexpr V partial_load(R&& r, const typename V::mask_type& mask, flags<Flags...> f = {}); template<class V = see below, contiguous_iterator I, class... Flags> constexpr V partial_load(I first, iter_difference_t<I> n, flags<Flags...> f = {}); template<class V = see below, contiguous_iterator I, class... Flags> constexpr V partial_load(I first, iter_difference_t<I> n, const typename V::mask_type& mask, flags<Flags...> f = {}); template<class V = see below, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags> constexpr V partial_load(I first, S last, flags<Flags...> f = {}); template<class V = see below, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags> constexpr V partial_load(I first, S last, const typename V::mask_type& mask, flags<Flags...> f = {});
Let
  • mask be V​::​mask_type(true) for the overloads with no mask parameter;
  • R be span<const iter_value_t<I>> for the overloads with no template parameter R;
  • r be R(first, n) for the overloads with an n parameter and R(first, last) for the overloads with a last parameter.
Mandates:
  • ranges​::​range_value_t<R> is a vectorizable type,
  • same_as<remove_cvref_t<V>, V> is true,
  • V is an enabled specialization of basic_vec, and
  • if the template parameter pack Flags does not contain convert-flag, then the conversion from ranges​::​range_value_t<R> to V​::​value_type is value-preserving.
Preconditions:
  • [first, first + n) is a valid range for the overloads with an n parameter.
  • [first, last) is a valid range for the overloads with a last parameter.
  • If the template parameter pack Flags contains aligned-flag, ranges​::​data(r) points to storage aligned by alignment_v<V, ranges​::​range_value_t<R>>.
  • If the template parameter pack Flags contains overaligned-flag<N>, ranges​::​data(r) points to storage aligned by N.
Effects: Initializes the element with
mask[i] && i < ranges​::​size(r) ? static_cast<T>(​ranges​::​data(r)[i]) : T() for all i in the range of [0, V​::​size()).
Remarks: The default argument for template parameter V is basic_vec<ranges​::​range_value_t<R>>.
template<class T, class Abi, ranges::contiguous_range R, class... Flags> requires ranges::sized_range<R> && indirectly_writable<ranges::iterator_t<R>, T> constexpr void unchecked_store(const basic_vec<T, Abi>& v, R&& r, flags<Flags...> f = {}); template<class T, class Abi, ranges::contiguous_range R, class... Flags> requires ranges::sized_range<R> && indirectly_writable<ranges::iterator_t<R>, T> constexpr void unchecked_store(const basic_vec<T, Abi>& v, R&& r, const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {}); template<class T, class Abi, contiguous_iterator I, class... Flags> requires indirectly_writable<I, T> constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n, flags<Flags...> f = {}); template<class T, class Abi, contiguous_iterator I, class... Flags> requires indirectly_writable<I, T> constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n, const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {}); template<class T, class Abi, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags> requires indirectly_writable<I, T> constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, S last, flags<Flags...> f = {}); template<class T, class Abi, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags> requires indirectly_writable<I, T> constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, S last, const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
Let
  • mask be basic_vec<T, Abi>​::​mask_type(true) for the overloads with no mask parameter;
  • R be span<iter_value_t<I>> for the overloads with no template parameter R;
  • r be R(first, n) for the overloads with an n parameter and R(first, last) for the overloads with a last parameter.
Mandates: If ranges​::​size(r) is a constant expression then ranges​::​size(r)  ≥  simd-size-v<T, Abi>.
Preconditions:
  • [first, first + n) is a valid range for the overloads with an n parameter.
  • [first, last) is a valid range for the overloads with a last parameter.
  • ranges​::​size(r)  ≥  simd-size-v<T, Abi>
Effects: Equivalent to: partial_store(v, r, mask, f).
template<class T, class Abi, ranges::contiguous_range R, class... Flags> requires ranges::sized_range<R> && indirectly_writable<ranges::iterator_t<R>, T> constexpr void partial_store(const basic_vec<T, Abi>& v, R&& r, flags<Flags...> f = {}); template<class T, class Abi, ranges::contiguous_range R, class... Flags> requires ranges::sized_range<R> && indirectly_writable<ranges::iterator_t<R>, T> constexpr void partial_store(const basic_vec<T, Abi>& v, R&& r, const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {}); template<class T, class Abi, contiguous_iterator I, class... Flags> requires indirectly_writable<I, T> constexpr void partial_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n, flags<Flags...> f = {}); template<class T, class Abi, contiguous_iterator I, class... Flags> requires indirectly_writable<I, T> constexpr void partial_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n, const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {}); template<class T, class Abi, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags> requires indirectly_writable<I, T> constexpr void partial_store(const basic_vec<T, Abi>& v, I first, S last, flags<Flags...> f = {}); template<class T, class Abi, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags> requires indirectly_writable<I, T> constexpr void partial_store(const basic_vec<T, Abi>& v, I first, S last, const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
Let
  • mask be basic_vec<T, Abi>​::​mask_type(true) for the overloads with no mask parameter;
  • R be span<iter_value_t<I>> for the overloads with no template parameter R;
  • r be R(first, n) for the overloads with an n parameter and R(first, last) for the overloads with a last parameter.
Mandates:
  • ranges​::​range_value_t<R> is a vectorizable type, and
  • if the template parameter pack Flags does not contain convert-flag, then the conversion from T to ranges​::​range_value_t<R> is value-preserving.
Preconditions:
  • [first, first + n) is a valid range for the overloads with an n parameter.
  • [first, last) is a valid range for the overloads with a last parameter.
  • If the template parameter pack Flags contains aligned-flag, ranges​::​data(r) points to storage aligned by alignment_v<basic_vec<T, Abi>, ranges​::​range_value_t<R>>.
  • If the template parameter pack Flags contains overaligned-flag<N>, ranges​::​data(r) points to storage aligned by N.
Effects: For all i in the range of [0, basic_vec<T, Abi>​::​size()), if mask[i] && i < ranges​::​​size(r) is true, evaluates ranges​::​data(r)[i] = v[i].

29.10.8.8 vec static permute [simd.permute.static]

template<simd-size-type N = see below, simd-vec-type V, class IdxMap> constexpr resize_t<N, V> permute(const V& v, IdxMap&& idxmap); template<simd-size-type N = see below, simd-mask-type M, class IdxMap> constexpr resize_t<N, M> permute(const M& v, IdxMap&& idxmap);
Let:
  • gen-fn(i) be idxmap(i, V​::​size()) if that expression is well-formed, and idxmap(i) otherwise.
  • perm-fn be the following exposition-only function template: template<simd-size-type I> typename V::value_type perm-fn() { constexpr auto src_index = gen-fn(I); if constexpr (src_index == zero_element) { return typename V::value_type(); } else if constexpr (src_index == uninit_element) { return unspecified-value; } else { return v[src_index]; } }
Constraints: integral<invoke_result_t<IdxMap&, simd-size-type>> || integral<invoke_result_t<IdxMap&, simd-size-type, simd-size-type>> is true.
Mandates: gen-fn(i) is a constant expression whose value is zero_element, uninit_element, or in the range [0, V​::​size()), for all i in the range [0, N).
Returns: A data-parallel object where the element is initialized to the result of perm-fn<i>() for all i in the range [0, N).
Remarks: The default argument for template parameter N is V​::​size().

29.10.8.9 vec dynamic permute [simd.permute.dynamic]

template<simd-vec-type V, simd-integral I> constexpr resize_t<I::size(), V> permute(const V& v, const I& indices); template<simd-mask-type M, simd-integral I> constexpr resize_t<I::size(), M> permute(const M& v, const I& indices);
Preconditions: All values in indices are in the range [0, V​::​size()).
Returns: A data-parallel object where the element is initialized to the result of v[indices[i]] for all i in the range [0, I​::​size()).

29.10.8.10 vec mask permute [simd.permute.mask]

template<simd-vec-type V> constexpr V compress(const V& v, const typename V::mask_type& selector); template<simd-mask-type M> constexpr M compress(const M& v, const type_identity_t<M>& selector);
Let:
  • bit-index(i) be a function which returns the index of the element of selector that is true.
  • select-value(i) be a function which returns v[bit-index(i)] for i in the range [0, reduce_count(selector)) and a valid but unspecified value otherwise.
    [Note 1: 
    Different calls to select-value can return different unspecified values.
    — end note]
Returns: A data-parallel object where the element is initialized to the result of select-value(i) for all i in the range [0, V​::​size()).
template<simd-vec-type V> constexpr V compress(const V& v, const typename V::mask_type& selector, const typename V::value_type& fill_value); template<simd-mask-type M> constexpr M compress(const M& v, const type_identity_t<M>& selector, const typename V::value_type& fill_value);
Let:
  • bit-index(i) be a function which returns the index of the element of selector that is true.
  • select-value(i) be a function which returns v[bit-index(i)] for i in the range [0, reduce_count(selector)) and fill_value otherwise.
Returns: A data-parallel object where the element is initialized to the result of select-value(i) for all i in the range [0, V​::​size()).
template<simd-vec-type V> constexpr V expand(const V& v, const typename V::mask_type& selector, const V& original = {}); template<simd-mask-type M> constexpr M expand(const M& v, const type_identity_t<M>& selector, const M& original = {});
Let:
  • set-indices be a list of the index positions of true elements in selector.
  • bit-lookup(b) be a function which returns the index where b appears in set-indices.
  • select-value(i) be a function which returns v[bit-lookup(i)] if selector[i] is true, otherwise returns original[i].
Returns: A data-parallel object where the element is initialized to the result of select-value(i) for all i in the range [0, V​::​size()).

29.10.8.11 simd memory permute [simd.permute.memory]

template<class V = see below, ranges::contiguous_range R, simd-integral I, class... Flags> requires ranges::sized_range<R> constexpr V unchecked_gather_from(R&& in, const I& indices, flags<Flags...> f = {}); template<class V = see below, ranges::contiguous_range R, simd-integral I, class... Flags> requires ranges::sized_range<R> constexpr V unchecked_gather_from(R&& in, const typename I::mask_type& mask, const I& indices, flags<Flags...> f = {});
Let mask be typename I​::​mask_type(true) for the overload with no mask parameter.
Preconditions: All values in select(mask, indices, typename I​::​value_type()) are in the range [0, ranges​::​size(in)).
Effects: Equivalent to: return partial_gather_from<V>(in, mask, indices, f);
Remarks: The default argument for template parameter V is vec<ranges​::​range_value_t<R>, I​::​​size()>.
template<class V = see below, ranges::contiguous_range R, simd-integral I, class... Flags> requires ranges::sized_range<R> constexpr V partial_gather_from(R&& in, const I& indices, flags<Flags...> f = {}); template<class V = see below, ranges::contiguous_range R, simd-integral I, class... Flags> requires ranges::sized_range<R> constexpr V partial_gather_from(R&& in, const typename I::mask_type& mask, const I& indices, flags<Flags...> f = {});
Let:
  • mask be typename I​::​mask_type(true) for the overload with no mask parameter;
  • T be typename V​::​value_type.
Mandates:
  • ranges​::​range_value_t<R> is a vectorizable type,
  • same_as<remove_cvref_t<V>, V> is true,
  • V is an enabled specialization of basic_vec,
  • V​::​size() == I​::​size() is true, and
  • if the template parameter pack Flags does not contain convert-flag, then the conversion from ranges​::​range_value_t<R> to T is value-preserving.
Preconditions:
  • If the template parameter pack Flags contains aligned-flag, ranges​::​data(in) points to storage aligned by alignment_v<V, ranges​::​range_value_t<R>>.
  • If the template parameter pack Flags contains overaligned-flag<N>, ranges​::​data(in) points to storage aligned by N.
Returns: A basic_vec object where the element is initialized to the result of mask[i] && indices[i] < ranges::size(in) ? static_cast<T>(ranges::data(in)[indices[i]]) : T() for all i in the range [0, I​::​size()).
Remarks: The default argument for template parameter V is vec<ranges​::​range_value_t<R>, I​::​​size()>.
template<simd-vec-type V, ranges::contiguous_range R, simd-integral I, class... Flags> requires ranges::sized_range<R> constexpr void unchecked_scatter_to(const V& v, R&& out, const I& indices, flags<Flags...> f = {}); template<simd-vec-type V, ranges::contiguous_range R, simd-integral I, class... Flags> requires ranges::sized_range<R> constexpr void unchecked_scatter_to(const V& v, R&& out, const typename I::mask_type& mask, const I& indices, flags<Flags...> f = {});
Let mask be typename I​::​mask_type(true) for the overload with no mask parameter.
Preconditions: All values in select(mask, indices, typename I​::​value_type()) are in the range [0, ranges​::​size(out)).
Effects: Equivalent to: partial_scatter_to(v, out, mask, indices, f);
template<simd-vec-type V, ranges::contiguous_range R, simd-integral I, class... Flags> requires ranges::sized_range<R> constexpr void partial_scatter_to(const V& v, R&& out, const I& indices, flags<Flags...> f = {}); template<simd-vec-type V, ranges::contiguous_range R, simd-integral I, class... Flags> requires ranges::sized_range<R> constexpr void partial_scatter_to(const V& v, R&& out, const typename I::mask_type& mask, const I& indices, flags<Flags...> f = {});
Let mask be typename I​::​mask_type(true) for the overload with no mask parameter.
Constraints: V​::​size() == I​::​size() is true.
Mandates:
  • ranges​::​range_value_t<R> is a vectorizable type, and
  • if the template parameter pack Flags does not contain convert-flag, then the conversion from typename V​::​value_type to ranges​::​range_value_t<R> is value-preserving.
Preconditions:
  • For all selected indices i the values indices[i] are unique.
  • If the template parameter pack Flags contains aligned-flag, ranges​::​data(out) points to storage aligned by alignment_v<V, ranges​::​range_value_t<R>>.
  • If the template parameter pack Flags contains overaligned-flag<N>, ranges​::​data(out) points to storage aligned by N.
Effects: For all i in the range [0, I​::​size()), if mask[i] && (indices[i] < ranges​::​size(out)) is true, evaluates ranges​::​data(out)[indices[i]] = v[i].

29.10.8.12 basic_vec and basic_mask creation [simd.creation]

template<class T, class Abi> constexpr auto chunk(const basic_vec<typename T::value_type, Abi>& x) noexcept; template<class T, class Abi> constexpr auto chunk(const basic_mask<mask-element-size<T>, Abi>& x) noexcept;
Constraints:
  • For the first overload, T is an enabled specialization of basic_vec.
    If basic_vec<​typename T​::​​value_type, Abi>​::​size() % T​::​size() is not 0, then resize_t<basic_vec<​typename T​::​​value_type, Abi>​::​size() % T​::​size(), T> is valid and denotes a type.
  • For the second overload, T is an enabled specialization of basic_mask.
    If basic_mask<mask-element-size<T>, Abi>​::​size() % T​::​size() is not 0, then resize_t<​basic_mask<​mask-element-size<T>, Abi>​::​size() % T​::​size(), T> is valid and denotes a type.
Let N be x.size() / T​::​size().
Returns:
  • If x.size() % T​::​size() == 0 is true, an array<T, N> with the basic_vec or basic_mask element of the array element initialized to the value of the element in x with index i + j * T​::​size().
  • Otherwise, a tuple of N objects of type T and one object of type resize_t<x.size() % T​::​size(), T>.
    The basic_vec or basic_mask element of the tuple element of type T is initialized to the value of the element in x with index i + j * T​::​size().
    The basic_vec or basic_mask element of the tuple element is initialized to the value of the element in x with index i + N * T​::​size().
template<simd-size-type N, class T, class Abi> constexpr auto chunk(const basic_vec<T, Abi>& x) noexcept;
Effects: Equivalent to: return chunk<resize_t<N, basic_vec<T, Abi>>>(x);
template<simd-size-type N, size_t Bytes, class Abi> constexpr auto chunk(const basic_mask<Bytes, Abi>& x) noexcept;
Effects: Equivalent to: return chunk<resize_t<N, basic_mask<Bytes, Abi>>>(x);
template<class T, class... Abis> constexpr vec<T, (basic_vec<T, Abis>::size() + ...)> cat(const basic_vec<T, Abis>&... xs) noexcept; template<size_t Bytes, class... Abis> constexpr basic_mask<Bytes, deduce-abi-t<integer-from<Bytes>, (basic_mask<Bytes, Abis>::size() + ...)>> cat(const basic_mask<Bytes, Abis>&... xs) noexcept;
Constraints:
  • For the first overload vec<T, (basic_vec<T, Abis>​::​size() + ...)> is enabled.
  • For the second overload basic_mask<Bytes, deduce-abi-t<integer-from<Bytes>, (basic_mask<Bytes, Abis>​::​size() + ...)>> is enabled.
Returns: A data-parallel object initialized with the concatenated values in the xs pack of data-parallel objects: The basic_vec/basic_mask element of the parameter in the xs pack is copied to the return value's element with index i + the sum of the width of the first j parameters in the xs pack.

29.10.8.13 Algorithms [simd.alg]

template<class T, class Abi> constexpr basic_vec<T, Abi> min(const basic_vec<T, Abi>& a, const basic_vec<T, Abi>& b) noexcept;
Constraints: T models totally_ordered.
Returns: The result of the element-wise application of min(a[i], b[i]) for all i in the range of [0, basic_vec<T, Abi>​::​size()).
template<class T, class Abi> constexpr basic_vec<T, Abi> max(const basic_vec<T, Abi>& a, const basic_vec<T, Abi>& b) noexcept;
Constraints: T models totally_ordered.
Returns: The result of the element-wise application of max(a[i], b[i]) for all i in the range of [0, basic_vec<T, Abi>​::​size()).
template<class T, class Abi> constexpr pair<basic_vec<T, Abi>, basic_vec<T, Abi>> minmax(const basic_vec<T, Abi>& a, const basic_vec<T, Abi>& b) noexcept;
Effects: Equivalent to: return pair{min(a, b), max(a, b)};
template<class T, class Abi> constexpr basic_vec<T, Abi> clamp( const basic_vec<T, Abi>& v, const basic_vec<T, Abi>& lo, const basic_vec<T, Abi>& hi);
Constraints: T models totally_ordered.
Preconditions: No element in lo shall be greater than the corresponding element in hi.
Returns: The result of element-wise application of clamp(v[i], lo[i], hi[i]) for all i in the range of [0, basic_vec<T, Abi>​::​size()).
template<class T, class U> constexpr auto select(bool c, const T& a, const U& b) -> remove_cvref_t<decltype(c ? a : b)>;
Effects: Equivalent to: return c ? a : b;
template<size_t Bytes, class Abi, class T, class U> constexpr auto select(const basic_mask<Bytes, Abi>& c, const T& a, const U& b) noexcept -> decltype(simd-select-impl(c, a, b));
Effects: Equivalent to: return simd-select-impl(c, a, b); where simd-select-impl is found by argument-dependent lookup ([basic.lookup.argdep]) contrary to [contents].

29.10.8.14 Mathematical functions [simd.math]

template<math-floating-point V> constexpr rebind_t<int, deduced-vec-t<V>> ilogb(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> ldexp(const V& x, const rebind_t<int, deduced-vec-t<V>>& exp); template<math-floating-point V> constexpr deduced-vec-t<V> scalbn(const V& x, const rebind_t<int, deduced-vec-t<V>>& n); template<math-floating-point V> constexpr deduced-vec-t<V> scalbln(const V& x, const rebind_t<long int, deduced-vec-t<V>>& n); template<signed_integral T, class Abi> constexpr basic_vec<T, Abi> abs(const basic_vec<T, Abi>& j); template<math-floating-point V> constexpr deduced-vec-t<V> abs(const V& j); template<math-floating-point V> constexpr deduced-vec-t<V> fabs(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> ceil(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> floor(const V& x); template<math-floating-point V> deduced-vec-t<V> nearbyint(const V& x); template<math-floating-point V> deduced-vec-t<V> rint(const V& x); template<math-floating-point V> rebind_t<long int, deduced-vec-t<V>> lrint(const V& x); template<math-floating-point V> rebind_t<long long int, deduced-vec-t<V>> llrint(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> round(const V& x); template<math-floating-point V> constexpr rebind_t<long int, deduced-vec-t<V>> lround(const V& x); template<math-floating-point V> constexpr rebind_t<long long int, deduced-vec-t<V>> llround(const V& x); template<class V0, class V1> constexpr math-common-simd-t<V0, V1> fmod(const V0& x, const V1& y); template<math-floating-point V> constexpr deduced-vec-t<V> trunc(const V& x); template<class V0, class V1> constexpr math-common-simd-t<V0, V1> remainder(const V0& x, const V1& y); template<class V0, class V1> constexpr math-common-simd-t<V0, V1> copysign(const V0& x, const V1& y); template<class V0, class V1> constexpr math-common-simd-t<V0, V1> nextafter(const V0& x, const V1& y); template<class V0, class V1> constexpr math-common-simd-t<V0, V1> fdim(const V0& x, const V1& y); template<class V0, class V1> constexpr math-common-simd-t<V0, V1> fmax(const V0& x, const V1& y); template<class V0, class V1> constexpr math-common-simd-t<V0, V1> fmin(const V0& x, const V1& y); template<class V0, class V1, class V2> constexpr math-common-simd-t<V0, V1, V2> fma(const V0& x, const V1& y, const V2& z); template<math-floating-point V> constexpr rebind_t<int, deduced-vec-t<V>> fpclassify(const V& x); template<math-floating-point V> constexpr typename deduced-vec-t<V>::mask_type isfinite(const V& x); template<math-floating-point V> constexpr typename deduced-vec-t<V>::mask_type isinf(const V& x); template<math-floating-point V> constexpr typename deduced-vec-t<V>::mask_type isnan(const V& x); template<math-floating-point V> constexpr typename deduced-vec-t<V>::mask_type isnormal(const V& x); template<math-floating-point V> constexpr typename deduced-vec-t<V>::mask_type signbit(const V& x); template<class V0, class V1> constexpr typename math-common-simd-t<V0, V1>::mask_type isgreater(const V0& x, const V1& y); template<class V0, class V1> constexpr typename math-common-simd-t<V0, V1>::mask_type isgreaterequal(const V0& x, const V1& y); template<class V0, class V1> constexpr typename math-common-simd-t<V0, V1>::mask_type isless(const V0& x, const V1& y); template<class V0, class V1> constexpr typename math-common-simd-t<V0, V1>::mask_type islessequal(const V0& x, const V1& y); template<class V0, class V1> constexpr typename math-common-simd-t<V0, V1>::mask_type islessgreater(const V0& x, const V1& y); template<class V0, class V1> constexpr typename math-common-simd-t<V0, V1>::mask_type isunordered(const V0& x, const V1& y);
Let Ret denote the return type of the specialization of a function template with the name math-func.
Let math-func-vec denote: template<class... Args> Ret math-func-vec(Args... args) { return Ret([&](simd-size-type i) { math-func(make-compatible-simd-t<Ret, Args>(args)[i]...); }); }
Returns: A value ret of type Ret, that is element-wise equal to the result of calling math-func-vec with the arguments of the above functions.
If in an invocation of a scalar overload of math-func for index i in math-func-vec a domain, pole, or range error would occur, the value of ret[i] is unspecified.
Remarks: It is unspecified whether errno ([errno]) is accessed.
template<math-floating-point V> constexpr deduced-vec-t<V> acos(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> asin(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> atan(const V& x); template<class V0, class V1> constexpr math-common-simd-t<V0, V1> atan2(const V0& y, const V1& x); template<math-floating-point V> constexpr deduced-vec-t<V> cos(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> sin(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> tan(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> acosh(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> asinh(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> atanh(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> cosh(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> sinh(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> tanh(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> exp(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> exp2(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> expm1(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> log(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> log10(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> log1p(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> log2(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> logb(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> cbrt(const V& x); template<class V0, class V1> constexpr math-common-simd-t<V0, V1> hypot(const V0& x, const V1& y); template<class V0, class V1, class V2> constexpr math-common-simd-t<V0, V1, V2> hypot(const V0& x, const V1& y, const V2& z); template<class V0, class V1> constexpr math-common-simd-t<V0, V1> pow(const V0& x, const V1& y); template<math-floating-point V> constexpr deduced-vec-t<V> sqrt(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> erf(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> erfc(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> lgamma(const V& x); template<math-floating-point V> constexpr deduced-vec-t<V> tgamma(const V& x); template<class V0, class V1, class V2> constexpr math-common-simd-t<V0, V1, V2> lerp(const V0& a, const V1& b, const V2& t) noexcept; template<math-floating-point V> deduced-vec-t<V> assoc_laguerre(const rebind_t<unsigned, deduced-vec-t<V>>& n, const rebind_t<unsigned, deduced-vec-t<V>>& m, const V& x); template<math-floating-point V> deduced-vec-t<V> assoc_legendre(const rebind_t<unsigned, deduced-vec-t<V>>& l, const rebind_t<unsigned, deduced-vec-t<V>>& m, const V& x); template<class V0, class V1> math-common-simd-t<V0, V1> beta(const V0& x, const V1& y); template<math-floating-point V> deduced-vec-t<V> comp_ellint_1(const V& k); template<math-floating-point V> deduced-vec-t<V> comp_ellint_2(const V& k); template<class V0, class V1> math-common-simd-t<V0, V1> comp_ellint_3(const V0& k, const V1& nu); template<class V0, class V1> math-common-simd-t<V0, V1> cyl_bessel_i(const V0& nu, const V1& x); template<class V0, class V1> math-common-simd-t<V0, V1> cyl_bessel_j(const V0& nu, const V1& x); template<class V0, class V1> math-common-simd-t<V0, V1> cyl_bessel_k(const V0& nu, const V1& x); template<class V0, class V1> math-common-simd-t<V0, V1> cyl_neumann(const V0& nu, const V1& x); template<class V0, class V1> math-common-simd-t<V0, V1> ellint_1(const V0& k, const V1& phi); template<class V0, class V1> math-common-simd-t<V0, V1> ellint_2(const V0& k, const V1& phi); template<class V0, class V1, class V2> math-common-simd-t<V0, V1, V2> ellint_3(const V0& k, const V1& nu, const V2& phi); template<math-floating-point V> deduced-vec-t<V> expint(const V& x); template<math-floating-point V> deduced-vec-t<V> hermite(const rebind_t<unsigned, deduced-vec-t<V>>& n, const V& x); template<math-floating-point V> deduced-vec-t<V> laguerre(const rebind_t<unsigned, deduced-vec-t<V>>& n, const V& x); template<math-floating-point V> deduced-vec-t<V> legendre(const rebind_t<unsigned, deduced-vec-t<V>>& l, const V& x); template<math-floating-point V> deduced-vec-t<V> riemann_zeta(const V& x); template<math-floating-point V> deduced-vec-t<V> sph_bessel(const rebind_t<unsigned, deduced-vec-t<V>>& n, const V& x); template<math-floating-point V> deduced-vec-t<V> sph_legendre(const rebind_t<unsigned, deduced-vec-t<V>>& l, const rebind_t<unsigned, deduced-vec-t<V>>& m, const V& theta); template<math-floating-point V> deduced-vec-t<V> sph_neumann(const rebind_t<unsigned, deduced-vec-t<V>>& n, const V& x);
Let Ret denote the return type of the specialization of a function template with the name math-func.
Let math-func-vec denote: template<class... Args> Ret math-func-vec(Args... args) { return Ret([&](simd-size-type i) { math-func(make-compatible-simd-t<Ret, Args>(args)[i]...); }); }
Returns: A value ret of type Ret, that is element-wise approximately equal to the result of calling math-func-vec with the arguments of the above functions.
If in an invocation of a scalar overload of math-func for index i in math-func-vec a domain, pole, or range error would occur, the value of ret[i] is unspecified.
Remarks: It is unspecified whether errno ([errno]) is accessed.
template<math-floating-point V> constexpr deduced-vec-t<V> frexp(const V& value, rebind_t<int, deduced-vec-t<V>>* exp);
Let Ret be deduced-vec-t<V>.
Let frexp-vec denote: template<class V> pair<Ret, rebind_t<int, Ret>> frexp-vec(const V& x) { int r1[Ret::size()]; Ret r0([&](simd-size-type i) { frexp(make-compatible-simd-t<Ret, V>(x)[i], &r1[i]); }); return {r0, rebind_t<int, Ret>(r1)}; }
Let ret be a value of type pair<Ret, rebind_t<int, Ret>> that is the same value as the result of calling frexp-vec(x).
Effects: Sets *exp to ret.second.
Returns: ret.first.
template<class V0, class V1> constexpr math-common-simd-t<V0, V1> remquo(const V0& x, const V1& y, rebind_t<int, math-common-simd-t<V0, V1>>* quo);
Let Ret be math-common-simd-t<V0, V1>.
Let remquo-vec denote: template<class V0, class V1> pair<Ret, rebind_t<int, Ret>> remquo-vec(const V0& x, const V1& y) { int r1[Ret::size()]; Ret r0([&](simd-size-type i) { remquo(make-compatible-simd-t<Ret, V0>(x)[i], make-compatible-simd-t<Ret, V1>(y)[i], &r1[i]); }); return {r0, rebind_t<int, Ret>(r1)}; }
Let ret be a value of type pair<Ret, rebind_t<int, Ret>> that is the same value as the result of calling remquo-vec(x, y).
If in an invocation of a scalar overload of remquo for index i in remquo-vec a domain, pole, or range error would occur, the value of ret[i] is unspecified.
Effects: Sets *quo to ret.second.
Returns: ret.first.
Remarks: It is unspecified whether errno ([errno]) is accessed.
template<class T, class Abi> constexpr basic_vec<T, Abi> modf(const type_identity_t<basic_vec<T, Abi>>& value, basic_vec<T, Abi>* iptr);
Let V be basic_vec<T, Abi>.
Let modf-vec denote: pair<V, V> modf-vec(const V& x) { T r1[Ret::size()]; V r0([&](simd-size-type i) { modf(V(x)[i], &r1[i]); }); return {r0, V(r1)}; }
Let ret be a value of type pair<V, V> that is the same value as the result of calling modf-vec(value).
Effects: Sets *iptr to ret.second.
Returns: ret.first.

29.10.8.15 basic_vec bit library [simd.bit]

template<simd-vec-type V> constexpr V byteswap(const V& v) noexcept;
Constraints: The type V​::​value_type models integral.
Returns: A basic_vec object where the element is initialized to the result of std​::​byteswap(v[i]) for all i in the range [0, V​::​size()).
template<simd-vec-type V> constexpr V bit_ceil(const V& v) noexcept;
Constraints: The type V​::​value_type is an unsigned integer type ([basic.fundamental]).
Preconditions: For every i in the range [0, V​::​size()), the smallest power of 2 greater than or equal to v[i] is representable as a value of type V​::​value_type.
Returns: A basic_vec object where the element is initialized to the result of std​::​bit_ceil(v[i]) for all i in the range [0, V​::​size()).
Remarks: A function call expression that violates the precondition in the Preconditions: element is not a core constant expression ([expr.const]).
template<simd-vec-type V> constexpr V bit_floor(const V& v) noexcept;
Constraints: The type V​::​value_type is an unsigned integer type ([basic.fundamental]).
Returns: A basic_vec object where the element is initialized to the result of std​::​bit_floor(v[i]) for all i in the range [0, V​::​size()).
template<simd-vec-type V> constexpr typename V::mask_type has_single_bit(const V& v) noexcept;
Constraints: The type V​::​value_type is an unsigned integer type ([basic.fundamental]).
Returns: A basic_mask object where the element is initialized to the result of std​::​has_single_bit(v[i]) for all i in the range [0, V​::​size()).
template<simd-vec-type V0, simd-vec-type V1> constexpr V0 rotl(const V0& v0, const V1& v1) noexcept; template<simd-vec-type V0, simd-vec-type V1> constexpr V0 rotr(const V0& v0, const V1& v1) noexcept;
Constraints:
  • The type V0​::​value_type is an unsigned integer type ([basic.fundamental]),
  • the type V1​::​value_type models integral,
  • V0​::​size() == V1​::​size() is true, and
  • sizeof(typename V0​::​value_type) == sizeof(typename V1​::​value_type) is true.
Returns: A basic_vec object where the element is initialized to the result of bit-func(v0[i], static_cast<int>(v1[i])) for all i in the range [0, V0​::​size()), where bit-func is the corresponding scalar function from <bit>.
template<simd-vec-type V> constexpr V rotl(const V& v, int s) noexcept; template<simd-vec-type V> constexpr V rotr(const V& v, int s) noexcept;
Constraints: The type V​::​value_type is an unsigned integer type ([basic.fundamental]).
Returns: A basic_vec object where the element is initialized to the result of bit-func(v[i], s) for all i in the range [0, V​::​size()), where bit-func is the corresponding scalar function from <bit>.
template<simd-vec-type V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> bit_width(const V& v) noexcept; template<simd-vec-type V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> countl_zero(const V& v) noexcept; template<simd-vec-type V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> countl_one(const V& v) noexcept; template<simd-vec-type V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> countr_zero(const V& v) noexcept; template<simd-vec-type V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> countr_one(const V& v) noexcept; template<simd-vec-type V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> popcount(const V& v) noexcept;
Constraints: The type V​::​value_type is an unsigned integer type ([basic.fundamental]).
Returns: A basic_vec object where the element is initialized to the result of bit-func(v[i]) for all i in the range [0, V​::​size()), where bit-func is the corresponding scalar function from <bit>.

29.10.8.16 vec complex math [simd.complex.math]

template<simd-complex V> constexpr rebind_t<simd-complex-value-type<V>, V> real(const V&) noexcept; template<simd-complex V> constexpr rebind_t<simd-complex-value-type<V>, V> imag(const V&) noexcept; template<simd-complex V> constexpr rebind_t<simd-complex-value-type<V>, V> abs(const V&); template<simd-complex V> constexpr rebind_t<simd-complex-value-type<V>, V> arg(const V&); template<simd-complex V> constexpr rebind_t<simd-complex-value-type<V>, V> norm(const V&); template<simd-complex V> constexpr V conj(const V&); template<simd-complex V> constexpr V proj(const V&); template<simd-complex V> constexpr V exp(const V& v); template<simd-complex V> constexpr V log(const V& v); template<simd-complex V> constexpr V log10(const V& v); template<simd-complex V> constexpr V sqrt(const V& v); template<simd-complex V> constexpr V sin(const V& v); template<simd-complex V> constexpr V asin(const V& v); template<simd-complex V> constexpr V cos(const V& v); template<simd-complex V> constexpr V acos(const V& v); template<simd-complex V> constexpr V tan(const V& v); template<simd-complex V> constexpr V atan(const V& v); template<simd-complex V> constexpr V sinh(const V& v); template<simd-complex V> constexpr V asinh(const V& v); template<simd-complex V> constexpr V cosh(const V& v); template<simd-complex V> constexpr V acosh(const V& v); template<simd-complex V> constexpr V tanh(const V& v); template<simd-complex V> constexpr V atanh(const V& v);
Returns: A basic_vec object ret where the element is initialized to the result of cmplx-func(v[i]) for all i in the range [0, V​::​size()), where cmplx-func is the corresponding function from <complex>.
If in an invocation of cmplx-func for index i a domain, pole, or range error would occur, the value of ret[i] is unspecified.
Remarks: It is unspecified whether errno ([errno]) is accessed.
template<simd-floating-point V> rebind_t<complex<typename V::value_type>, V> polar(const V& x, const V& y = {}); template<simd-complex V> constexpr V pow(const V& x, const V& y);
Returns: A basic_vec object ret where the element is initialized to the result of cmplx-func(x[i], y[i]) for all i in the range [0, V​::​size()), where cmplx-func is the corresponding function from <complex>.
If in an invocation of cmplx-func for index i a domain, pole, or range error would occur, the value of ret[i] is unspecified.
Remarks: It is unspecified whether errno ([errno]) is accessed.