On Mon, 5 Oct 2026 at 09:49, Tomasz Kaminski <[email protected]> wrote:
>
>
>
> On Mon, Oct 5, 2026 at 10:40 AM Jonathan Wakely <[email protected]> wrote:
>>
>> Typo in "uniquness" in the subject line.
>>
>> On Fri, 24 Jul 2026 at 15:09 +0200, Tomasz Kamiński wrote:
>> >As indicated by issue LWG4606, the previous wording for checking uniqueness
>> >of the mapping was incorrect, and rejected some valid combination of 
>> >strides.
>> >
>> >Firstly, we observe that if new mapping N is produced by adding dimension
>> >(with at least two elements) to some unique mapping M, for N to remain 
>> >unique,
>> >the stride on the newly added dimension needs to be greater than to maximum
>> >index produced by M, i.e:
>> >  sum_[0,M::rank()) M.stride(1) * (M.extents().extent() - 1)
>> >As M.required_span_size() is 1 + above sum, equivalently stride needs to be
>> >greater than or equal to it.
>> >
>> >This patch, uses above to find permutation of dimension index (__perm),
>> >corresponding to order in which dimension are appended (for extent greater
>> >than one, this is equivalent to lowest to highest value of strides).
>> >Starting from zero-dimensional mapping (__cur_size == 1), in each iteration
>> >we compare the next __stride against required_span_size (__cur_span), and
>> >if check passes, we update it's value. The above also guarantees that are
>> >__stride values are greater than zero.
>> >
>> >As dimension of extent one (with one element), can be used only with index
>> >value of 0, they stride do not contribute to index value, and can be
>> >selected arbitrary (including having value zero). We handle above by moving
>> >indices corresponding such dimensions to front of __perm. To support that
>>
>> "corresponding to"
>>
>> >__popmin is modified to accept mapping from index to value.
>> >
>> >As mentioned above, stride value zero are acceptable also for dimension
>> >with extent equal to one (in addition to empty mappings). We remove
>> >unconditional check rejecting zero strides, and replace it with invocation
>> >of __stride_nonzero. This is done separately for mappings of rank one, two,
>> >three and larger. In the last case, a separate loop is only required in
>> >non-debug mode.
>> >
>> >As for the two dimension mappings, the above sum reduces to stride *
>> >(extent - 1), we continue validating them in non-debug mode. We handle
>> >degenerate mappings (at least one extent is one) first, reusing
>> >__stride_nonzero to check other dimension.
>> >
>> >libstdc++-v3/ChangeLog:
>> >
>> >       * include/std/mdspan (layout_stride::mapping::_M_check_unique):
>> >       Change the algorithm to correctly recognize examples from LWG4606
>> >       as unique.
>> >       (layout_stride::mapping(const extents_type&, span<....>)):
>> >       Assert on _M_check_unique only for non-zero ranks.
>> >       * testsuite/23_containers/mdspan/layouts/stride_neg.cc:
>> >       Expand tests cases and moved some examples to...
>> >       * testsuite/23_containers/mdspan/layouts/stride_debug_neg.cc:
>> >       Separate test for issues detected only in debug mode.
>> >---
>> >I have separate stride_debug_neg as DejaGNU was giving me strange failure
>> >on dg-bogus line, when there was error on that line on mdspan header. It
>> >is also easier to read the output that way.
>> >
>> >Given the little induction based "proof" for the condition above, I am
>> >pretty certain that I got it correctly.
>> >
>> >Testing on x86_64-linux. *mdspan* test passed in 32bits, debug and
>> >all standard modes. OK for trunk, either now or after issue is approved?
>>
>> OK for trunk with the typos above and below fixed, thanks.
>
> I would backport it to 16 together with r17-2356-g1a4d8dc0d2dc04, after
> letting it sit for some time. OK for 16 for both?

Yes for both - thanks.

Reply via email to