[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> constexpr T reduce(const basic_vec& 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.1 Exposition-only helpers [simd.expos.defn]")[.](#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(x[0]), …, vec(x[x.size() - 1]))[​0] ([[numerics.defns]](numerics.defns "26.10.2 Definitions"))[.](#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> constexpr T reduce( const basic_vec& x, const typename basic_vec::mask_type& mask, BinaryOperation binary_op = {}, type_identity_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.1 Exposition-only helpers [simd.expos.defn]")[.](#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(identity_element), vec(y))[0] and y == binary_op(vec(y), vec(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(x[k0]), …, vec(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 constexpr T reduce_min(const basic_vec& 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.5 Concept 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​::​size())[.](#simd.reductions-11.sentence-1) [🔗](#lib:reduce_min,simd_) `template constexpr T reduce_min( const basic_vec&, const typename basic_vec::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.5 Concept 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​::​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 constexpr T reduce_max(const basic_vec& 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.5 Concept 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​::​size())[.](#simd.reductions-15.sentence-1) [🔗](#lib:reduce_max,simd_) `template constexpr T reduce_max( const basic_vec&, const typename basic_vec::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.5 Concept 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​::​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 requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr V unchecked_load(R&& r, flags f = {}); template requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr V unchecked_load(R&& r, const typename V::mask_type& mask, flags f = {}); template constexpr V unchecked_load(I first, iter_difference_t n, flags f = {}); template constexpr V unchecked_load(I first, iter_difference_t n, const typename V::mask_type& mask, flags f = {}); template S, class... Flags> constexpr V unchecked_load(I first, S last, flags f = {}); template S, class... Flags> constexpr V unchecked_load(I first, S last, const typename V::mask_type& mask, 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> 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(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>[.](#simd.loadstore-5.sentence-1) [🔗](#lib:partial_load,simd) `template requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr V partial_load(R&& r, flags f = {}); template requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr V partial_load(R&& r, const typename V::mask_type& mask, flags f = {}); template constexpr V partial_load(I first, iter_difference_t n, flags f = {}); template constexpr V partial_load(I first, iter_difference_t n, const typename V::mask_type& mask, flags f = {}); template S, class... Flags> constexpr V partial_load(I first, S last, flags f = {}); template S, class... Flags> constexpr V partial_load(I first, S last, const typename V::mask_type& mask, 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> 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 is a vectorizable type, - [(7.2)](#simd.loadstore-7.2) same_as, 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 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>[.](#simd.loadstore-8.3.sentence-1) - [(8.4)](#simd.loadstore-8.4) If the template parameter pack Flags contains *overaligned-flag*, 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(​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>[.](#simd.loadstore-10.sentence-1) [🔗](#lib:unchecked_store,simd) `template requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") && [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]"), T> constexpr void unchecked_store(const basic_vec& v, R&& r, flags f = {}); template requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") && [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]"), T> constexpr void unchecked_store(const basic_vec& v, R&& r, const typename basic_vec::mask_type& mask, flags f = {}); template requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]") constexpr void unchecked_store(const basic_vec& v, I first, iter_difference_t n, flags f = {}); template requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]") constexpr void unchecked_store(const basic_vec& v, I first, iter_difference_t n, const typename basic_vec::mask_type& mask, flags f = {}); template S, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]") constexpr void unchecked_store(const basic_vec& v, I first, S last, flags f = {}); template S, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]") constexpr void unchecked_store(const basic_vec& v, I first, S last, const typename basic_vec::mask_type& mask, 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​::​mask_type(true) for the overloads with no mask parameter; - [(11.2)](#simd.loadstore-11.2) R be span> 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*[.](#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* [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 requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") && [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]"), T> constexpr void partial_store(const basic_vec& v, R&& r, flags f = {}); template requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") && [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]"), T> constexpr void partial_store(const basic_vec& v, R&& r, const typename basic_vec::mask_type& mask, flags f = {}); template requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]") constexpr void partial_store(const basic_vec& v, I first, iter_difference_t n, flags f = {}); template requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]") constexpr void partial_store(const basic_vec& v, I first, iter_difference_t n, const typename basic_vec::mask_type& mask, flags f = {}); template S, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]") constexpr void partial_store(const basic_vec& v, I first, S last, flags f = {}); template S, class... Flags> requires [indirectly_writable](iterator.concept.writable#concept:indirectly_writable "24.3.4.3 Concept indirectly_­writable [iterator.concept.writable]") constexpr void partial_store(const basic_vec& v, I first, S last, const typename basic_vec::mask_type& mask, 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​::​mask_type(true) for the overloads with no mask parameter; - [(15.2)](#simd.loadstore-15.2) R be span> 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 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 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, ranges​::​range_value_t>[.](#simd.loadstore-17.3.sentence-1) - [(17.4)](#simd.loadstore-17.4) If the template parameter pack Flags contains *overaligned-flag*, 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​::​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 constexpr resize_t permute(const V& v, IdxMap&& idxmap); template constexpr resize_t 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.7 Arithmetic concepts [concepts.arithmetic]")> ||[integral](concepts.arithmetic#concept:integral "18.4.7 Arithmetic concepts [concepts.arithmetic]")> 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*() 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.2 Exposition-only types, variables, and concepts [simd.expos]") V, [simd-integral](simd.expos#concept:simd-integral "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") I> constexpr resize_t permute(const V& v, const I& indices); template<[simd-mask-type](simd.expos#concept:simd-mask-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") M, [simd-integral](simd.expos#concept:simd-integral "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") I> constexpr resize_t 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.2 Exposition-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.2 Exposition-only types, variables, and concepts [simd.expos]") M> constexpr M compress(const M& v, const type_identity_t& 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.2 Exposition-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.2 Exposition-only types, variables, and concepts [simd.expos]") M> constexpr M compress(const M& v, const type_identity_t& 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.2 Exposition-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.2 Exposition-only types, variables, and concepts [simd.expos]") M> constexpr M expand(const M& v, const type_identity_t& 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 requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr V unchecked_gather_from(R&& in, const I& indices, flags f = {}); template requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr V unchecked_gather_from(R&& in, const typename I::mask_type& mask, const I& indices, 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(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, I​::​​size()>[.](#simd.permute.memory-4.sentence-1) [🔗](#lib:partial_gather_from,simd) `template requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr V partial_gather_from(R&& in, const I& indices, flags f = {}); template requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr V partial_gather_from(R&& in, const typename I::mask_type& mask, const I& indices, 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 is a vectorizable type, - [(6.2)](#simd.permute.memory-6.2) same_as, 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 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>[.](#simd.permute.memory-7.1.sentence-1) - [(7.2)](#simd.permute.memory-7.2) If the template parameter pack Flags contains*overaligned-flag*, 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(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, 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.2 Exposition-only types, variables, and concepts [simd.expos]") V, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr void unchecked_scatter_to(const V& v, R&& out, const I& indices, flags f = {}); template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr void unchecked_scatter_to(const V& v, R&& out, const typename I::mask_type& mask, const I& indices, 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.2 Exposition-only types, variables, and concepts [simd.expos]") V, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr void partial_scatter_to(const V& v, R&& out, const I& indices, flags f = {}); template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V, ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]") R, [simd-integral](simd.expos#concept:simd-integral "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") I, class... Flags> requires ranges::[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") constexpr void partial_scatter_to(const V& v, R&& out, const typename I::mask_type& mask, const I& indices, 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 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 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>[.](#simd.permute.memory-16.2.sentence-1) - [(16.3)](#simd.permute.memory-16.3) If the template parameter pack Flags contains*overaligned-flag*,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 constexpr auto chunk(const basic_vec& x) noexcept; template constexpr auto chunk(const basic_mask, 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​::​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*, Abi>​::​size() % T​::​size() is not 0, then resize_t<​basic_mask<​*mask-element-size*, Abi>​::​size() % T​::​size(), T> is valid and denotes a type[.](#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 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[.](#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 constexpr auto chunk(const basic_vec& x) noexcept; ` [4](#simd.creation-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19175) *Effects*: Equivalent to: return chunk>>(x); [🔗](#lib:chunk,simd__) `template constexpr auto chunk(const basic_mask& x) noexcept; ` [5](#simd.creation-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19187) *Effects*: Equivalent to: return chunk>>(x); [🔗](#lib:cat,simd) `template constexpr vec::size() + ...)> cat(const basic_vec&... xs) noexcept; template constexpr basic_mask, (basic_mask::size() + ...)>> cat(const basic_mask&... 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​::​size() + ...)> is enabled[.](#simd.creation-6.1.sentence-1) - [(6.2)](#simd.creation-6.2) For the second overload basic_mask, (basic_mask​::​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 constexpr basic_vec min(const basic_vec& a, const basic_vec& 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.5 Concept 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​::​size())[.](#simd.alg-2.sentence-1) [🔗](#lib:max,simd) `template constexpr basic_vec max(const basic_vec& a, const basic_vec& 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.5 Concept 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​::​size())[.](#simd.alg-4.sentence-1) [🔗](#lib:minmax,simd) `template constexpr pair, basic_vec> minmax(const basic_vec& a, const basic_vec& 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 constexpr basic_vec clamp( const basic_vec& v, const basic_vec& lo, const basic_vec& 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.5 Concept 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​::​size())[.](#simd.alg-8.sentence-1) [🔗](#lib:select,simd) `template constexpr auto select(bool c, const T& a, const U& b) -> remove_cvref_t; ` [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 constexpr auto select(const basic_mask& 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.4 Argument-dependent name lookup")) contrary to [[contents]](contents "16.4.2.2 Library 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.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t> ilogb(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t ldexp(const V& x, const rebind_t>& exp); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t scalbn(const V& x, const rebind_t>& n); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t scalbln(const V& x, const rebind_t>& n); template<[signed_integral](concepts.arithmetic#concept:signed_integral "18.4.7 Arithmetic concepts [concepts.arithmetic]") T, class Abi> constexpr basic_vec abs(const basic_vec& j); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t abs(const V& j); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t fabs(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t ceil(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t floor(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t nearbyint(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t rint(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> rebind_t> lrint(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> rebind_t> llrint(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t round(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t> lround(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t> llround(const V& x); template constexpr math-common-simd-t fmod(const V0& x, const V1& y); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t trunc(const V& x); template constexpr math-common-simd-t remainder(const V0& x, const V1& y); template constexpr math-common-simd-t copysign(const V0& x, const V1& y); template constexpr math-common-simd-t nextafter(const V0& x, const V1& y); template constexpr math-common-simd-t fdim(const V0& x, const V1& y); template constexpr math-common-simd-t fmax(const V0& x, const V1& y); template constexpr math-common-simd-t fmin(const V0& x, const V1& y); template constexpr math-common-simd-t fma(const V0& x, const V1& y, const V2& z); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t> fpclassify(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr typename deduced-vec-t::mask_type isfinite(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr typename deduced-vec-t::mask_type isinf(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr typename deduced-vec-t::mask_type isnan(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr typename deduced-vec-t::mask_type isnormal(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr typename deduced-vec-t::mask_type signbit(const V& x); template constexpr typename math-common-simd-t::mask_type isgreater(const V0& x, const V1& y); template constexpr typename math-common-simd-t::mask_type isgreaterequal(const V0& x, const V1& y); template constexpr typename math-common-simd-t::mask_type isless(const V0& x, const V1& y); template constexpr typename math-common-simd-t::mask_type islessequal(const V0& x, const V1& y); template constexpr typename math-common-simd-t::mask_type islessgreater(const V0& x, const V1& y); template constexpr typename math-common-simd-t::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 Ret *math-func-vec*(Args... args) {return Ret([&](*simd-size-type* i) {*math-func*(*make-compatible-simd-t*(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.4 Error numbers")) is accessed[.](#simd.math-3.sentence-1) [🔗](#lib:acos,simd) `template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t acos(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t asin(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t atan(const V& x); template constexpr math-common-simd-t atan2(const V0& y, const V1& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t cos(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t sin(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t tan(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t acosh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t asinh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t atanh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t cosh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t sinh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t tanh(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t exp(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t exp2(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t expm1(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t log(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t log10(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t log1p(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t log2(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t logb(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t cbrt(const V& x); template constexpr math-common-simd-t hypot(const V0& x, const V1& y); template constexpr math-common-simd-t hypot(const V0& x, const V1& y, const V2& z); template constexpr math-common-simd-t pow(const V0& x, const V1& y); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t sqrt(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t erf(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t erfc(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t lgamma(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t tgamma(const V& x); template constexpr math-common-simd-t lerp(const V0& a, const V1& b, const V2& t) noexcept; template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t assoc_laguerre(const rebind_t>& n, const rebind_t>& m, const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t assoc_legendre(const rebind_t>& l, const rebind_t>& m, const V& x); template math-common-simd-t beta(const V0& x, const V1& y); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t comp_ellint_1(const V& k); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t comp_ellint_2(const V& k); template math-common-simd-t comp_ellint_3(const V0& k, const V1& nu); template math-common-simd-t cyl_bessel_i(const V0& nu, const V1& x); template math-common-simd-t cyl_bessel_j(const V0& nu, const V1& x); template math-common-simd-t cyl_bessel_k(const V0& nu, const V1& x); template math-common-simd-t cyl_neumann(const V0& nu, const V1& x); template math-common-simd-t ellint_1(const V0& k, const V1& phi); template math-common-simd-t ellint_2(const V0& k, const V1& phi); template math-common-simd-t ellint_3(const V0& k, const V1& nu, const V2& phi); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t expint(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t hermite(const rebind_t>& n, const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t laguerre(const rebind_t>& n, const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t legendre(const rebind_t>& l, const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t riemann_zeta(const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t sph_bessel(const rebind_t>& n, const V& x); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t sph_legendre(const rebind_t>& l, const rebind_t>& m, const V& theta); template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> deduced-vec-t sph_neumann(const rebind_t>& 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 Ret *math-func-vec*(Args... args) {return Ret([&](*simd-size-type* i) {*math-func*(*make-compatible-simd-t*(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.4 Error numbers")) is accessed[.](#simd.math-6.sentence-1) [🔗](#lib:frexp,simd) `template<[math-floating-point](simd.expos#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr deduced-vec-t frexp(const V& value, rebind_t>* exp); ` [7](#simd.math-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19648) Let Ret be *deduced-vec-t*[.](#simd.math-7.sentence-1) Let *frexp-vec* denote:template pair> *frexp-vec*(const V& x) {int r1[Ret::size()]; Ret r0([&](*simd-size-type* i) { frexp(*make-compatible-simd-t*(x)[i], &r1[i]); }); return {r0, rebind_t(r1)};} Let ret be a value of type pair> 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 constexpr math-common-simd-t remquo(const V0& x, const V1& y, rebind_t>* quo); ` [10](#simd.math-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19682) Let Ret be *math-common-simd-t*[.](#simd.math-10.sentence-1) Let *remquo-vec* denote:template pair> *remquo-vec*(const V0& x, const V1& y) {int r1[Ret::size()]; Ret r0([&](*simd-size-type* i) { remquo(*make-compatible-simd-t*(x)[i], *make-compatible-simd-t*(y)[i], &r1[i]); }); return {r0, rebind_t(r1)};} Let ret be a value of type pair> 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.4 Error numbers")) is accessed[.](#simd.math-13.sentence-1) [🔗](#lib:modf,simd) `template constexpr basic_vec modf(const type_identity_t>& value, basic_vec* iptr); ` [14](#simd.math-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L19724) Let V be basic_vec[.](#simd.math-14.sentence-1) Let *modf-vec* denote:pair *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 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.2 Exposition-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.7 Arithmetic 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.2 Exposition-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.2 Fundamental 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.7 Constant expressions"))[.](#simd.bit-6.sentence-1) [🔗](#lib:bit_floor,simd) `template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-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.2 Fundamental 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.2 Exposition-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.2 Fundamental 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.2 Exposition-only types, variables, and concepts [simd.expos]") V0, [simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-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.2 Exposition-only types, variables, and concepts [simd.expos]") V0, [simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-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.2 Fundamental types")), - [(11.2)](#simd.bit-11.2) the type V1​::​value_type models [integral](concepts.arithmetic#concept:integral "18.4.7 Arithmetic 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(v1[i])) for all i in the range [0, V0​::​size()), where *bit-func* is the corresponding scalar function from [](bit.general#header:%3cbit%3e "22.11.1 General [bit.general]")[.](#simd.bit-12.sentence-1) [🔗](#lib:rotl,simd_) `template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-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.2 Exposition-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.2 Fundamental 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.general#header:%3cbit%3e "22.11.1 General [bit.general]")[.](#simd.bit-14.sentence-1) [🔗](#lib:bit_width,simd) `template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, V> bit_width(const V& v) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, V> countl_zero(const V& v) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, V> countl_one(const V& v) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, V> countr_zero(const V& v) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, V> countr_one(const V& v) noexcept; template<[simd-vec-type](simd.expos#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, 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.2 Fundamental 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.general#header:%3cbit%3e "22.11.1 General [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.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, V> real(const V&) noexcept; template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, V> imag(const V&) noexcept; template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, V> abs(const V&); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, V> arg(const V&); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr rebind_t, V> norm(const V&); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V conj(const V&); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V proj(const V&); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V exp(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V log(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V log10(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V sqrt(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V sin(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V asin(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V cos(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V acos(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V tan(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V atan(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V sinh(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V asinh(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V cosh(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V acosh(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> constexpr V tanh(const V& v); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-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.syn#header:%3ccomplex%3e "29.4.2 Header 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.4 Error numbers")) is accessed[.](#simd.complex.math-2.sentence-1) [🔗](#lib:polar,simd) `template<[simd-floating-point](simd.expos#concept:simd-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") V> rebind_t, V> polar(const V& x, const V& y = {}); template<[simd-complex](simd.expos#concept:simd-complex "29.10.2 Exposition-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.syn#header:%3ccomplex%3e "29.4.2 Header 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.4 Error numbers")) is accessed[.](#simd.complex.math-4.sentence-1)