Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e590a2d
Initial plan
Copilot Feb 3, 2026
8696c2c
Change generator from Unix Makefiles to Ninja for gcc and clang presets
Copilot Feb 3, 2026
06dd56d
Use Ninja generator for msvc-base preset for consistency
Copilot Feb 4, 2026
55f4956
Fix ClangCL builds by conditionally using Visual Studio generator
Copilot Feb 6, 2026
bff804a
Improve workflow readability with matrix include for generator config…
Copilot Feb 6, 2026
ffdd653
Clean up unused matrix include fields
Copilot Feb 6, 2026
69a3a21
feat: implementation of gsl::dyn_array
carsonRadtke Jan 27, 2026
9f20a8c
address a number of PR comments
carsonRadtke Feb 6, 2026
9331f28
update generator for vs18 development
carsonRadtke May 18, 2026
135f3c2
fold dyn_array_impl into dyn_array_base
carsonRadtke May 19, 2026
3505f5b
remove dyn_array_traits and inline types
carsonRadtke May 19, 2026
b9ecae9
use allocator traits instead of digging into base allocator directly
carsonRadtke May 19, 2026
aad451d
no more UB in fill and copy-fill constructors
carsonRadtke May 19, 2026
e839865
copilot found some bugs. added tests for them and fixed them.
carsonRadtke May 20, 2026
c71e799
fix cpp14 build and test failures (msvc)
carsonRadtke May 20, 2026
2a4f6db
is_same_v -> is_same + comments for static_assertion
carsonRadtke May 20, 2026
36195f1
clang-cl support w/ ninja
carsonRadtke May 20, 2026
ddbc567
stole the clang-cl solution from pr1230
carsonRadtke May 20, 2026
4ced9d6
make sure we have a dev shell before running cmake
carsonRadtke May 20, 2026
4e695e7
add tests and patch more issues found by gpt-5.5
carsonRadtke May 20, 2026
cb86729
make sure helper functions are properly marked constexpr
carsonRadtke May 20, 2026
f76cfab
fix some typos
carsonRadtke May 20, 2026
63acb93
resolve remaining todos
carsonRadtke May 20, 2026
40d3ec1
remove GSL_HAS_* macros
carsonRadtke May 20, 2026
f3c853c
misc fixes from self-review
carsonRadtke May 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions .github/workflows/compilers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,30 @@ jobs:
cmake_preset: clang-${{ matrix.cxx_version }}-${{ matrix.build_type == 'Debug' && 'debug' || 'release' }}
extra_cmake_configure_args: '-DCMAKE_CXX_FLAGS="-isysroot \"$(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk\""'

VisualStudio:
msvc:
strategy:
matrix:
generator: [ 'Visual Studio 17 2022' ]
image: [ windows-2022, windows-2025 ]
build_type: [ Debug, Release ]
extra_args: [ '', '-T ClangCL' ]
toolset: [ 'msvc', 'ClangCL' ]
cxx_version: [ 14, 17, 20, 23 ]
include:
# Regular MSVC builds use Ninja (from preset)
- toolset: 'msvc'
generator_override: ''
# ClangCL builds require Visual Studio generator
- toolset: 'ClangCL'
generator_override: '-G "Visual Studio 17 2022" -T ClangCL'
runs-on: ${{ matrix.image }}
steps:
- uses: actions/checkout@v6
- uses: microsoft/setup-msbuild@v3
- uses: ilammy/msvc-dev-cmd@v1

- name: Run CMake (configure, build, test)
uses: ./.github/workflows/cmake
with:
cmake_preset: msvc-${{ matrix.cxx_version }}-${{ matrix.build_type == 'Debug' && 'debug' || 'release' }}
extra_cmake_configure_args: ${{ matrix.extra_args }}
extra_cmake_build_args: --config ${{ matrix.build_type }}
extra_ctest_args: -C ${{ matrix.build_type }}
extra_cmake_configure_args: ${{ matrix.generator_override }}
extra_cmake_build_args: ${{ matrix.toolset == 'ClangCL' && format('--config {0}', matrix.build_type) || '' }}
extra_ctest_args: ${{ matrix.toolset == 'ClangCL' && format('-C {0}', matrix.build_type) || '' }}
6 changes: 1 addition & 5 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"hidden": true,
"binaryDir": "${sourceDir}/build/${presetName}",
"installDir": "${sourceDir}/install/${presetName}",
"generator": "Ninja",
Comment thread
carsonRadtke marked this conversation as resolved.
"cacheVariables": {
"GSL_CXX_STANDARD": "14",
"GSL_TEST": "ON"
Expand All @@ -15,14 +16,11 @@
"name": "msvc-base",
"inherits": "base",
"hidden": true,
"generator": "Visual Studio 17 2022",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolset": "host=x64",
"architecture": "x64",
"cacheVariables": {
"CMAKE_CXX_COMPILER": "cl"
}
Expand All @@ -31,7 +29,6 @@
"name": "gcc-base",
"inherits": "base",
"hidden": true,
"generator": "Unix Makefiles",
"cacheVariables": {
"CMAKE_CXX_COMPILER": "g++",
"CMAKE_C_COMPILER": "gcc"
Expand All @@ -41,7 +38,6 @@
"name": "clang-base",
"inherits": "base",
"hidden": true,
"generator": "Unix Makefiles",
"cacheVariables": {
"CMAKE_CXX_COMPILER": "clang++",
"CMAKE_C_COMPILER": "clang"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ span_p | &#x26
[cu32zstring](docs/headers.md#user-content-H-zstring) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of `const char32_t`
[**2. Owners**][cg-owners] | |
stack_array | ☐ | A stack-allocated array
dyn_array | ☐ | A heap-allocated array
dyn_array | ☑ | A heap-allocated array
[**3. Assertions**][cg-assertions] | |
[Expects](docs/headers.md#user-content-H-assert-expects) | ☑ | A precondition assertion; on failure it terminates
[Ensures](docs/headers.md#user-content-H-assert-ensures) | ☑ | A postcondition assertion; on failure it terminates
Expand Down
173 changes: 173 additions & 0 deletions docs/headers.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ See [GSL: Guidelines support library](https://isocpp.github.io/CppCoreGuidelines
- [`<algorithms>`](#user-content-H-algorithms)
- [`<assert>`](#user-content-H-assert)
- [`<byte>`](#user-content-H-byte)
- [`<dyn_array>`](#user-content-H-dyn_array)
- [`<gsl>`](#user-content-H-gsl)
- [`<narrow>`](#user-content-H-narrow)
- [`<pointers>`](#user-content-H-pointers)
Expand Down Expand Up @@ -155,6 +156,178 @@ constexpr byte to_byte() noexcept;

Convert the given value `I` to a `byte`. The template requires `I` to be in the valid range 0..255 for a `gsl::byte`.

## <a name="H-dyn_array" />`<dyn_array>`

This header contains an owning dynamically allocated array type whose size is fixed between assignments.

- [`gsl::dyn_array`](#user-content-H-dyn_array-dyn_array)

### <a name="H-dyn_array-dyn_array" />`gsl::dyn_array`

```cpp
template <typename T, typename Allocator = std::allocator<T>>
class dyn_array;
```

`gsl::dyn_array` owns a contiguous sequence of `T` objects allocated with `Allocator`.
The number of elements is established when the object is constructed and remains unchanged until the object is copy-assigned.
It provides bounds-checked element access and checked random-access iterators.

`gsl::dyn_array` is useful when the number of elements is known only at runtime, but the array should not grow or shrink through container operations.

#### Member Types

```cpp
using value_type = T;
using reference = T&;
using const_reference = const T&;
using iterator = details::dyn_array_iterator<T>;
using const_iterator = details::dyn_array_iterator<const T>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using difference_type = std::ptrdiff_t;
using size_type = std::size_t;

using allocator_type = Allocator;
```

#### Member functions

##### Construct/Copy

```cpp
explicit constexpr dyn_array(const Allocator& alloc = {});
```

Constructs an empty `dyn_array`.
No elements are allocated and `data()` returns `nullptr`.

```cpp
constexpr explicit dyn_array(size_type count, const Allocator& alloc = {});

constexpr dyn_array(size_type count, const T& value, const Allocator& alloc = {});
```

Constructs a `dyn_array` with `count` elements using `alloc`.
The first overload default-constructs each element.
The second overload constructs each element as a copy of `value`.

```cpp
template <typename InputIt>
constexpr dyn_array(InputIt first, InputIt last, const Allocator& alloc = {});
```

Constructs a `dyn_array` by copying the elements in the range `[first, last)`.

```cpp
template <std::ranges::input_range InputRg>
constexpr dyn_array(std::from_range_t, InputRg&& rg, const Allocator& alloc = {});
```

Constructs a `dyn_array` by copying the elements in `rg`.
This overload is available when container ranges are supported.

```cpp
constexpr dyn_array(const dyn_array& other, const Allocator& alloc = {});

constexpr dyn_array(std::initializer_list<T> init, const Allocator& alloc = {});
```

Constructs a `dyn_array` by copying the elements from another `dyn_array` or from an initializer list.

```cpp
constexpr auto operator=(const dyn_array& other) -> dyn_array&;

constexpr dyn_array(dyn_array&&) = delete;
dyn_array& operator=(dyn_array&&) = delete;
```

Copy assignment replaces the contents with copies of the elements in `other`.
Move construction and move assignment are explicitly deleted.

##### Observers

```cpp
constexpr auto size() const;
constexpr auto empty() const;
constexpr auto max_size() const;
constexpr auto get_allocator() -> Allocator&;
```

Returns the number of elements, whether the array is empty, the maximum representable size, or the allocator used by the `dyn_array`.

##### Element access

```cpp
constexpr auto operator[](size_type pos) -> reference;
constexpr auto operator[](size_type pos) const -> const_reference;
```

Returns a reference to the element at the given index.
[`Expects`](#user-content-H-assert-expects) that `pos` is less than the `dyn_array`'s size.

```cpp
constexpr auto data();
constexpr auto data() const -> const T*;
```

Returns a pointer to the beginning of the contained data.
If the `dyn_array` is empty, this returns `nullptr`.

##### Iterators

```cpp
constexpr auto begin();
constexpr auto begin() const;
constexpr auto cbegin() const;

constexpr auto end();
constexpr auto end() const;
constexpr auto cend() const;
```

Returns an iterator to the first element or to one past the last element.

```cpp
constexpr auto rbegin();
constexpr auto rbegin() const;
constexpr auto crbegin() const;

constexpr auto rend();
constexpr auto rend() const;
constexpr auto crend() const;
```

Returns a reverse iterator to the first element of the reversed range or to one past the last element of the reversed range.

The iterators are random-access iterators and perform bounds checking.
Dereferencing `end()`, moving before `begin()` or past `end()`, or comparing iterators from different arrays violates preconditions.

##### Comparisons

```cpp
constexpr auto operator==(const dyn_array& other) const;
constexpr auto operator!=(const dyn_array& other) const;
```

Compares two `dyn_array`s by size and element value.

#### Deduction guides

```cpp
template <class InputIt,
class Alloc = std::allocator<typename std::iterator_traits<InputIt>::value_type>>
dyn_array(InputIt, InputIt,
Alloc = {}) -> dyn_array<typename std::iterator_traits<InputIt>::value_type, Alloc>;

template <std::ranges::input_range InputRg,
class Alloc = std::allocator<std::ranges::range_value_t<InputRg>>>
dyn_array(std::from_range_t, InputRg&&,
Alloc = {}) -> dyn_array<std::ranges::range_value_t<InputRg>, Alloc>;
```

The range deduction guide is available when container ranges are supported.

Comment thread
carsonRadtke marked this conversation as resolved.
## <a name="H-gsl" />`<gsl>`

This header is a convenience header that includes all other [GSL headers](#user-content-H).
Expand Down
Loading
Loading