basic_zstring_view: add opt-in nonnull variants - #668
Draft
Monroe Thomas (mmthomas) wants to merge 4 commits into
Draft
basic_zstring_view: add opt-in nonnull variants#668Monroe Thomas (mmthomas) wants to merge 4 commits into
Monroe Thomas (mmthomas) wants to merge 4 commits into
Conversation
added 4 commits
August 19, 2026 13:45
Add a traits policy that preserves the underlying char_traits type while enforcing non-null construction. Provide narrow and wide aliases, checked cross-variant conversion, and focused invariant, reference-conversion, custom-traits, formatting, and fail-fast tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5697cd0e-cf83-4d94-9f72-4b8c79379229
Detect a null pointer when c_str() is called after mutation through the public string_view base, and cover the inheritance escape hatch with a regression test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5697cd0e-cf83-4d94-9f72-4b8c79379229
Route nonnull pointer checks through FAIL_FAST_IF_NULL so diagnostics retain the checked expression and static analysis receives the pointer-specific contract. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5697cd0e-cf83-4d94-9f72-4b8c79379229
Gate cross-policy conversions on the exact string_view base type, reject incompatible specializations, and limit rebinding to explicitly marked policy traits. Use a debug assertion rather than a partial production fail-fast for base-class mutation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5697cd0e-cf83-4d94-9f72-4b8c79379229
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.
Summary
wil::zstring_viewis a non-owning view of a null-terminated string. Its default constructor followsstd::string_view: the view is empty anddata()is null. That behavior must remain unchanged because existing callers may use null to mean "no string."Some callers instead need an empty view that can be passed directly to a C API without first checking for null. This PR adds opt-in
nonnull_zstring_viewandnonnull_zwstring_viewaliases for that use case. Their constructors reject null pointers, and their default constructors point at an internal empty string.The existing
zstring_viewandzwstring_viewaliases retain their current behavior.C++ standardization
WG21 is standardizing the same general abstraction for C++29 as
std::basic_cstring_viewin P3655R5,std::cstring_view. The proposed type is a non-owning view of a null-terminated string. Its default constructor refers to a static null terminator, sodata()andc_str()return a valid empty string rather than null, and directnullptrconstruction is deleted.P3655 is an active proposal rather than part of the published C++ standard. WIL retains its existing
zstring_viewnaming and public-inheritance design; this PR adds an opt-in construction policy that provides the proposal's non-null empty-state behavior without changing existing callers.Public API
The policy type keeps the non-null behavior separate from the character traits used by
std::basic_string_view. As a result,nonnull_zstring_viewandzstring_viewboth derive fromstd::string_view, rather than deriving from differentstd::basic_string_viewspecializations.This matters for normal C++ interoperability:
wil::nonnull_zstring_view value{"hello"}; std::string_view& base = value; // binds to the inherited base objectCustom character traits remain supported through
nonnull_zstring_view_traits<TChar, Traits>.Construction and conversion behavior
nullptrconstruction is deleted.std::basic_string, compatible string-like objects, and valid pointer inputs behave like the existing type.substr(pos)preserves the selected policy. A substring of a default-constructed non-null view therefore remains non-null.Inheritance limitation
basic_zstring_viewpublicly inherits fromstd::basic_string_view. This permits a caller to explicitly obtain a mutable base reference and assign a nullable base view:wil::nonnull_zstring_view value{"hello"}; std::string_view& base = value; base = std::string_view{}; // bypasses the non-null construction policyThe new type enforces non-null construction through its own API. In debug builds, the derived
c_str()asserts if base-class mutation has changed the stored pointer to null. Calls made directly through the base class still bypass that check. Removing the escape hatch entirely would require replacing the existing inheritance design rather than extending it.Compatibility
Existing code can continue to use
wil::zstring_viewandwil::zwstring_viewwith the same source syntax and nullable default behavior. Adding the defaultedTraitsparameter changes the compiler-generated linker name for functions that exposebasic_zstring_viewin a binary interface. Default construction also now runs the policy-selection constructor instead of being a trivial operation. Object layout, size, and trivial copyability remain unchanged.Tests
The focused tests cover both
charandwchar_tvariants:std::basic_string_viewbase-reference compatibility;substr(pos);Local validation:
witest.exe "[zstring_view]": 155 assertions passed.witest.cpplatest.exe "[zstring_view]": 159 assertions passed.Scope
This PR does not add new string literals, change SAL annotations, alter the existing nullable aliases, or redesign
basic_zstring_viewto remove public inheritance.The API direction originated in the compatibility and traits discussion on #635; this description is intended to stand on its own.