[simd.mask.class]

# 29 Numerics library [[numerics]](./#numerics)

## 29.10 Data-parallel types [[simd]](simd#mask.class)

### 29.10.9 Class template basic_mask [simd.mask.class]

#### [29.10.9.1](#simd.mask.overview) Class template basic_mask overview [[simd.mask.overview]](simd.mask.overview)

namespace std::simd {template<size_t Bytes, class Abi> class basic_mask {public:using [value_type](#lib:basic_mask,value_type "29.10.9.1 Class template basic_­mask overview [simd.mask.overview]") = bool; using [abi_type](#lib:basic_mask,abi_type "29.10.9.1 Class template basic_­mask overview [simd.mask.overview]") = Abi; using [iterator](#lib:basic_mask,iterator "29.10.9.1 Class template basic_­mask overview [simd.mask.overview]") = *simd-iterator*<basic_mask>; using [const_iterator](#lib:basic_mask,const_iterator "29.10.9.1 Class template basic_­mask overview [simd.mask.overview]") = *simd-iterator*<const basic_mask>; constexpr iterator [begin](#lib:basic_mask,begin "29.10.9.1 Class template basic_­mask overview [simd.mask.overview]")() noexcept { return {*this, 0}; }constexpr const_iterator [begin](#lib:basic_mask,begin "29.10.9.1 Class template basic_­mask overview [simd.mask.overview]")() const noexcept { return {*this, 0}; }constexpr const_iterator [cbegin](#lib:basic_mask,cbegin "29.10.9.1 Class template basic_­mask overview [simd.mask.overview]")() const noexcept { return {*this, 0}; }constexpr default_sentinel_t [end](#lib:basic_mask,end "29.10.9.1 Class template basic_­mask overview [simd.mask.overview]")() const noexcept { return {}; }constexpr default_sentinel_t [cend](#lib:basic_mask,cend "29.10.9.1 Class template basic_­mask overview [simd.mask.overview]")() const noexcept { return {}; }static constexpr integral_constant<*simd-size-type*, *simd-size-v*<*integer-from*<Bytes>, Abi>>[size](#lib:basic_mask,size "29.10.9.1 Class template basic_­mask overview [simd.mask.overview]") {}; constexpr basic_mask() noexcept = default; // [[simd.mask.ctor]](#simd.mask.ctor "29.10.9.2 basic_­mask constructors"), basic_mask constructorsconstexpr explicit basic_mask(value_type) noexcept; template<size_t UBytes, class UAbi>constexpr explicit basic_mask(const basic_mask<UBytes, UAbi>&) noexcept; template<class G>constexpr explicit basic_mask(G&& gen) noexcept; constexpr basic_mask(const bitset<size()>& b) noexcept; constexpr explicit basic_mask([unsigned_integral](concepts.arithmetic#concept:unsigned_integral "18.4.7 Arithmetic concepts [concepts.arithmetic]") auto val) noexcept; // [[simd.mask.subscr]](#simd.mask.subscr "29.10.9.3 basic_­mask subscript operator"), basic_mask subscript operatorsconstexpr value_type operator[](*simd-size-type*) const; template<[*simd-integral*](simd.expos#concept:simd-integral "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") I>constexpr resize_t<I::size(), basic_mask> operator[](const I& indices) const; // [[simd.mask.unary]](#simd.mask.unary "29.10.9.4 basic_­mask unary operators"), basic_mask unary operatorsconstexpr basic_mask operator!() const noexcept; constexpr basic_vec<*integer-from*<Bytes>, Abi> operator+() const noexcept; constexpr basic_vec<*integer-from*<Bytes>, Abi> operator-() const noexcept; constexpr basic_vec<*integer-from*<Bytes>, Abi> operator~() const noexcept; // [[simd.mask.conv]](#simd.mask.conv "29.10.9.5 basic_­mask conversions"), basic_mask conversionstemplate<class U, class A>constexpr explicit(sizeof(U) != Bytes) operator basic_vec<U, A>() const noexcept; constexpr bitset<size()> to_bitset() const noexcept; constexpr unsigned long long to_ullong() const; // [[simd.mask.binary]](simd.mask.binary "29.10.10.1 basic_­mask binary operators"), basic_mask binary operatorsfriend constexpr basic_mask operator&&(const basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask operator||(const basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask operator&(const basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask operator|(const basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask operator^(const basic_mask&, const basic_mask&) noexcept; // [[simd.mask.cassign]](simd.mask.cassign "29.10.10.2 basic_­mask compound assignment"), basic_mask compound assignmentfriend constexpr basic_mask&operator&=(basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask&operator|=(basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask&operator^=(basic_mask&, const basic_mask&) noexcept; // [[simd.mask.comparison]](simd.mask.comparison "29.10.10.3 basic_­mask comparisons"), basic_mask comparisonsfriend constexpr basic_mask operator==(const basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask operator!=(const basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask operator>=(const basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask operator<=(const basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask operator>(const basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask operator<(const basic_mask&, const basic_mask&) noexcept; // [[simd.mask.cond]](simd.mask.cond "29.10.10.4 basic_­mask exposition only conditional operators"), basic_mask exposition only conditional operatorsfriend constexpr basic_mask *simd-select-impl*( // *exposition only*const basic_mask&, const basic_mask&, const basic_mask&) noexcept; friend constexpr basic_mask *simd-select-impl*( // *exposition only*const basic_mask&, [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<bool> auto, [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<bool> auto) noexcept; template<class T0, class T1>friend constexpr vec<*see below*, size()>*simd-select-impl*(const basic_mask&, const T0&, const T1&) noexcept; // *exposition only*};}

[1](#simd.mask.overview-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20109)

Every specialization of basic_mask is a complete type[.](#simd.mask.overview-1.sentence-1)

The specialization of basic_mask<Bytes, Abi> is:

- [(1.1)](#simd.mask.overview-1.1)

disabled, if there is no vectorizable type T such that Bytes is equal to sizeof(T),

- [(1.2)](#simd.mask.overview-1.2)

otherwise, enabled, if there exists a vectorizable type T and a
 value N in the range [1, 64] such that Bytes is equal
 to sizeof(T) and Abi is *deduce-abi-t*<T,
 N>,

- [(1.3)](#simd.mask.overview-1.3)

otherwise, it is implementation-defined if such a specialization is enabled[.](#simd.mask.overview-1.sentence-2)

If basic_mask<Bytes, Abi> is disabled, the specialization has a
deleted default constructor, deleted destructor, deleted copy constructor, and
deleted copy assignment[.](#simd.mask.overview-1.sentence-3)

In addition only the value_type and abi_type members are
present[.](#simd.mask.overview-1.sentence-4)

If basic_mask<Bytes, Abi> is enabled,basic_mask<Bytes, Abi> is trivially copyable[.](#simd.mask.overview-1.sentence-5)

[2](#simd.mask.overview-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20135)

*Recommended practice*: Implementations should support implicit conversions between
specializations of basic_mask and appropriate implementation-defined types[.](#simd.mask.overview-2.sentence-1)

[*Note [1](#simd.mask.overview-note-1)*:

Appropriate types are non-standard vector types which are available in the
implementation[.](#simd.mask.overview-2.sentence-2)

â *end note*]

#### [29.10.9.2](#simd.mask.ctor) basic_mask constructors [[simd.mask.ctor]](simd.mask.ctor)

[ð](#lib:basic_mask,constructor)

`constexpr explicit basic_mask(value_type x) noexcept;
`

[1](#simd.mask.ctor-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20152)

*Effects*: Initializes each element with x[.](#simd.mask.ctor-1.sentence-1)

[ð](#lib:basic_mask,constructor_)

`template<size_t UBytes, class UAbi>
  constexpr explicit basic_mask(const basic_mask<UBytes, UAbi>& x) noexcept;
`

[2](#simd.mask.ctor-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20164)

*Constraints*: basic_mask<UBytes, UAbi>​::​size() == size() istrue[.](#simd.mask.ctor-2.sentence-1)

[3](#simd.mask.ctor-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20169)

*Effects*: Initializes the ith element with x[i] for all i in the
range of [0, size())[.](#simd.mask.ctor-3.sentence-1)

[ð](#lib:basic_mask,constructor__)

`template<class G> constexpr explicit basic_mask(G&& gen);
`

[4](#simd.mask.ctor-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20181)

*Constraints*: The expression gen(integral_constant<*simd-size-type*, i>()) is
well-formed and its type is bool for all i in the range of
[0, size())[.](#simd.mask.ctor-4.sentence-1)

[5](#simd.mask.ctor-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20187)

*Effects*: Initializes the ith element withgen(integral_constant<*simd-size-type*, i>()) for all i in
the range of [0, size())[.](#simd.mask.ctor-5.sentence-1)

[6](#simd.mask.ctor-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20193)

*Remarks*: gen is invoked exactly once for each i, in increasing order of i[.](#simd.mask.ctor-6.sentence-1)

[ð](#lib:basic_mask,constructor___)

`constexpr basic_mask(const bitset<size()>& b) noexcept;
`

[7](#simd.mask.ctor-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20204)

*Effects*: Initializes the ith element with b[i] for all i in the
range [0, size())[.](#simd.mask.ctor-7.sentence-1)

[ð](#lib:basic_mask,constructor____)

`constexpr explicit basic_mask([unsigned_integral](concepts.arithmetic#concept:unsigned_integral "18.4.7 Arithmetic concepts [concepts.arithmetic]") auto val) noexcept;
`

[8](#simd.mask.ctor-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20216)

*Effects*: Initializes the first M elements to the corresponding bit values inval, where M is the smaller of size() and the number of bits in
the value representation ([[basic.types.general]](basic.types.general "6.9.1 General")) of the type of val[.](#simd.mask.ctor-8.sentence-1)

IfM is less than size(), the remaining elements are initialized to
zero[.](#simd.mask.ctor-8.sentence-2)

#### [29.10.9.3](#simd.mask.subscr) basic_mask subscript operator [[simd.mask.subscr]](simd.mask.subscr)

[ð](#lib:operator%5b%5d,basic_mask)

`constexpr value_type operator[](simd-size-type i) const;
`

[1](#simd.mask.subscr-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20233)

*Preconditions*: i >= 0 && i < size() is true[.](#simd.mask.subscr-1.sentence-1)

[2](#simd.mask.subscr-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20237)

*Returns*: The value of the ith element[.](#simd.mask.subscr-2.sentence-1)

[3](#simd.mask.subscr-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20241)

*Throws*: Nothing[.](#simd.mask.subscr-3.sentence-1)

[ð](#lib:operator%5b%5d,basic_mask_)

`template<[simd-integral](simd.expos#concept:simd-integral "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") I>
  constexpr resize_t<I::size(), basic_mask> operator[](const I& indices) const;
`

[4](#simd.mask.subscr-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20253)

*Effects*: Equivalent to: return permute(*this, indices);

#### [29.10.9.4](#simd.mask.unary) basic_mask unary operators [[simd.mask.unary]](simd.mask.unary)

[ð](#lib:operator,operator,basic_mask)

`constexpr basic_mask operator!() const noexcept;
constexpr basic_vec<integer-from<Bytes>, Abi> operator+() const noexcept;
constexpr basic_vec<integer-from<Bytes>, Abi> operator-() const noexcept;
constexpr basic_vec<integer-from<Bytes>, Abi> operator~() const noexcept;
`

[1](#simd.mask.unary-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20272)

Let *op* be the operator[.](#simd.mask.unary-1.sentence-1)

[2](#simd.mask.unary-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20275)

*Returns*: A data-parallel object where the ith element is initialized to the
results of applying *op* to operator[](i) for all i in
the range of [0, size())[.](#simd.mask.unary-2.sentence-1)

#### [29.10.9.5](#simd.mask.conv) basic_mask conversions [[simd.mask.conv]](simd.mask.conv)

[ð](#lib:operator_basic_vec,basic_mask)

`template<class U, class A>
  constexpr explicit(sizeof(U) != Bytes) operator basic_vec<U, A>() const noexcept;
`

[1](#simd.mask.conv-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20291)

*Constraints*: *simd-size-v*<U, A> == *simd-size-v*<T, Abi>[.](#simd.mask.conv-1.sentence-1)

[2](#simd.mask.conv-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20295)

*Returns*: A data-parallel object where the ith element is initialized tostatic_cast<U>(operator[](i))[.](#simd.mask.conv-2.sentence-1)

[ð](#lib:to_bitset,basic_mask)

`constexpr bitset<size()> to_bitset() const noexcept;
`

[3](#simd.mask.conv-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20307)

*Returns*: A bitset<size()> object where the ith element is initialized tooperator[](i) for all i in the range [0, size())[.](#simd.mask.conv-3.sentence-1)

[ð](#lib:to_ullong,basic_mask)

`constexpr unsigned long long to_ullong() const;
`

[4](#simd.mask.conv-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20319)

Let N be the width of unsigned long long[.](#simd.mask.conv-4.sentence-1)

[5](#simd.mask.conv-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20322)

*Preconditions*: 

- [(5.1)](#simd.mask.conv-5.1)

size() <= N is true, or

- [(5.2)](#simd.mask.conv-5.2)

for all i in the range [N, size()), operator[](i) returns false[.](#simd.mask.conv-5.sentence-1)

[6](#simd.mask.conv-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20329)

*Returns*: The integral value corresponding to the bits in *this[.](#simd.mask.conv-6.sentence-1)

[7](#simd.mask.conv-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L20333)

*Throws*: Nothing[.](#simd.mask.conv-7.sentence-1)
