This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
ranges::size(r)
Constraints and Mandates in [simd]Section: 29.10 [simd] Status: New Submitter: Lénárd Szolnoki Opened: 2025-10-10 Last modified: 2025-10-12
Priority: Not Prioritized
View all issues with New status.
Discussion:
Various Constraints and Mandates in 29.10 [simd] are conditioned on ranges::size(r)
,
assuming that subsequent operations on the result are also constant expression. This is not a given,
since ranges::size(r)
is allowed to return an integer-class type, and it is not mandated that operations
on integer-class types are usable in constant expressions.
29.10.7.2 [simd.ctor] p13:
Constraints:
R
modelsranges::contiguous_range
andranges::sized_range
,
ranges::size(r)
is a constant expression, and
ranges::size(r)
is equal tosize()
.
Here ranges::size(r) == size()
might not be a constant expression, even when ranges::size(r)
is. Operations that are not accounted for:
Possible conversion from range::size(r)
to simd-size-type
.
Possible operator overloading on ==.
29.10.7.2 [simd.ctor] p17+18:
Constraints:
R
modelsranges::contiguous_range
andranges::sized_range
, and
ranges::size(r)
is a constant expressionRemarks: The deduced type is equivalent to
vec<ranges::range_value_t<R>, ranges::size(r)>
.
Here the second constraint is simply redundant, if failure to form the type is in the immediate context.
If we want to type it out in the constraints then we should account for conversion to simd-size-type
and narrowing.
29.10.8.7 [simd.loadstore] p2:
Mandates: If
ranges::size(r)
is a constant expression thenranges::size(r)
≥V::size()
.
Here ranges::size(r) >= V::size()
might not be a constant expression, even when
ranges::size(r)
is. It is unclear why a mathematical operator symbol is used here (and further
down in the preconditions).
Proposed resolution:
This wording is relative to N5014.
Modify 29.10.7.2 [simd.ctor] as indicated:
template<class R, class... Flags> constexpr basic_vec(R&& r, flags<Flags...> = {}); template<class R, class... Flags> constexpr basic_vec(R&& r, const mask_type& mask, flags<Flags...> = {});-12- Let
-13- Constraints:mask
bemask_type(true)
for the overload with nomask
parameter.[…]
(13.1) —
R
modelsranges::contiguous_range
andranges::sized_range
, and(13.2) —
ranges::size(r) == size()
is a constant expression, and evaluates totrue
.
(13.3) —ranges::size(r)
is equal tosize()
.template<class R, class... Ts> basic_vec(R&& r, Ts...) -> see below;-17- Constraints:
(17.1) —R
modelsranges::contiguous_range
andranges::sized_range
, and.
(17.2) —ranges::size(r)
is a constant expression.-18- Remarks: The deduced type is equivalent to
vec<ranges::range_value_t<R>, ranges::size(r)>
.
Modify 29.10.8.7 [simd.loadstore] as indicated:
template<class V = see below, ranges::contiguous_range R, class... Flags> requires ranges::sized_range<R> constexpr V unchecked_load(R&& r, flags<Flags...> f = {}); […] template<class V = see below, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags> constexpr V unchecked_load(I first, S last, const typename V::mask_type& mask, flags<Flags...> f = {});-1- Let […]
-2- Mandates: Ifranges::size(r) >= V::size()
is a constant expression thenit evaluates toranges::size(r)
≥V::size()
true
.