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

1895 lines
100 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[simd.nonmembers]
# 29 Numerics library [[numerics]](./#numerics)
## 29.10 Data-parallel types [[simd]](simd#nonmembers)
### 29.10.8 basic_vec non-member operations [simd.nonmembers]
#### [29.10.8.1](#simd.binary) basic_vec binary operators [[simd.binary]](simd.binary)
[🔗](#lib:operator+,basic_vec)
`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](#simd.binary-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18153)
Let *op* be the operator[.](#simd.binary-1.sentence-1)
[2](#simd.binary-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18156)
*Constraints*: requires (value_type a, value_type b) { a *op* b; } istrue[.](#simd.binary-2.sentence-1)
[3](#simd.binary-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18161)
*Returns*: A basic_vec object initialized with the results of applying*op* to lhs and rhs as a binary element-wise
operation[.](#simd.binary-3.sentence-1)
[🔗](#lib:operator%3c%3c,basic_vec_)
`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](#simd.binary-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18176)
Let *op* be the operator[.](#simd.binary-4.sentence-1)
[5](#simd.binary-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18179)
*Constraints*: requires (value_type a, *simd-size-type* b) { a*op* b; } is true[.](#simd.binary-5.sentence-1)
[6](#simd.binary-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18184)
*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())[.](#simd.binary-6.sentence-1)
#### [29.10.8.2](#simd.cassign) basic_vec compound assignment [[simd.cassign]](simd.cassign)
[🔗](#lib:operator+=,basic_vec)
`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](#simd.cassign-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18217)
Let *op* be the operator[.](#simd.cassign-1.sentence-1)
[2](#simd.cassign-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18220)
*Constraints*: requires (value_type a, value_type b) { a *op* b; } istrue[.](#simd.cassign-2.sentence-1)
[3](#simd.cassign-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18225)
*Effects*: These operators apply the indicated operator to lhs and rhs as
an element-wise operation[.](#simd.cassign-3.sentence-1)
[4](#simd.cassign-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18230)
*Returns*: lhs[.](#simd.cassign-4.sentence-1)
[🔗](#lib:operator%3c%3c=,basic_vec_)
`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](#simd.cassign-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18243)
Let *op* be the operator[.](#simd.cassign-5.sentence-1)
[6](#simd.cassign-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18246)
*Constraints*: requires (value_type a, *simd-size-type* b) { a*op* b; } is true[.](#simd.cassign-6.sentence-1)
[7](#simd.cassign-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18251)
*Effects*: Equivalent to: return operator *op* (lhs, basic_vec(n));
#### [29.10.8.3](#simd.comparison) basic_vec compare operators [[simd.comparison]](simd.comparison)
[🔗](#lib:operator==,basic_vec)
`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](#simd.comparison-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18274)
Let *op* be the operator[.](#simd.comparison-1.sentence-1)
[2](#simd.comparison-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18277)
*Constraints*: requires (value_type a, value_type b) { a *op* b; } istrue[.](#simd.comparison-2.sentence-1)
[3](#simd.comparison-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18282)
*Returns*: A basic_mask object initialized with the results of applying*op* to lhs and rhs as a binary element-wise
operation[.](#simd.comparison-3.sentence-1)
#### [29.10.8.4](#simd.cond) basic_vec exposition only conditional operators [[simd.cond]](simd.cond)
[🔗](#simd.cond-itemdecl:1)
`friend constexpr basic_vec
simd-select-impl(const mask_type& mask, const basic_vec& a, const basic_vec& b) noexcept;
`
[1](#simd.cond-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18297)
*Returns*: A basic_vec object where the ith element equalsmask[i] ? a[i] : b[i] for all i in the range of
[0, size())[.](#simd.cond-1.sentence-1)
#### [29.10.8.5](#simd.reductions) basic_vec reductions [[simd.reductions]](simd.reductions)
[🔗](#lib:reduce,simd)
`template<class T, class Abi, class BinaryOperation = plus<>>
constexpr T reduce(const basic_vec<T, Abi>& x, BinaryOperation binary_op = {});
`
[1](#simd.reductions-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18313)
*Constraints*: BinaryOperation models[*reduction-binary-operation*](simd.expos.defn#concept:reduction-binary-operation "29.10.2.1Exposition-only helpers[simd.expos.defn]")<T>[.](#simd.reductions-1.sentence-1)
[2](#simd.reductions-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18318)
*Preconditions*: binary_op does not modify x[.](#simd.reductions-2.sentence-1)
[3](#simd.reductions-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18322)
*Returns*: *GENERALIZED_SUM*(binary_op, vec<T, 1>(x[0]), …,
vec<T, 1>(x[x.size() - 1]))[0] ([[numerics.defns]](numerics.defns "26.10.2Definitions"))[.](#simd.reductions-3.sentence-1)
[4](#simd.reductions-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18327)
*Throws*: Any exception thrown from binary_op[.](#simd.reductions-4.sentence-1)
[🔗](#lib:reduce,simd_)
`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](#simd.reductions-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18341)
*Constraints*:
- [(5.1)](#simd.reductions-5.1)
BinaryOperation models [*reduction-binary-operation*](simd.expos.defn#concept:reduction-binary-operation "29.10.2.1Exposition-only helpers[simd.expos.defn]")<T>[.](#simd.reductions-5.1.sentence-1)
- [(5.2)](#simd.reductions-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<>[.](#simd.reductions-5.2.sentence-1)
[6](#simd.reductions-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18354)
*Preconditions*:
- [(6.1)](#simd.reductions-6.1)
binary_op does not modify x[.](#simd.reductions-6.1.sentence-1)
- [(6.2)](#simd.reductions-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[.](#simd.reductions-6.2.sentence-1)
[7](#simd.reductions-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18366)
*Returns*: If none_of(mask) is true, returns identity_element[.](#simd.reductions-7.sentence-1)
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[.](#simd.reductions-7.sentence-2)
[8](#simd.reductions-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18373)
*Throws*: Any exception thrown from binary_op[.](#simd.reductions-8.sentence-1)
[9](#simd.reductions-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18377)
*Remarks*: The default argument for identity_element is equal to
- [(9.1)](#simd.reductions-9.1)
T() if BinaryOperation is plus<>,
- [(9.2)](#simd.reductions-9.2)
T(1) if BinaryOperation is multiplies<>,
- [(9.3)](#simd.reductions-9.3)
T(~T()) if BinaryOperation is bit_and<>,
- [(9.4)](#simd.reductions-9.4)
T() if BinaryOperation is bit_or<>, or
- [(9.5)](#simd.reductions-9.5)
T() if BinaryOperation is bit_xor<>[.](#simd.reductions-9.sentence-1)
[🔗](#lib:reduce_min,simd)
`template<class T, class Abi> constexpr T reduce_min(const basic_vec<T, Abi>& x) noexcept;
`
[10](#simd.reductions-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18395)
*Constraints*: T models [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")[.](#simd.reductions-10.sentence-1)
[11](#simd.reductions-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18399)
*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())[.](#simd.reductions-11.sentence-1)
[🔗](#lib:reduce_min,simd_)
`template<class T, class Abi>
constexpr T reduce_min(
const basic_vec<T, Abi>&, const typename basic_vec<T, Abi>::mask_type&) noexcept;
`
[12](#simd.reductions-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18413)
*Constraints*: T models [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")[.](#simd.reductions-12.sentence-1)
[13](#simd.reductions-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18417)
*Returns*: If none_of(mask) is true, returnsnumeric_limits<T>::max()[.](#simd.reductions-13.sentence-1)
Otherwise, returns the value of a selected element x[j] for whichx[i] < x[j] is false for all selected indices i ofmask[.](#simd.reductions-13.sentence-2)
[🔗](#lib:reduce_max,simd)
`template<class T, class Abi> constexpr T reduce_max(const basic_vec<T, Abi>& x) noexcept;
`
[14](#simd.reductions-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18432)
*Constraints*: T models [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")[.](#simd.reductions-14.sentence-1)
[15](#simd.reductions-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18436)
*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())[.](#simd.reductions-15.sentence-1)
[🔗](#lib:reduce_max,simd_)
`template<class T, class Abi>
constexpr T reduce_max(
const basic_vec<T, Abi>&, const typename basic_vec<T, Abi>::mask_type&) noexcept;
`
[16](#simd.reductions-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18450)
*Constraints*: T models [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")[.](#simd.reductions-16.sentence-1)
[17](#simd.reductions-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18454)
*Returns*: If none_of(mask) is true, returnsnumeric_limits<V::value_type>::lowest()[.](#simd.reductions-17.sentence-1)
Otherwise, returns the value of a selected element x[j] for whichx[j] < x[i] is false for all selected indices i ofmask[.](#simd.reductions-17.sentence-2)
#### [29.10.8.6](#simd.loadstore) basic_vec load and store functions [[simd.loadstore]](simd.loadstore)
[🔗](#lib:unchecked_load,simd)
`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](#simd.loadstore-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18486)
Let
- [(1.1)](#simd.loadstore-1.1)
mask be V::mask_type(true) for the overloads with no mask parameter;
- [(1.2)](#simd.loadstore-1.2)
R be span<const iter_value_t<I>> for the overloads with no
template parameter R;
- [(1.3)](#simd.loadstore-1.3)
r be R(first, n) for the overloads with an n parameter and R(first, last) for the overloads with a last parameter[.](#simd.loadstore-1.sentence-1)
[2](#simd.loadstore-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18501)
*Mandates*: If ranges::size(r) is a constant expression thenranges::size(r) ≥ V::size()[.](#simd.loadstore-2.sentence-1)
[3](#simd.loadstore-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18506)
*Preconditions*:
- [(3.1)](#simd.loadstore-3.1)
[first, first + n) is a valid range for the overloads with an n parameter[.](#simd.loadstore-3.1.sentence-1)
- [(3.2)](#simd.loadstore-3.2)
[first, last) is a valid range for the overloads with a last parameter[.](#simd.loadstore-3.2.sentence-1)
- [(3.3)](#simd.loadstore-3.3)
ranges::size(r) ≥ V::size()
[4](#simd.loadstore-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18516)
*Effects*: Equivalent to: return partial_load<V>(r, mask, f);
[5](#simd.loadstore-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18520)
*Remarks*: The default argument for template parameter V isbasic_vec<ranges::range_value_t<R>>[.](#simd.loadstore-5.sentence-1)
[🔗](#lib:partial_load,simd)
`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](#simd.loadstore-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18547)
Let
- [(6.1)](#simd.loadstore-6.1)
mask be V::mask_type(true) for the overloads with no mask parameter;
- [(6.2)](#simd.loadstore-6.2)
R be span<const iter_value_t<I>> for the overloads with no
template parameter R;
- [(6.3)](#simd.loadstore-6.3)
r be R(first, n) for the overloads with an n parameter and R(first, last) for the overloads with a last parameter[.](#simd.loadstore-6.sentence-1)
[7](#simd.loadstore-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18562)
*Mandates*:
- [(7.1)](#simd.loadstore-7.1)
ranges::range_value_t<R> is a vectorizable type,
- [(7.2)](#simd.loadstore-7.2)
same_as<remove_cvref_t<V>, V> is true,
- [(7.3)](#simd.loadstore-7.3)
V is an enabled specialization of basic_vec, and
- [(7.4)](#simd.loadstore-7.4)
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[.](#simd.loadstore-7.sentence-1)
[8](#simd.loadstore-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18578)
*Preconditions*:
- [(8.1)](#simd.loadstore-8.1)
[first, first + n) is a valid range for the overloads with an n parameter[.](#simd.loadstore-8.1.sentence-1)
- [(8.2)](#simd.loadstore-8.2)
[first, last) is a valid range for the overloads with a last parameter[.](#simd.loadstore-8.2.sentence-1)
- [(8.3)](#simd.loadstore-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<R>>[.](#simd.loadstore-8.3.sentence-1)
- [(8.4)](#simd.loadstore-8.4)
If the template parameter pack Flags contains *overaligned-flag*<N>, ranges::data(r) points to
storage aligned by N[.](#simd.loadstore-8.4.sentence-1)
[9](#simd.loadstore-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18597)
*Effects*: Initializes the ith 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())[.](#simd.loadstore-9.sentence-2)
[10](#simd.loadstore-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18604)
*Remarks*: The default argument for template parameter V isbasic_vec<ranges::range_value_t<R>>[.](#simd.loadstore-10.sentence-1)
[🔗](#lib:unchecked_store,simd)
`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](#simd.loadstore-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18638)
Let
- [(11.1)](#simd.loadstore-11.1)
mask be basic_vec<T, Abi>::mask_type(true) for the
overloads with no mask parameter;
- [(11.2)](#simd.loadstore-11.2)
R be span<iter_value_t<I>> for the overloads with no
template parameter R;
- [(11.3)](#simd.loadstore-11.3)
r be R(first, n) for the overloads with an n parameter and R(first, last) for the overloads with a last parameter[.](#simd.loadstore-11.sentence-1)
[12](#simd.loadstore-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18653)
*Mandates*: If ranges::size(r) is a constant expression thenranges::size(r) ≥ *simd-size-v*<T, Abi>[.](#simd.loadstore-12.sentence-1)
[13](#simd.loadstore-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18658)
*Preconditions*:
- [(13.1)](#simd.loadstore-13.1)
[first, first + n) is a valid range for the overloads with an n parameter[.](#simd.loadstore-13.1.sentence-1)
- [(13.2)](#simd.loadstore-13.2)
[first, last) is a valid range for the overloads with a last parameter[.](#simd.loadstore-13.2.sentence-1)
- [(13.3)](#simd.loadstore-13.3)
ranges::size(r) ≥ *simd-size-v*<T, Abi>
[14](#simd.loadstore-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18671)
*Effects*: Equivalent to: partial_store(v, r, mask, f)[.](#simd.loadstore-14.sentence-1)
[🔗](#lib:partial_store,simd)
`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](#simd.loadstore-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18704)
Let
- [(15.1)](#simd.loadstore-15.1)
mask be basic_vec<T, Abi>::mask_type(true) for the
overloads with no mask parameter;
- [(15.2)](#simd.loadstore-15.2)
R be span<iter_value_t<I>> for the overloads with no
template parameter R;
- [(15.3)](#simd.loadstore-15.3)
r be R(first, n) for the overloads with an n parameter and R(first, last) for the overloads with a last parameter[.](#simd.loadstore-15.sentence-1)
[16](#simd.loadstore-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18719)
*Mandates*:
- [(16.1)](#simd.loadstore-16.1)
ranges::range_value_t<R> is a vectorizable type, and
- [(16.2)](#simd.loadstore-16.2)
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[.](#simd.loadstore-16.sentence-1)
[17](#simd.loadstore-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18730)
*Preconditions*:
- [(17.1)](#simd.loadstore-17.1)
[first, first + n) is a valid range for the overloads with an n parameter[.](#simd.loadstore-17.1.sentence-1)
- [(17.2)](#simd.loadstore-17.2)
[first, last) is a valid range for the overloads with a last parameter[.](#simd.loadstore-17.2.sentence-1)
- [(17.3)](#simd.loadstore-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<R>>[.](#simd.loadstore-17.3.sentence-1)
- [(17.4)](#simd.loadstore-17.4)
If the template parameter pack Flags contains *overaligned-flag*<N>, ranges::data(r) points to
storage aligned by N[.](#simd.loadstore-17.4.sentence-1)
[18](#simd.loadstore-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18750)
*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][.](#simd.loadstore-18.sentence-1)
#### [29.10.8.7](#simd.permute.static) vec static permute [[simd.permute.static]](simd.permute.static)
[🔗](#lib:permute,simd)
`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](#simd.permute.static-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18768)
Let:
- [(1.1)](#simd.permute.static-1.1)
*gen-fn*(i) be idxmap(i, V::size()) if that expression is well-formed, and idxmap(i) otherwise.
- [(1.2)](#simd.permute.static-1.2)
*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](#simd.permute.static-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18791)
*Constraints*: [integral](concepts.arithmetic#concept:integral "18.4.7Arithmetic concepts[concepts.arithmetic]")<invoke_result_t<IdxMap&, *simd-size-type*>> ||[integral](concepts.arithmetic#concept:integral "18.4.7Arithmetic concepts[concepts.arithmetic]")<invoke_result_t<IdxMap&, *simd-size-type*,*simd-size-type*>> is true[.](#simd.permute.static-2.sentence-1)
[3](#simd.permute.static-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18797)
*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)[.](#simd.permute.static-3.sentence-1)
[4](#simd.permute.static-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18803)
*Returns*: A data-parallel object where theith element is initialized to the result of*perm-fn*<i>() for all i in the range [0, N)[.](#simd.permute.static-4.sentence-1)
[5](#simd.permute.static-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18809)
*Remarks*: The default argument for template parameter N is V::size()[.](#simd.permute.static-5.sentence-1)
#### [29.10.8.8](#simd.permute.dynamic) vec dynamic permute [[simd.permute.dynamic]](simd.permute.dynamic)
[🔗](#lib:permute,simd_)
`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](#simd.permute.dynamic-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18825)
*Preconditions*: All values in indices are in the range [0, V::size())[.](#simd.permute.dynamic-1.sentence-1)
[2](#simd.permute.dynamic-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18829)
*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())[.](#simd.permute.dynamic-2.sentence-1)
#### [29.10.8.9](#simd.permute.mask) vec mask permute [[simd.permute.mask]](simd.permute.mask)
[🔗](#lib:compress,simd)
`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](#simd.permute.mask-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18847)
Let:
- [(1.1)](#simd.permute.mask-1.1)
*bit-index*(i) be a function which returns the index
of the ith element of selector that is true[.](#simd.permute.mask-1.1.sentence-1)
- [(1.2)](#simd.permute.mask-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[.](#simd.permute.mask-1.2.sentence-1)
[*Note [1](#simd.permute.mask-note-1)*:
Different calls to *select-value* can return different unspecified values[.](#simd.permute.mask-1.2.sentence-2)
— *end note*]
[2](#simd.permute.mask-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18863)
*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())[.](#simd.permute.mask-2.sentence-1)
[🔗](#lib:compress,simd_)
`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](#simd.permute.mask-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18881)
Let:
- [(3.1)](#simd.permute.mask-3.1)
*bit-index*(i) be a function which returns the index
of the ith element of selector that is true[.](#simd.permute.mask-3.1.sentence-1)
- [(3.2)](#simd.permute.mask-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[.](#simd.permute.mask-3.2.sentence-1)
[4](#simd.permute.mask-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18893)
*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())[.](#simd.permute.mask-4.sentence-1)
[🔗](#lib:expand,simd)
`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](#simd.permute.mask-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18909)
Let:
- [(5.1)](#simd.permute.mask-5.1)
*set-indices* be a list of the index positions of true elements in selector[.](#simd.permute.mask-5.1.sentence-1)
- [(5.2)](#simd.permute.mask-5.2)
*bit-lookup*(b) be a function which returns the index
where b appears in *set-indices*[.](#simd.permute.mask-5.2.sentence-1)
- [(5.3)](#simd.permute.mask-5.3)
*select-value*(i) be a function which returnsv[*bit-lookup*(i)] if selector[i] istrue, otherwise returns original[i][.](#simd.permute.mask-5.3.sentence-1)
[6](#simd.permute.mask-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18924)
*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())[.](#simd.permute.mask-6.sentence-1)
#### [29.10.8.10](#simd.permute.memory) simd memory permute [[simd.permute.memory]](simd.permute.memory)
[🔗](#lib:unchecked_gather_from,simd)
`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](#simd.permute.memory-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18945)
Let mask be typename I::mask_type(true) for the overload with
no mask parameter[.](#simd.permute.memory-1.sentence-1)
[2](#simd.permute.memory-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18949)
*Preconditions*: All values in select(mask, indices, typename I::value_type()) are in
the range [0, ranges::size(in))[.](#simd.permute.memory-2.sentence-1)
[3](#simd.permute.memory-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18954)
*Effects*: Equivalent to: return partial_gather_from<V>(in, mask, indices, f);
[4](#simd.permute.memory-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18958)
*Remarks*: The default argument for template parameter V isvec<ranges::range_value_t<R>, I::size()>[.](#simd.permute.memory-4.sentence-1)
[🔗](#lib:partial_gather_from,simd)
`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](#simd.permute.memory-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18976)
Let:
- [(5.1)](#simd.permute.memory-5.1)
mask be typename I::mask_type(true) for the overload with no mask parameter;
- [(5.2)](#simd.permute.memory-5.2)
T be typename V::value_type[.](#simd.permute.memory-5.sentence-1)
[6](#simd.permute.memory-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L18986)
*Mandates*:
- [(6.1)](#simd.permute.memory-6.1)
ranges::range_value_t<R> is a vectorizable type,
- [(6.2)](#simd.permute.memory-6.2)
same_as<remove_cvref_t<V>, V> is true,
- [(6.3)](#simd.permute.memory-6.3)
V is an enabled specialization of basic_vec,
- [(6.4)](#simd.permute.memory-6.4)
V::size() == I::size() is true, and
- [(6.5)](#simd.permute.memory-6.5)
if the template parameter pack Flags does not contain*convert-flag*, then the conversion fromranges::range_value_t<R> to T is value-preserving[.](#simd.permute.memory-6.sentence-1)
[7](#simd.permute.memory-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19003)
*Preconditions*:
- [(7.1)](#simd.permute.memory-7.1)
If the template parameter pack Flags contains*aligned-flag*, ranges::data(in) points to storage aligned byalignment_v<V, ranges::range_value_t<R>>[.](#simd.permute.memory-7.1.sentence-1)
- [(7.2)](#simd.permute.memory-7.2)
If the template parameter pack Flags contains*overaligned-flag*<N>, ranges::data(in) points to
storage aligned by N[.](#simd.permute.memory-7.2.sentence-1)
[8](#simd.permute.memory-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19016)
*Returns*: A basic_vec object where the ith element is initialized to the result ofmask[i] && indices[i] < ranges::size(in) ? static_cast<T>(ranges::data(in)[indices[i]]) : T() for all i in the range [0, I::size())[.](#simd.permute.memory-8.sentence-1)
[9](#simd.permute.memory-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19025)
*Remarks*: The default argument for template parameter V isvec<ranges::range_value_t<R>, I::size()>[.](#simd.permute.memory-9.sentence-1)
[🔗](#lib:unchecked_scatter_to,simd)
`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](#simd.permute.memory-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19044)
Let mask be typename I::mask_type(true) for the overload with
no mask parameter[.](#simd.permute.memory-10.sentence-1)
[11](#simd.permute.memory-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19048)
*Preconditions*: All values in select(mask, indices, typename I::value_type()) are in
the range [0, ranges::size(out))[.](#simd.permute.memory-11.sentence-1)
[12](#simd.permute.memory-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19053)
*Effects*: Equivalent to: partial_scatter_to(v, out, mask, indices, f);
[🔗](#lib:partial_scatter_to,simd)
`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](#simd.permute.memory-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19071)
Let mask be typename I::mask_type(true) for the overload with
no mask parameter[.](#simd.permute.memory-13.sentence-1)
[14](#simd.permute.memory-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19075)
*Constraints*: V::size() == I::size() is true[.](#simd.permute.memory-14.sentence-1)
[15](#simd.permute.memory-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19079)
*Mandates*:
- [(15.1)](#simd.permute.memory-15.1)
ranges::range_value_t<R> is a vectorizable type, and
- [(15.2)](#simd.permute.memory-15.2)
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[.](#simd.permute.memory-15.sentence-1)
[16](#simd.permute.memory-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19090)
*Preconditions*:
- [(16.1)](#simd.permute.memory-16.1)
For all selected indices i the values indices[i] are unique[.](#simd.permute.memory-16.1.sentence-1)
- [(16.2)](#simd.permute.memory-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<R>>[.](#simd.permute.memory-16.2.sentence-1)
- [(16.3)](#simd.permute.memory-16.3)
If the template parameter pack Flags contains*overaligned-flag*<N>,ranges::data(out) points to storage aligned by N[.](#simd.permute.memory-16.3.sentence-1)
[17](#simd.permute.memory-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19105)
*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][.](#simd.permute.memory-17.sentence-1)
#### [29.10.8.11](#simd.creation) basic_vec and basic_mask creation [[simd.creation]](simd.creation)
[🔗](#lib:chunk,simd)
`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](#simd.creation-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19123)
*Constraints*:
- [(1.1)](#simd.creation-1.1)
For the first overload, T is an enabled specialization of basic_vec[.](#simd.creation-1.1.sentence-1)
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[.](#simd.creation-1.1.sentence-2)
- [(1.2)](#simd.creation-1.2)
For the second overload, T is an enabled specialization of basic_mask[.](#simd.creation-1.2.sentence-1)
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[.](#simd.creation-1.2.sentence-2)
[2](#simd.creation-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19143)
Let N be x.size() / T::size()[.](#simd.creation-2.sentence-1)
[3](#simd.creation-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19146)
*Returns*:
- [(3.1)](#simd.creation-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()[.](#simd.creation-3.1.sentence-1)
- [(3.2)](#simd.creation-3.2)
Otherwise, a tuple of N objects of type T and one object
of type resize_t<x.size() % T::size(), T>[.](#simd.creation-3.2.sentence-1)
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()[.](#simd.creation-3.2.sentence-2)
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()[.](#simd.creation-3.2.sentence-3)
[🔗](#lib:chunk,simd_)
`template<simd-size-type N, class T, class Abi>
constexpr auto chunk(const basic_vec<T, Abi>& x) noexcept;
`
[4](#simd.creation-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19175)
*Effects*: Equivalent to: return chunk<resize_t<N, basic_vec<T, Abi>>>(x);
[🔗](#lib:chunk,simd__)
`template<simd-size-type N, size_t Bytes, class Abi>
constexpr auto chunk(const basic_mask<Bytes, Abi>& x) noexcept;
`
[5](#simd.creation-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19187)
*Effects*: Equivalent to: return chunk<resize_t<N, basic_mask<Bytes, Abi>>>(x);
[🔗](#lib:cat,simd)
`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](#simd.creation-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19204)
*Constraints*:
- [(6.1)](#simd.creation-6.1)
For the first overload vec<T, (basic_vec<T, Abis>::size() + ...)> is enabled[.](#simd.creation-6.1.sentence-1)
- [(6.2)](#simd.creation-6.2)
For the second overload basic_mask<Bytes, *deduce-abi-t*<*integer-from*<Bytes>, (basic_mask<Bytes, Abis>::size() + ...)>> is enabled[.](#simd.creation-6.2.sentence-1)
[7](#simd.creation-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19217)
*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[.](#simd.creation-7.sentence-1)
#### [29.10.8.12](#simd.alg) Algorithms [[simd.alg]](simd.alg)
[🔗](#lib:min,simd)
`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](#simd.alg-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19237)
*Constraints*: T models [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")[.](#simd.alg-1.sentence-1)
[2](#simd.alg-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19241)
*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())[.](#simd.alg-2.sentence-1)
[🔗](#lib:max,simd)
`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](#simd.alg-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19255)
*Constraints*: T models [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")[.](#simd.alg-3.sentence-1)
[4](#simd.alg-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19259)
*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())[.](#simd.alg-4.sentence-1)
[🔗](#lib:minmax,simd)
`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](#simd.alg-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19273)
*Effects*: Equivalent to: return pair{min(a, b), max(a, b)};
[🔗](#lib:clamp,simd)
`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](#simd.alg-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19286)
*Constraints*: T models [totally_ordered](concept.totallyordered#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")[.](#simd.alg-6.sentence-1)
[7](#simd.alg-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19290)
*Preconditions*: No element in lo shall be greater than the corresponding element inhi[.](#simd.alg-7.sentence-1)
[8](#simd.alg-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19295)
*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())[.](#simd.alg-8.sentence-1)
[🔗](#lib:select,simd)
`template<class T, class U>
constexpr auto select(bool c, const T& a, const U& b)
-> remove_cvref_t<decltype(c ? a : b)>;
`
[9](#simd.alg-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19309)
*Effects*: Equivalent to: return c ? a : b;
[🔗](#lib:select,simd_)
`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](#simd.alg-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19322)
*Effects*: Equivalent to:return *simd-select-impl*(c, a, b); where *simd-select-impl* is found by argument-dependent
lookup ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4Argument-dependent name lookup")) contrary to [[contents]](contents "16.4.2.2Library contents")[.](#simd.alg-10.sentence-1)
#### [29.10.8.13](#simd.math) Mathematical functions [[simd.math]](simd.math)
[🔗](#lib:ilogb,simd)
`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](#simd.math-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19451)
Let Ret denote the return type of the specialization of a function
template with the name *math-func*[.](#simd.math-1.sentence-1)
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](#simd.math-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19464)
*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[.](#simd.math-2.sentence-1)
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[.](#simd.math-2.sentence-2)
[3](#simd.math-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19473)
*Remarks*: It is unspecified whether errno ([[errno]](errno "19.4Error numbers")) is accessed[.](#simd.math-3.sentence-1)
[🔗](#lib:acos,simd)
`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](#simd.math-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19614)
Let Ret denote the return type of the specialization of a function
template with the name *math-func*[.](#simd.math-4.sentence-1)
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](#simd.math-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19627)
*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[.](#simd.math-5.sentence-1)
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[.](#simd.math-5.sentence-2)
[6](#simd.math-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19636)
*Remarks*: It is unspecified whether errno ([[errno]](errno "19.4Error numbers")) is accessed[.](#simd.math-6.sentence-1)
[🔗](#lib:frexp,simd)
`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](#simd.math-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19648)
Let Ret be *deduced-vec-t*<V>[.](#simd.math-7.sentence-1)
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)[.](#simd.math-7.sentence-3)
[8](#simd.math-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19665)
*Effects*: Sets *exp to ret.second[.](#simd.math-8.sentence-1)
[9](#simd.math-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19669)
*Returns*: ret.first[.](#simd.math-9.sentence-1)
[🔗](#lib:remquo,simd)
`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](#simd.math-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19682)
Let Ret be *math-common-simd-t*<V0, V1>[.](#simd.math-10.sentence-1)
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)[.](#simd.math-10.sentence-3)
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[.](#simd.math-10.sentence-4)
[11](#simd.math-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19703)
*Effects*: Sets *quo to ret.second[.](#simd.math-11.sentence-1)
[12](#simd.math-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19707)
*Returns*: ret.first[.](#simd.math-12.sentence-1)
[13](#simd.math-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19711)
*Remarks*: It is unspecified whether errno ([[errno]](errno "19.4Error numbers")) is accessed[.](#simd.math-13.sentence-1)
[🔗](#lib:modf,simd)
`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](#simd.math-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19724)
Let V be basic_vec<T, Abi>[.](#simd.math-14.sentence-1)
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)[.](#simd.math-14.sentence-3)
[15](#simd.math-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19739)
*Effects*: Sets *iptr to ret.second[.](#simd.math-15.sentence-1)
[16](#simd.math-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19743)
*Returns*: ret.first[.](#simd.math-16.sentence-1)
#### [29.10.8.14](#simd.bit) basic_vec bit library [[simd.bit]](simd.bit)
[🔗](#lib:byteswap,simd)
`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](#simd.bit-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19756)
*Constraints*: The type V::value_type models [integral](concepts.arithmetic#concept:integral "18.4.7Arithmetic concepts[concepts.arithmetic]")[.](#simd.bit-1.sentence-1)
[2](#simd.bit-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19760)
*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())[.](#simd.bit-2.sentence-1)
[🔗](#lib:bit_ceil,simd)
`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](#simd.bit-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19773)
*Constraints*: The type V::value_type is an unsigned integer type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#simd.bit-3.sentence-1)
[4](#simd.bit-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19777)
*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[.](#simd.bit-4.sentence-1)
[5](#simd.bit-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19783)
*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())[.](#simd.bit-5.sentence-1)
[6](#simd.bit-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19789)
*Remarks*: A function call expression that violates the precondition in the *Preconditions*: element is not a core constant expression ([[expr.const]](expr.const "7.7Constant expressions"))[.](#simd.bit-6.sentence-1)
[🔗](#lib:bit_floor,simd)
`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](#simd.bit-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19801)
*Constraints*: The type V::value_type is an unsigned integer type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#simd.bit-7.sentence-1)
[8](#simd.bit-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19805)
*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())[.](#simd.bit-8.sentence-1)
[🔗](#lib:has_single_bit,simd)
`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](#simd.bit-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19819)
*Constraints*: The type V::value_type is an unsigned integer type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#simd.bit-9.sentence-1)
[10](#simd.bit-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19823)
*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())[.](#simd.bit-10.sentence-1)
[🔗](#lib:rotl,simd)
`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](#simd.bit-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19840)
*Constraints*:
- [(11.1)](#simd.bit-11.1)
The type V0::value_type is an unsigned integer type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types")),
- [(11.2)](#simd.bit-11.2)
the type V1::value_type models [integral](concepts.arithmetic#concept:integral "18.4.7Arithmetic concepts[concepts.arithmetic]"),
- [(11.3)](#simd.bit-11.3)
V0::size() == V1::size() is true, and
- [(11.4)](#simd.bit-11.4)
sizeof(typename V0::value_type) == sizeof(typename V1::value_type) is true[.](#simd.bit-11.sentence-1)
[12](#simd.bit-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19853)
*Returns*: A basic_vec object where the ith 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>](bit.general#header:%3cbit%3e "22.11.1General[bit.general]")[.](#simd.bit-12.sentence-1)
[🔗](#lib:rotl,simd_)
`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](#simd.bit-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19869)
*Constraints*: The type V::value_type is an unsigned integer type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#simd.bit-13.sentence-1)
[14](#simd.bit-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19873)
*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 [<bit>](bit.general#header:%3cbit%3e "22.11.1General[bit.general]")[.](#simd.bit-14.sentence-1)
[🔗](#lib:bit_width,simd)
`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](#simd.bit-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19903)
*Constraints*: The type V::value_type is an unsigned integer type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#simd.bit-15.sentence-1)
[16](#simd.bit-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19907)
*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 [<bit>](bit.general#header:%3cbit%3e "22.11.1General[bit.general]")[.](#simd.bit-16.sentence-1)
#### [29.10.8.15](#simd.complex.math) vec complex math [[simd.complex.math]](simd.complex.math)
[🔗](#lib:real,simd)
`template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V>
constexpr rebind_t<simd-complex-value-type<V>, V> real(const V&) noexcept;
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V>
constexpr rebind_t<simd-complex-value-type<V>, V> imag(const V&) noexcept;
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V>
constexpr rebind_t<simd-complex-value-type<V>, V> abs(const V&);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V>
constexpr rebind_t<simd-complex-value-type<V>, V> arg(const V&);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V>
constexpr rebind_t<simd-complex-value-type<V>, V> norm(const V&);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V conj(const V&);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V proj(const V&);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V exp(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V log(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V log10(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V sqrt(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V sin(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V asin(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V cos(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V acos(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V tan(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V atan(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V sinh(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V asinh(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V cosh(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V acosh(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V tanh(const V& v);
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V atanh(const V& v);
`
[1](#simd.complex.math-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19975)
*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 [<complex>](complex.syn#header:%3ccomplex%3e "29.4.2Header <complex> synopsis[complex.syn]")[.](#simd.complex.math-1.sentence-1)
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[.](#simd.complex.math-1.sentence-2)
[2](#simd.complex.math-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19984)
*Remarks*: It is unspecified whether errno ([[errno]](errno "19.4Error numbers")) is accessed[.](#simd.complex.math-2.sentence-1)
[🔗](#lib:polar,simd)
`template<[simd-floating-point](simd.expos#concept:simd-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V>
rebind_t<complex<typename V::value_type>, V> polar(const V& x, const V& y = {});
template<[simd-complex](simd.expos#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") V> constexpr V pow(const V& x, const V& y);
`
[3](#simd.complex.math-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19999)
*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 [<complex>](complex.syn#header:%3ccomplex%3e "29.4.2Header <complex> synopsis[complex.syn]")[.](#simd.complex.math-3.sentence-1)
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[.](#simd.complex.math-3.sentence-2)
[4](#simd.complex.math-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20008)
*Remarks*: It is unspecified whether errno ([[errno]](errno "19.4Error numbers")) is accessed[.](#simd.complex.math-4.sentence-1)