Adopt LWG 4397: reject fixed-extent span from a constant-sized range that doesn't fit#22
Open
ssam18 wants to merge 1 commit into
Open
Adopt LWG 4397: reject fixed-extent span from a constant-sized range that doesn't fit#22ssam18 wants to merge 1 commit into
ssam18 wants to merge 1 commit into
Conversation
…that doesn't fit LWG 4397 adds a Mandate to the range constructor: when the extent is fixed and ranges::size(r) is a constant expression, it has to equal the extent, otherwise the program is ill-formed. This catches things like span<int, 42>(views::empty<int>) at compile time instead of only tripping the runtime precondition. Ranges whose size isn't a constant expression (std::vector and friends) are unaffected and still checked at run time. The compile-time check only kicks in on compilers that implement P2280R4, since the size has to be usable as a constant expression through the constructor parameter. Where that isn't available (e.g. GCC 13) the check quietly falls back to the existing runtime assert with no false rejections. Because of that, the negative-compile test is guarded: at configure time we probe whether the compiler actually rejects the mismatch, and only then wire up a WILL_FAIL ctest around it. On compilers that don't, the test is skipped. Fixes the issue #18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements LWG 4397 (Improve
span(R&& r)), which GCC has already shipped and LWG moved to Ready in Brno. Closes #18.What
The range constructor gains the new Mandate: when the extent is fixed and
ranges::size(r)is a constant expression, it must equal the extent. Otherwise, the program is ill-formed. This rejects e.g.span<int, 42>(views::empty<int>)at compile time instead of only tripping the runtime precondition. Ranges whose size isn't a constant expression (std::vectorand friends) are unaffected and still checked at run time via the existing assert (the hardened precondition).How
The check sits in the
Extent != dynamic_extentbranch of the constructor, guarded by arequiresprobe that only fires thestatic_assertwhenranges::size(r)is usable as a constant expression:Realizing the Mandate requires P2280R4, the size has to be usable as a constant expression through the constructor parameter. On compilers without it (e.g. GCC 13) the
requiresis simply never satisfied and the check degrades to the runtime assert, with no false rejections (fixed-extent construction from astd::vectorstill compiles).Tests
views::empty<int>, and fixed-extent-from-vectorstaying valid.try_compiles a matching probe (must compile) and a mismatching probe (must not); only when the compiler actually rejects the mismatch is aWILL_FAILctest wired up around it. On compilers that don't reject it, the test is skipped with a status message.Verified locally on GCC 13.3 (test correctly skipped, full suite green) and by simulating the reject path (test enabled and passing).