Files
cppdraft_translate/cppdraft/simd/nonmembers.md
2025-10-25 03:02:53 +03:00

100 KiB
Raw Blame History

[simd.nonmembers]

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;

1

#

Let op be the operator.

2

#

Constraints: requires (value_type a, value_type b) { a op b; } istrue.

3

#

Returns: A basic_vec object initialized with the results of applyingop 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;

4

#

Let op be the operator.

5

#

Constraints: requires (value_type a, simd-size-type b) { aop b; } is true.

6

#

Returns: A basic_vec object where the ith element is initialized to the result of applying op to v[i] and n for alli 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;

1

#

Let op be the operator.

2

#

Constraints: requires (value_type a, value_type b) { a op b; } istrue.

3

#

Effects: These operators apply the indicated operator to lhs and rhs as an element-wise operation.

4

#

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;

5

#

Let op be the operator.

6

#

Constraints: requires (value_type a, simd-size-type b) { aop b; } is true.

7

#

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;

1

#

Let op be the operator.

2

#

Constraints: requires (value_type a, value_type b) { a op b; } istrue.

3

#

Returns: A basic_mask object initialized with the results of applyingop to lhs and rhs as a binary element-wise operation.

29.10.8.4 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;

1

#

Returns: A basic_vec object where the ith element equalsmask[i] ? a[i] : b[i] for all i in the range of [0, size()).

29.10.8.5 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 = {});

1

#

Constraints: BinaryOperation modelsreduction-binary-operation.

2

#

Preconditions: binary_op does not modify x.

3

#

Returns: GENERALIZED_SUM(binary_op, vec<T, 1>(x[0]), …, vec<T, 1>(x[x.size() - 1]))[0] ([numerics.defns]).

4

#

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);

5

#

Constraints:

  • (5.1)

    BinaryOperation models reduction-binary-operation.

  • (5.2)

    An argument for identity_element is provided for the invocation, unless BinaryOperation is one of plus<>, multiplies<>, bit_and<>, bit_or<>, or bit_xor<>.

6

#

Preconditions:

  • (6.1)

    binary_op does not modify x.

  • (6.2)

    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.

7

#

Returns: If none_of(mask) is true, returns identity_element.

Otherwise, returns GENERALIZED_SUM(binary_op, vec<T,1>(x[k0]), …, vec<T, 1>(x[kn]))[0] where k0,…,kn are the selected indices of mask.

8

#

Throws: Any exception thrown from binary_op.

9

#

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;

10

#

Constraints: T models totally_ordered.

11

#

Returns: The value of an element x[j] for which x[i] < x[j] isfalse 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;

12

#

Constraints: T models totally_ordered.

13

#

Returns: If none_of(mask) is true, returnsnumeric_limits::max().

Otherwise, returns the value of a selected element x[j] for whichx[i] < x[j] is false for all selected indices i ofmask.

🔗

template<class T, class Abi> constexpr T reduce_max(const basic_vec<T, Abi>& x) noexcept;

14

#

Constraints: T models totally_ordered.

15

#

Returns: The value of an element x[j] for which x[j] < x[i] isfalse 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;

16

#

Constraints: T models totally_ordered.

17

#

Returns: If none_of(mask) is true, returnsnumeric_limits<V::value_type>::lowest().

Otherwise, returns the value of a selected element x[j] for whichx[j] < x[i] is false for all selected indices i ofmask.

29.10.8.6 basic_vec load and store functions [simd.loadstore]

🔗

template<class V = see below, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr V unchecked_load(R&& r, flags<Flags...> f = {}); template<class V = see below, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr V unchecked_load(R&& r, const typename V::mask_type& mask, flags<Flags...> f = {}); template<class V = see below, [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, class... Flags> constexpr V unchecked_load(I first, iter_difference_t<I> n, flags<Flags...> f = {}); template<class V = see below, [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") 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](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S, class... Flags> constexpr V unchecked_load(I first, S last, flags<Flags...> f = {}); template<class V = see below, [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S, class... Flags> constexpr V unchecked_load(I first, S last, const typename V::mask_type& mask, flags<Flags...> f = {});

1

#

Let

mask be V::mask_type(true) for the overloads with no mask parameter;

R be span<const iter_value_t> 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.

2

#

Mandates: If ranges::size(r) is a constant expression thenranges::size(r) ≥ V::size().

3

#

Preconditions:

  • (3.1)

    [first, first + n) is a valid range for the overloads with an n parameter.

  • (3.2)

    [first, last) is a valid range for the overloads with a last parameter.

  • (3.3)

    ranges::size(r) ≥ V::size()

4

#

Effects: Equivalent to: return partial_load(r, mask, f);

5

#

Remarks: The default argument for template parameter V isbasic_vec<ranges::range_value_t>.

🔗

template<class V = see below, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr V partial_load(R&& r, flags<Flags...> f = {}); template<class V = see below, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr V partial_load(R&& r, const typename V::mask_type& mask, flags<Flags...> f = {}); template<class V = see below, [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, class... Flags> constexpr V partial_load(I first, iter_difference_t<I> n, flags<Flags...> f = {}); template<class V = see below, [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") 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](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S, class... Flags> constexpr V partial_load(I first, S last, flags<Flags...> f = {}); template<class V = see below, [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S, class... Flags> constexpr V partial_load(I first, S last, const typename V::mask_type& mask, flags<Flags...> f = {});

6

#

Let

mask be V::mask_type(true) for the overloads with no mask parameter;

R be span<const iter_value_t> 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.

7

#

Mandates:

ranges::range_value_t is a vectorizable type,

same_as<remove_cvref_t, 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 to V::value_type is value-preserving.

8

#

Preconditions:

  • (8.1)

    [first, first + n) is a valid range for the overloads with an n parameter.

  • (8.2)

    [first, last) is a valid range for the overloads with a last parameter.

  • (8.3)

    If the template parameter pack Flags contains aligned-flag, ranges::data(r) points to storage aligned by alignment_v<V, ranges::range_value_t>.

  • (8.4)

    If the template parameter pack Flags contains overaligned-flag, ranges::data(r) points to storage aligned by N.

9

#

Effects: Initializes the ith element with

mask[i] && i < ranges::size(r) ?static_cast(ranges::data(r)[i]) : T() for all i in the range of [0, V::size()).

10

#

Remarks: The default argument for template parameter V isbasic_vec<ranges::range_value_t>.

🔗

template<class T, class Abi, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> && [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> && [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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 = {});

11

#

Let

mask be basic_vec<T, Abi>::mask_type(true) for the overloads with no mask parameter;

R be span<iter_value_t> 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.

12

#

Mandates: If ranges::size(r) is a constant expression thenranges::size(r) ≥ simd-size-v<T, Abi>.

13

#

Preconditions:

  • (13.1)

    [first, first + n) is a valid range for the overloads with an n parameter.

  • (13.2)

    [first, last) is a valid range for the overloads with a last parameter.

  • (13.3)

    ranges::size(r) ≥ simd-size-v<T, Abi>

14

#

Effects: Equivalent to: partial_store(v, r, mask, f).

🔗

template<class T, class Abi, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> && [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> && [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3Concept indirectly_­writable[iterator.concept.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 = {});

15

#

Let

mask be basic_vec<T, Abi>::mask_type(true) for the overloads with no mask parameter;

R be span<iter_value_t> 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.

16

#

Mandates:

ranges::range_value_t 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 is value-preserving.

17

#

Preconditions:

  • (17.1)

    [first, first + n) is a valid range for the overloads with an n parameter.

  • (17.2)

    [first, last) is a valid range for the overloads with a last parameter.

  • (17.3)

    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>.

  • (17.4)

    If the template parameter pack Flags contains overaligned-flag, ranges::data(r) points to storage aligned by N.

18

#

Effects: For all i in the range of [0, basic_vec<T, Abi>::size()), ifmask[i] && i < ranges::size(r) is true, evaluatesranges::data(r)[i] = v[i].

29.10.8.7 vec static permute [simd.permute.static]

🔗

template<simd-size-type N = see below, [simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V, class IdxMap> constexpr resize_t<N, V> permute(const V& v, IdxMap&& idxmap); template<simd-size-type N = see below, [simd-mask-type](simd.expos#concept:simd-mask-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") M, class IdxMap> constexpr resize_t<N, M> permute(const M& v, IdxMap&& idxmap);

1

#

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]; }}

2

#

Constraints: integral<invoke_result_t<IdxMap&, simd-size-type>> ||integral<invoke_result_t<IdxMap&, simd-size-type,simd-size-type>> is true.

3

#

Mandates: gen-fn(i) is a constant expression whose value iszero_element, uninit_element, or in the range [0, V::size()), for all i in the range [0, N).

4

#

Returns: A data-parallel object where theith element is initialized to the result ofperm-fn() for all i in the range [0, N).

5

#

Remarks: The default argument for template parameter N is V::size().

29.10.8.8 vec dynamic permute [simd.permute.dynamic]

🔗

template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V, [simd-integral](simd.expos#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") I> constexpr resize_t<I::size(), V> permute(const V& v, const I& indices); template<[simd-mask-type](simd.expos#concept:simd-mask-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") M, [simd-integral](simd.expos#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") I> constexpr resize_t<I::size(), M> permute(const M& v, const I& indices);

1

#

Preconditions: All values in indices are in the range [0, V::size()).

2

#

Returns: A data-parallel object where the ith element is initialized to the result of v[indices[i]] for all i in the range [0, I::size()).

29.10.8.9 vec mask permute [simd.permute.mask]

🔗

template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V compress(const V& v, const typename V::mask_type& selector); template<[simd-mask-type](simd.expos#concept:simd-mask-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") M> constexpr M compress(const M& v, const type_identity_t<M>& selector);

1

#

Let:

  • (1.1)

    bit-index(i) be a function which returns the index of the ith element of selector that is true.

  • (1.2)

    select-value(i) be a function which returnsv[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]

2

#

Returns: A data-parallel object where the ith element is initialized to the result of select-value(i) for all i in the range [0, V::size()).

🔗

template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V compress(const V& v, const typename V::mask_type& selector, const typename V::value_type& fill_value); template<[simd-mask-type](simd.expos#concept:simd-mask-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") M> constexpr M compress(const M& v, const type_identity_t<M>& selector, const typename M::value_type& fill_value);

3

#

Let:

  • (3.1)

    bit-index(i) be a function which returns the index of the ith element of selector that is true.

  • (3.2)

    select-value(i) be a function which returnsv[bit-index(i)] for i in the range [0, reduce_count(selector)) and fill_value otherwise.

4

#

Returns: A data-parallel object where the ith element is initialized to the result of select-value(i) for all i in the range [0, V::size()).

🔗

template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V expand(const V& v, const typename V::mask_type& selector, const V& original = {}); template<[simd-mask-type](simd.expos#concept:simd-mask-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") M> constexpr M expand(const M& v, const type_identity_t<M>& selector, const M& original = {});

5

#

Let:

  • (5.1)

    set-indices be a list of the index positions of true elements in selector.

  • (5.2)

    bit-lookup(b) be a function which returns the index where b appears in set-indices.

  • (5.3)

    select-value(i) be a function which returnsv[bit-lookup(i)] if selector[i] istrue, otherwise returns original[i].

6

#

Returns: A data-parallel object where the ith element is initialized to the result of select-value(i) for all i in the range [0, V::size()).

29.10.8.10 simd memory permute [simd.permute.memory]

🔗

template<class V = see below, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr V unchecked_gather_from(R&& in, const I& indices, flags<Flags...> f = {}); template<class V = see below, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr V unchecked_gather_from(R&& in, const typename I::mask_type& mask, const I& indices, flags<Flags...> f = {});

1

#

Let mask be typename I::mask_type(true) for the overload with no mask parameter.

2

#

Preconditions: All values in select(mask, indices, typename I::value_type()) are in the range [0, ranges::size(in)).

3

#

Effects: Equivalent to: return partial_gather_from(in, mask, indices, f);

4

#

Remarks: The default argument for template parameter V isvec<ranges::range_value_t, I::size()>.

🔗

template<class V = see below, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr V partial_gather_from(R&& in, const I& indices, flags<Flags...> f = {}); template<class V = see below, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr V partial_gather_from(R&& in, const typename I::mask_type& mask, const I& indices, flags<Flags...> f = {});

5

#

Let:

mask be typename I::mask_type(true) for the overload with no mask parameter;

T be typename V::value_type.

6

#

Mandates:

ranges::range_value_t is a vectorizable type,

same_as<remove_cvref_t, 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 containconvert-flag, then the conversion fromranges::range_value_t to T is value-preserving.

7

#

Preconditions:

  • (7.1)

    If the template parameter pack Flags containsaligned-flag, ranges::data(in) points to storage aligned byalignment_v<V, ranges::range_value_t>.

  • (7.2)

    If the template parameter pack Flags containsoveraligned-flag, ranges::data(in) points to storage aligned by N.

8

#

Returns: A basic_vec object where the ith element is initialized to the result ofmask[i] && indices[i] < ranges::size(in) ? static_cast(ranges::data(in)[indices[i]]) : T() for all i in the range [0, I::size()).

9

#

Remarks: The default argument for template parameter V isvec<ranges::range_value_t, I::size()>.

🔗

template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr void unchecked_scatter_to(const V& v, R&& out, const I& indices, flags<Flags...> f = {}); template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr void unchecked_scatter_to(const V& v, R&& out, const typename I::mask_type& mask, const I& indices, flags<Flags...> f = {});

10

#

Let mask be typename I::mask_type(true) for the overload with no mask parameter.

11

#

Preconditions: All values in select(mask, indices, typename I::value_type()) are in the range [0, ranges::size(out)).

12

#

Effects: Equivalent to: partial_scatter_to(v, out, mask, indices, f);

🔗

template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr void partial_scatter_to(const V& v, R&& out, const I& indices, flags<Flags...> f = {}); template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<R> constexpr void partial_scatter_to(const V& v, R&& out, const typename I::mask_type& mask, const I& indices, flags<Flags...> f = {});

13

#

Let mask be typename I::mask_type(true) for the overload with no mask parameter.

14

#

Constraints: V::size() == I::size() is true.

15

#

Mandates:

ranges::range_value_t 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 is value-preserving.

16

#

Preconditions:

  • (16.1)

    For all selected indices i the values indices[i] are unique.

  • (16.2)

    If the template parameter pack Flags contains aligned-flag,ranges::data(out) points to storage aligned byalignment_v<V, ranges::range_value_t>.

  • (16.3)

    If the template parameter pack Flags containsoveraligned-flag,ranges::data(out) points to storage aligned by N.

17

#

Effects: For all i in the range [0, I::size()), if mask[i] &&(indices[i] < ranges::size(out)) is true, evaluatesranges::data(out)[indices[i]] = v[i].

29.10.8.11 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;

1

#

Constraints:

  • (1.1)

    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.

  • (1.2)

    For the second overload, T is an enabled specialization of basic_mask. If basic_mask<mask-element-size, Abi>::size() % T::size() is not 0, then resize_t<basic_mask<mask-element-size, Abi>::size() % T::size(), T> is valid and denotes a type.

2

#

Let N be x.size() / T::size().

3

#

Returns:

  • (3.1)

    If x.size() % T::size() == 0 is true, an array<T, N> with the ith basic_vec or basic_mask element of the jth array element initialized to the value of the element in x with index i + j * T::size().

  • (3.2)

    Otherwise, a tuple of N objects of type T and one object of type resize_t<x.size() % T::size(), T>. The ith basic_vec or basic_mask element of the jth tuple element of type T is initialized to the value of the element in x with index i + j * T::size(). The ith basic_vec or basic_mask element of the Nth 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;

4

#

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;

5

#

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;

6

#

Constraints:

  • (6.1)

    For the first overload vec<T, (basic_vec<T, Abis>::size() + ...)> is enabled.

  • (6.2)

    For the second overload basic_mask<Bytes, deduce-abi-t<integer-from, (basic_mask<Bytes, Abis>::size() + ...)>> is enabled.

7

#

Returns: A data-parallel object initialized with the concatenated values in thexs pack of data-parallel objects: The ithbasic_vec/basic_mask element of the jth 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.12 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;

1

#

Constraints: T models totally_ordered.

2

#

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;

3

#

Constraints: T models totally_ordered.

4

#

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;

5

#

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);

6

#

Constraints: T models totally_ordered.

7

#

Preconditions: No element in lo shall be greater than the corresponding element inhi.

8

#

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)>;

9

#

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));

10

#

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.13 Mathematical functions [simd.math]

🔗

template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr rebind_t<int, deduced-vec-t<V>> ilogb(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> ldexp(const V& x, const rebind_t<int, deduced-vec-t<V>>& exp); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> scalbn(const V& x, const rebind_t<int, deduced-vec-t<V>>& n); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> scalbln(const V& x, const rebind_t<long int, deduced-vec-t<V>>& n); template<[signed_integral](concepts.arithmetic#concept:signed_integral "18.4.7Arithmetic concepts[concepts.arithmetic]") T, class Abi> constexpr basic_vec<T, Abi> abs(const basic_vec<T, Abi>& j); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> abs(const V& j); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> fabs(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> ceil(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> floor(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> deduced-vec-t<V> nearbyint(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> deduced-vec-t<V> rint(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> rebind_t<long int, deduced-vec-t<V>> lrint(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> rebind_t<long long int, deduced-vec-t<V>> llrint(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> round(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr rebind_t<long int, deduced-vec-t<V>> lround(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") 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](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") 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](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr rebind_t<int, deduced-vec-t<V>> fpclassify(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr typename deduced-vec-t<V>::mask_type isfinite(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr typename deduced-vec-t<V>::mask_type isinf(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr typename deduced-vec-t<V>::mask_type isnan(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr typename deduced-vec-t<V>::mask_type isnormal(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") 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);

1

#

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]...); });}

2

#

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 indexi in math-func-vec a domain, pole, or range error would occur, the value of ret[i] is unspecified.

3

#

Remarks: It is unspecified whether errno ([errno]) is accessed.

🔗

template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> acos(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> asin(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") 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](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> cos(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> sin(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> tan(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> acosh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> asinh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> atanh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> cosh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> sinh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> tanh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> exp(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> exp2(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> expm1(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> log(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> log10(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> log1p(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> log2(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> logb(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") 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](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> sqrt(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> erf(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> erfc(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> lgamma(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") 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](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") 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](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") 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](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> deduced-vec-t<V> comp_ellint_1(const V& k); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") 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](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> deduced-vec-t<V> expint(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> deduced-vec-t<V> hermite(const rebind_t<unsigned, deduced-vec-t<V>>& n, const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> deduced-vec-t<V> laguerre(const rebind_t<unsigned, deduced-vec-t<V>>& n, const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> deduced-vec-t<V> legendre(const rebind_t<unsigned, deduced-vec-t<V>>& l, const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> deduced-vec-t<V> riemann_zeta(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> deduced-vec-t<V> sph_bessel(const rebind_t<unsigned, deduced-vec-t<V>>& n, const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") 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](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> deduced-vec-t<V> sph_neumann(const rebind_t<unsigned, deduced-vec-t<V>>& n, const V& x);

4

#

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]...); });}

5

#

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 indexi in math-func-vec a domain, pole, or range error would occur, the value of ret[i] is unspecified.

6

#

Remarks: It is unspecified whether errno ([errno]) is accessed.

🔗

template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr deduced-vec-t<V> frexp(const V& value, rebind_t<int, deduced-vec-t<V>>* exp);

7

#

Let Ret be deduced-vec-t.

Let frexp-vec denote:template 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 callingfrexp-vec(x).

8

#

Effects: Sets *exp to ret.second.

9

#

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);

10

#

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 callingremquo-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.

11

#

Effects: Sets *quo to ret.second.

12

#

Returns: ret.first.

13

#

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);

14

#

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).

15

#

Effects: Sets *iptr to ret.second.

16

#

Returns: ret.first.

29.10.8.14 basic_vec bit library [simd.bit]

🔗

template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V byteswap(const V& v) noexcept;

1

#

Constraints: The type V::value_type models integral.

2

#

Returns: A basic_vec object where the ith element is initialized to the result of std::byteswap(v[i]) for all i in the range [0, V::size()).

🔗

template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V bit_ceil(const V& v) noexcept;

3

#

Constraints: The type V::value_type is an unsigned integer type ([basic.fundamental]).

4

#

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 typeV::value_type.

5

#

Returns: A basic_vec object where the ith element is initialized to the result of std::bit_ceil(v[i]) for all i in the range [0, V::size()).

6

#

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](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V bit_floor(const V& v) noexcept;

7

#

Constraints: The type V::value_type is an unsigned integer type ([basic.fundamental]).

8

#

Returns: A basic_vec object where the ith 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](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr typename V::mask_type has_single_bit(const V& v) noexcept;

9

#

Constraints: The type V::value_type is an unsigned integer type ([basic.fundamental]).

10

#

Returns: A basic_mask object where the ith 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](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V0, [simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V1> constexpr V0 rotl(const V0& v0, const V1& v1) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V0, [simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V1> constexpr V0 rotr(const V0& v0, const V1& v1) noexcept;

11

#

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.

12

#

Returns: A basic_vec object where the ith element is initialized to the result of bit-func(v0[i],static_cast(v1[i])) for all i in the range [0, V0::size()), where bit-func is the corresponding scalar function from .

🔗

template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V rotl(const V& v, int s) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V rotr(const V& v, int s) noexcept;

13

#

Constraints: The type V::value_type is an unsigned integer type ([basic.fundamental]).

14

#

Returns: A basic_vec object where the ith 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 .

🔗

template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> bit_width(const V& v) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> countl_zero(const V& v) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> countl_one(const V& v) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> countr_zero(const V& v) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> countr_one(const V& v) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr rebind_t<make_signed_t<typename V::value_type>, V> popcount(const V& v) noexcept;

15

#

Constraints: The type V::value_type is an unsigned integer type ([basic.fundamental]).

16

#

Returns: A basic_vec object where the ith 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 .

29.10.8.15 vec complex math [simd.complex.math]

🔗

`template<simd-complex V> constexpr rebind_t<simd-complex-value-type, V> real(const V&) noexcept; template<simd-complex V> constexpr rebind_t<simd-complex-value-type, V> imag(const V&) noexcept;

template<simd-complex V> constexpr rebind_t<simd-complex-value-type, V> abs(const V&); template<simd-complex V> constexpr rebind_t<simd-complex-value-type, V> arg(const V&); template<simd-complex V> constexpr rebind_t<simd-complex-value-type, 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); `

1

#

Returns: A basic_vec object ret where the ith element is initialized to the result of cmplx-func(v[i]) for alli in the range [0, V::size()), where cmplx-func is the corresponding function from .

If in an invocation ofcmplx-func for index i a domain, pole, or range error would occur, the value of ret[i] is unspecified.

2

#

Remarks: It is unspecified whether errno ([errno]) is accessed.

🔗

`template<simd-floating-point V> rebind_t<complex, V> polar(const V& x, const V& y = {});

template<simd-complex V> constexpr V pow(const V& x, const V& y); `

3

#

Returns: A basic_vec object ret where the ith 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 .

If in an invocation ofcmplx-func for index i a domain, pole, or range error would occur, the value of ret[i] is unspecified.

4

#

Remarks: It is unspecified whether errno ([errno]) is accessed.