Repository navigation
Complete VLA range and initializer-list assignment - #238
Merged
Merged
Conversation
thirtytwobits
marked this pull request as ready for review
October 17, 2026 14:55
- Skip deallocate(nullptr, 0) for arrays that never allocated. - Keep caller-requested element conversions from raising -Wconversion in the header; use std::copy_n for random-access prefixes. - Enforce max_size() in ensure_size_plus_one() and resize() so spare capacity adopted by assignment cannot exceed the bound; drop the input path's special case and always trim the unused suffix. - Guard loop increments against overloaded comma operators. - Clamp VLA<bool>::resize() to existing storage when growth is declined without exceptions (heap overflow). - Make assign(count, value) release insufficient storage before allocating, like the range overloads. - Constrain the range constructors to input iterators and implement them with assign(first, last). - Pack bits per byte in the VLA<bool> forward path; destroy suffixes with fast_destroy. - Correct the assign documentation on failure detection and modes. - Strengthen length_error and single-pass failure tests, add regression tests, and extend the fuzz harness to the new assign overloads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
thirtytwobits
requested review from
MAMONTBOT
and
a balanced review from Copilot
October 17, 2026 16:52
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Range construction now rejects previously supported copy-constructible, nonassignable element types.
1 open issue
What changed in this PR
Completes VLA assignment overloads requested in #55 for ordinary elements and packed bool.
Changes:
- Adds iterator-range and initializer-list assignment.
- Updates storage replacement, size limits, and failure handling.
- Adds assignment tests, exception-safety checks, and fuzz coverage.
| File | Description |
|---|---|
| include/cetl/variable_length_array.hpp | Implements assignment overloads and updates range construction. |
| cetlvast/suites/unittest/test_variable_length_array_exception_safety.cpp | Tests assignment failures and lifetime preservation. |
| cetlvast/suites/unittest/test_variable_length_array_assign.cpp | Adds assignment and iterator regression tests. |
| cetlvast/suites/unittest/CMakeLists.txt | Registers the assignment test suite. |
| cetlvast/suites/fuzz/fuzz_variable_length_array.cpp | Exercises assignment variants against vector models. |
Review effort: Balanced
MAMONTBOT
previously approved these changes
Oct 17, 2026
MAMONTBOT
left a comment
There was a problem hiding this comment.
Reviewed the changes; no blocking issues found.
Range construction delegated to assign(first, last), whose forward path instantiates element assignment even when nothing overlaps. Copy- constructible types with deleted assignment, which main and std::vector accept, stopped compiling. Give the constructors a construction-only path (emplace_back for single-pass ranges; one allocation plus element construction for forward ranges) that keeps the new iterator support, max_size handling, and failure cleanup, and add a regression test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MAMONTBOT
approved these changes
Oct 17, 2026
MAMONTBOT
left a comment
There was a problem hiding this comment.
Reviewed the changes; no blocking issues found.
thirtytwobits
added a commit
that referenced
this pull request
Oct 17, 2026
…239) Makes the full CETLVaSt suite build and pass with GCC 7 (7.5.0), and adds GCC 7 to CI. The Arduino ecosystem is still on GCC 7, so this is a step toward embedded/Arduino support. Refs #149, refs #136. ## Changes **Library** - `type_traits_ext.hpp` (#136): `is_convertible_without_narrowing` is now spelled as copy-list-initialization of a by-value function parameter. GCC 7 rejects the old `std::array<To, 1>{{{from}}}` for scalar `To`. GCC 7 doesn't diagnose narrowing in constructor arguments during list-initialization of a class type, so for that case it now behaves like `std::variant`. The trait docs and `test_type_traits_ext.cpp` describe this. This commit (0ad3b87) is the fix that was sitting uncommitted on the `issue/136` working tree. If #136 lands separately, drop it. - `pf20/span.hpp`: the `CDE_span_002` debug assert now casts the iterator distance to `size_type` explicitly before comparing it with `Extent`. The comparison already did this conversion implicitly, so behaviour is the same on every compiler. GCC 7 flags the implicit version with `-Wsign-conversion` (Debug builds only). **Tests only** - `test_variable_length_array_exception_safety.cpp`: GCC 7 deduces `const auto list = {Value{...}, ...}` as `std::initializer_list<const Value>` (GCC PR c++/63149, fixed in GCC 8), so no constructor matched. `VariableLengthArray` itself is correct. The fix is to spell out `std::initializer_list<Value>`, both in the constructor test and in the initializer-list assignment test that #238 added. - `pmr/test_pmr_function.cpp`: clear functions with `= nullptr` instead of `= {}`. Both resolve to `operator=(std::nullptr_t)`, but GCC 7 reports the `{}` form under `-Wzero-as-null-pointer-constant`. **CI** - `.github/workflows/cetlvast.yml`: adds a `gcc7-native` / `cpp-14` entry to the arm64 verification matrix through `include:`, so GCC 7 isn't combined with cpp-17/20. It uploads the same artifacts as the other entries. The `gcc7-native` presets only exist for cpp-14. ## Verification Rebased onto main after #238 and re-verified: - `cmake --workflow --preset workflow-gcc7-native-cpp-14-offline` passes end to end in `ghcr.io/opencyphal/toolshed:ts24.4.3` (aarch64) from a clean build dir. All 5 steps pass, including `run_unittests` and `run_examples` in Release, ReleaseEP, Debug and DebugEP: 216 passing suite runs. - Host `workflow-gcc-native-cpp-14-offline` (Homebrew GCC 13.4, macOS) passes end to end, also 216 passing suite runs. Clang and the other standards are left to CI. - Changed lines pass the toolshed's clang-format (`clang-format-diff` with clang-format 19.1.7). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
thirtytwobits
added a commit
that referenced
this pull request
Oct 18, 2026
Adds `operator=(std::initializer_list)` to `cetl::VariableLengthArray`, matching [`std::vector::operator=` (3)](https://en.cppreference.com/w/cpp/container/vector/operator%3D). Both the general and the packed-`bool` specializations forward to `assign(std::initializer_list)` (from #238), so the operator has the same guarantees as that overload: - the allocator and `max_size()` are kept, and existing storage is reused when it is large enough - a list longer than `max_size()` throws `std::length_error`; with exceptions disabled the list is truncated to `max_size()` - allocation failure throws `std::bad_alloc` - returns `*this` `vla = {}` now resolves to the new overload and clears the array, the same as `std::vector`. ## Tests New cases in `test_variable_length_array_assign.cpp`, typed over `int` and `bool`: - growing, shrinking, clearing, and re-growing across packed-byte boundaries, checked against `std::vector` - the returned reference - the logical maximum, with and without exceptions - reusing storage without allocating, and keeping the allocator and `max_size()` ## Validation - GCC 13, C++14: all 11 VLA test suites pass in Debug and DebugEP (`-fno-exceptions`) - Clang, C++14 and C++20, with and without exceptions: the assign suite compiles cleanly with `-Wall -Wextra -Werror -Wconversion -Wsign-conversion` - `clang-format` 19.1.7 from `toolshed:ts24.4.3` (the CI image) reports no changes for either file; `git diff --check` is clean Closes #70. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

VLA only provided
assign(count, value). Addassign(first, last)andassign(std::initializer_list<T>)for both ordinary elements and packedbool, completing the overloads requested in #55.Single-pass input ranges reuse existing elements and grow incrementally. Forward ranges are measured first and obtain replacement storage in one allocation, without requiring old elements to be movable. Both paths preserve the allocator and maximum size, support proxy and move iterators, and maintain valid object lifetimes after failure. The API documentation describes partial updates, size limits, and allocation failure with exceptions disabled.
Validation:
git diff --checkpassed.Regression coverage includes single-pass and forward iterators, initializer lists, integral overload resolution, empty ranges, packed-bit boundaries, move-only and immovable elements, allocation failure, and throwing iterator/element/allocator operations.
Closes #55.