libstdc++: questions about P3663
Tomasz Kamiński
tomaszkam@gmail.com
Fri Oct 31 21:03:14 GMT 2025
There are a few general comments on the wording that I think are worth
clearing:
1) Mandates means that a program containing a call that does not specify
the requirements is ill-formed.
This does not mean static_assert; any compiler diagnostic is fine. Note
that the standard does not even say that
that ill-formed program (including failing Mandates) must not produce
binary, just emit at least one diagnostic.
2) The layout mapping requirements, where a unit/valid stride definition
exists, are requirements put on
user-provided sliceable layouts that aim to interoperate with submspan.
Such user-provided mappings
will only see one kind of unit-stride (strided_slice with stride being
cw<1>), and valid slices are only
ones of canonical types at that point
3) This is repeated often in discussion, but a standard is not a tutorial.
This is why we do not describe
what kind of slices are transformed to unit-stride (pairs, tuples), or what
inputs are considered valid
slices after canonicalization. The only goal is to describe the
canonicalization process in a way that
can be implemented. Such distinction should be part of "how to use
submdspan" presentations or tutorials.
This is why I am opposed to defining "canonical unit-stride" or "canonical
valid slice", as non-canonical
ones are not important from the perspective of layout creators, for which
this section is intended.
Regards,
Tomasz
pt., 31 paź 2025 o 19:46 Mark Hoemmen <mark.hoemmen@gmail.com> napisał(a):
> Hi Luc and other libstdc++ devs!
>
> Jonathan Wakely pointed out your questions about P3663 (
> https://gcc.gnu.org/pipermail/libstdc++/2025-October/064198.html ).
> I'll answer them here.
>
> > 1. What are the requirements for user provided integer-like objects
> (when used as slices)? Do they need to have copy and move ctors? There's a
> few locations where non-canonicalized slices are copied, e.g. when passed
> to `submdspan_canonical_slices`.
>
> The original `submdspan` proposal P2630 never made this clear. P3663
> doesn't try to resolve that.
>
> The reference implementation copies slices all over the place. I
> think it's fair to assume that slice specifiers are copyable and
> movable.
>
> Design intent for what you call "user provided integer-like objects"
> includes "strong typedefs," say special index types that people use in
> nested for loops to make sure that they aren't getting the order of
> indices wrong (that implies wrapping mdspan's `operator[]`). Those
> normally don't need the full set of integer operations, just what they
> would need to make sense in a for loop.
>
> > 2. What happens if in the future the standard wants to add a new kind of
> *canonical* selection? For example, block-wise selection: pick N, skip M,
> pick N, skip M, etc. This can't be expressed by any of the current
> canonical slices (currently there's also no layout to express this idea,
> but presumably it would be added at the same time).
>
> P3663 makes it possible for the Standard to do this in the future.
> Please see Section 4.6, "WG21 may add a new slice category" (
>
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3663r3.html#wg21-may-add-a-new-slice-category
> ).
>
> The idea is that it's never a breaking change to go from "ill-formed"
> (status quo after adopting P3663) to "well-formed and well-defined"
> (after hypothetical addition of a new kind of selection).
>
> > 3. Is there a way to `static_assert` the mandate that something is a
> "submdspan slice type for IndexType"?
>
> If you're referring to [mdspan.sub.helpers] 6, in the specification of
> _`canonical-slice`_, then the way that you implement the Mandates is
> by means of the code in [mdspan.sub.helpers] 7. That code will be
> ill-formed otherwise.
>
> We do it that way because you can't write an expression (to use in a
> `static_assert` or the definition of a concept) to express that a
> structured binding declaration is well-formed.
>
> > 4. The notion of "unit-stride slice" is false for pairs and tuples, even
> though they intuitively have unit strides. By renaming the concept
> "canonical unit-stride slice", the name would match my intuition again.
>
> I debated that with Tomasz (CC'd) and lost ; - ) . If I remember
> right, he explained that the Standard never needs a non-canonical
> unit-stride slice, so there's no reason to define that idea. The
> Standard defines terms only because it uses them.
>
> > 5. There's a notion of "lower bound of the submdspan slice range" which
> is also used in contexts where the slice could be empty, e.g.
> `strided_slice(n, 0, 1)`. This represents the same empty interval
> regardless of the value of `n`, the question is what is the "lower bound"?
>
> [mdspan.sub.overview] 8.2 defines the lower bound for this case as the
> offset `n`. The upper bound is also `n` for this case.
>
> > Concretely, let `n == exts[i]`. Then, is `pair{n, n}` a valid slice for
> dimension `i`?
>
> Yes, it is. Acceptance of the Proposed Resolution of LWG Issue 4060 (
> https://cplusplus.github.io/LWG/lwg-defects.html#4060 ) at the St.
> Louis meeting last year fixed this.
>
> > It sounds like yes, because the condition:
> >
> > > the kth interval of e contains the submdspan slice range of s for the
> kth extent of e;
> >
> > is satisfied due to the interval being empty. By the same logic,
> `pair{n+1, n+1}` should also be valid, but `pair{cw<n+1>, cw<n+1>}` isn't,
> because it's not a slice type for the kth extent.
>
> That's a good point. `pair{cw<n+1>, cw<n+1>}` would have a
> canonicalization that is invalid per [mdspan.sub.overview] 9.1.1.
>
> We should file an LWG issue about this. Would you like to do it?
>
> > 6. I'd like to suggest adding "canonical" to "valid submdspan slice for
> the kth extent of e," because:
> >
> > - a "submdspan slice type for IndexType" is not required to be canonical,
> > - there's a couple of related concepts that explicitly mention the word
> canonical,
> > - it makes it harder to know when `SliceSpecifiers` refer to canonical
> slices, since that property isn't mentioned and only implied by "valid
> submdspan slice for the kth extent of e".
>
> I'm not quite sure what you mean. Would you like the phrase to be
> "valid canonical submdspan slice..."?
>
> The hierarchy works like this:
>
> 1. `submdspan` slice type for `IndexType`: lots of types, possibly out of
> bounds
> 2. canonical `submdspan` slice type for `IndexType`: result of calling
> _`canonical-slice`_ on (1), still possibly out of bounds
> 3. valid `submdspan` slice type for the $k^{th}$ extent of `E`: (2),
> plus anything known at compile time is known to be in bounds
> 4. valid `submdspan` slice for the $k^{th}$ extent of `E`: (3), plus
> fully in bounds
>
> Saying "valid canonical" would incorrectly imply that something can be
> valid but not canonical.
>
> Thanks for your work in implementing submdspan!
> mfh
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20251031/08c2bac1/attachment.htm>
More information about the Libstdc++
mailing list