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.
