Created on 2025-09-24.00:00:00 last changed 1 month ago
Proposed resolution:
This wording is relative to N5014.
Modify [simd.mask.overview], class template basic_mask synopsis, as indicated:
namespace std::simd {
template<size_t Bytes, class Abi> class basic_mask {
public:
[…]
constexpr basic_mask() noexcept = default;
// [simd.mask.ctor], basic_mask constructors
constexpr explicit basic_mask(same_as<value_type> auto) 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;
template<same_as<bitset<size()>> T>
constexpr basic_mask(const Tbitset<size()>& b) noexcept;
template<unsigned_integral T> requires (!same_as<T, value_type>)
constexpr explicit basic_mask(Tunsigned_integral auto val) noexcept;
[…]
};
}
Modify [simd.mask.ctor] as indicated:
constexpr explicit basic_mask(same_as<value_type> auto x) noexcept;[…]-1- Effects: Initializes each element with `x`.
template<same_as<bitset<size()>> T> constexpr basic_mask(const Tbitset<size()>& b) noexcept;-7- Effects: Initializes the ith element with b[i] for all i in the range `[0, size())`.
template<unsigned_integral T> requires (!same_as<T, value_type>) constexpr explicit basic_mask(Tunsigned_integral autoval) noexcept;-8- Effects: Initializes the first M elements to the corresponding bit values in `val`, […]
[ Kona 2025-11-08; Status changed: Voting → WP. ]
[ 2025-10-23; Reflector poll. ]
Set status to Tentatively Ready after seven votes in favour during reflector poll.
[ 2025-10-06; Matthias Kretz improves wording after reflector discussion ]
[simd.mask.ctor] defines the overloads `basic_mask(bool)` and `basic_mask(unsigned_integral auto)`. This leads to the following pitfall:
auto g0() {
unsigned short k = 0xf;
return simd::mask<float, 8>(k); // mov eax, 15
}
auto g1() {
unsigned short k = 0xf;
return simd::mask<float, 8>(k >> 1); // mov eax, -1 ⚠️
}
auto g2() {
unsigned int k = 0xf;
return simd::mask<float, 8>(k >> 1); // mov eax, 7
}
In `g1`, `k` is promoted to `int`, shifted and then passed to the mask constructor. Instead of failing, `int(0x7)` is converted to `bool` and the mask thus initialized to all `true`.
Also consider:simd::mask<float>(true_type());
unsigned_integral<bool> is `true` => same_as<bool> auto instead of 'bool' makes the overload set ambiguous
`float` is convertible to `bool`, thus simd::mask<float>(1.f) continues to compile
This wording is relative to N5014.
Modify [simd.mask.overview], class template basic_mask synopsis, as indicated:
namespace std::simd {
template<size_t Bytes, class Abi> class basic_mask {
public:
[…]
constexpr basic_mask() noexcept = default;
// [simd.mask.ctor], basic_mask constructors
constexpr 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 auto val) noexcept;
basic_mask(signed_integral auto) = delete;
[…]
};
}
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2025-11-11 10:48:16 | admin | set | messages: + msg15648 |
| 2025-11-11 10:48:16 | admin | set | status: voting -> wp |
| 2025-10-30 17:45:31 | admin | set | status: ready -> voting |
| 2025-10-27 10:00:32 | admin | set | messages: + msg15460 |
| 2025-10-27 10:00:32 | admin | set | status: new -> ready |
| 2025-10-10 15:45:30 | admin | set | messages: + msg15137 |
| 2025-09-26 16:59:48 | admin | set | messages: + msg15082 |
| 2025-09-24 00:00:00 | admin | create | |