* clang-format improvements
- Add a clang-format linter check to the PR pipeline
- Apply clang-format to files where the linter initially failed
- Remove `CommentPragmas` from `.clang-format`
- Remove all `// clang-format off` and `// NO-FORMAT` as they are not needed
- Remove a commented out `GSL_SUPPRESS`
* clang-format 20
* pipeline fail
* Update .github/workflows/clang-format.yml
Co-authored-by: Carson Radtke <nosrac925@gmail.com>
* output used clang-format version
* installed version is 18 which replaces "GSL_SUPPRESS(bounds.1)" with "GSL_SUPPRESS(bounds .1)"
* only include/gsl, not include
to prevent formatting of include/CMakeLists.txt
* apply clang-format[-20]
In a VS2026 developer command prompt I ran `clang-format -i include\gsl\* --assume-filename x.cpp`. This was necessary because VS GUI does not format files without an extension :(. Please note that `--assume-filename` is necessary here, otherwise the files will not be formatted. Surprisingly the behaviour for the formatter differs from the behaviour of `lang-format(-20) --dry-run --Werror include/gsl/*` where clang-format recognizes that the files is C++.
* change "#if 0" back to original version with comments only
* formatting scripts for windows and linux
for linux with linter (shfmt and shellcheck)
* add WhitespaceSensitiveMacros: [GSL_SUPPRESS]
* provide path for clang-format (Windows)
Currently not clear to me:
On my personal computer at home, when I start "Developer Command Prompt for VS18", I can run `clang-format` without providing the path.
On my managed (domain) company computer, when I start "Developer Command Prompt for VS18", I can NOT run `clang-format` without providing the path. I need to call `"%VCINSTALLDIR%Tools\Llvm\bin\clang-format"`.
I have no idea what the difference is. At least the version `"%VCINSTALLDIR%Tools\Llvm\bin\clang-format"` works on both computers, so I add the path.
---------
Co-authored-by: Werner Henze <w.henze@avm.de>
Co-authored-by: Carson Radtke <nosrac925@gmail.com>
Co-authored-by: Werner Henze <werner.henze+gitcommits@posteo.de>
As VS2026 wants a string literal in `[[gsl::suppress(...)]]` it is a difference, if you `GSL_SUPPRESS(a.1)` without space or `GSL_SUPPRESS(a .1)` with space. The version with the space does not work, so this commit removes the spaces.
Co-authored-by: Werner Henze <werner.henze+gitcommits@posteo.de>
This removes the "warning C26472: Don't use a static_cast for arithmetic conversions. Use brace initialization, gsl::narrow_cast or gsl::narrow (type.1)." issued by VS2026.
Co-authored-by: Werner Henze <w.henze@avm.de>
Without this change, the guideline
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c89-make-a-hash-noexcept
would be violated.
The test fails before the changes here:
```
tests/pointers_tests.cpp:102:23: error: static assertion failed due to requirement 'noexcept(std::hash<gsl::not_null<std::shared_ptr<int>>>{}(std::declval()))': gsl::not_null hash operator must be noexcept
102 | static_assert(noexcept(std::hash<Key>{}(std::declval<Key>())),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tests/pointers_tests.cpp:108:23: error: static assertion failed due to requirement 'noexcept(std::hash<gsl::strict_not_null<std::shared_ptr<int>>>{}(std::declval()))': gsl::strict_not_null hash operator must be noexcept
108 | static_assert(noexcept(std::hash<Key>{}(std::declval<Key>())),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
A new Visual Studio version will soon be available that deprecates the
old syntax for gsl::suppress. Customers will now get a C4875 diagnostic
on suppressions that look like `gsl::suppress(x)` urging them to use
`gsl::suppress("x")` instead.
This change updates the `GSL_SUPPRESS` macro to preprocess
GSL_SUPPRESS(x) to gsl::suppress("x") on clang and new versions of MSVC.
- A macro with the very generic name `BYTE_TYPE` is likely to collide with existing code, so get rid of the macro.
- The new solution is to provide a non-deprecated `byte` in the namespace `gsl::impl`.
- Users of GSL should use `gsl::byte`, which is still deprecated when mapped to a `std::std::byte`.
- GSL types and functions need to use `gsl::impl::byte` so they do not trigger the deprecation warning.
- The `gsl::impl::byte` return type in an exported function is not nice, it might mislead users to use that type in their own declarations. But the `BYTE_TYPE` solution is not better in this respect.
Co-authored-by: Werner Henze <w.henze@avm.de>
* deprecated features adopted into C++
1) Mark the following GSL features as deprecated:
- gsl::unique_ptr (always)
- gsl::shared_ptr (always)
- gsl::byte (since c++17)
- gsl::joining_thread (never implemented)
2) Refactor existing deprecations to use the new GSL_DEPRECATED(msg) macro.
3) Create a section in the README for deprecated features in the
standard.
* do not deprecate gsl::to_integer because we never claim to implement it.
* do not use gsl::byte if it is deprecated
Reverts commit that changes #include "assert" -> #include "gsl/assert".
This change is necessary in order to comply with CppCoreGuideline's
SF.12. Now we do #include "./assert".
Office is seeing build breaks due to `#include "span"` including
C++20 span instead of gsl/span. Most likely we want all headers
includes qualified with "gsl/" to avoid similar issues.
- `strict_not_null<std::unique_ptr<int>>{ std::make_unique<int>()}` failed to compile
- `strict_not_null` ctor needs to move the passed `unique_ptr`, not copy
- Copied `not_null` `TestNotNullConstructors` for `strict_not_null`
- The `noexcept` specifiers on the `strict_not_null` and `not_null` constructors were out of sync.
- Added unit test for `not_null<unique_ptr<T>>` and for `strict_not_null<unique_ptr<T>>`
- Added unit test for `gsl::swap` for two `strict_not_null`
- Added unit test for `gsl::swap` for `not_null` and `strict_not_null`
Co-authored-by: Werner Henze <w.henze@avm.de>
`std::enable_if_t` must not be used as a default template argument, otherwise the instantiator will be able to override it freely with something that doesn't fail substitution. Instead, `std::enable_if_t` itself must be the type of the template argument.
More information in the examples here: https://en.cppreference.com/w/cpp/types/enable_if
* improve performance of span_iterator w/ clang
Issue: #1165
Before this PR, the range-for loop was ~3300x slower. After this PR, it
is ~1.005x slower
The clang optimizer is very good at optimizing `current != end`, so
we changed to this idiom. This moves the Expects assertion into the
constructor instead of on the hot-path which is called whenever either
operator++ or operator* is called.
Note: The codegen for the assertion is still a missed optimization,
but less worrisome as it only happens once per iterator.
Note: benchmarks on M1 Macbook Pro w/ Apple Clang 16.0.0
* Remove unused headers from gsl/pointers
forward is already declared in utility, no need to include algorithm which is relativaly heavy
hash is already declared in memory, no need to bring brand-new header system_error for hash only
* Fix: add missing header <functional> to gsl/pointers due to using less/greater
Two warnings were being emitted in the MSVC+LLVM tests.
The warning `-Wunsafe-buffer-usage` is initially introduced in some capacity here https://reviews.llvm.org/D137346 pointing to documentation at https://discourse.llvm.org/t/rfc-c-buffer-hardening/65734. The warning is a stylistic checker whose goal is to "emit a warning every time an unsafe operation is performed on a raw pointer". This type of programming model is not useful for library implementations of types such as `span`, where direct manipulation of raw pointers is inevitable, so disable the warning altogether.
There is also a false-positive warning https://github.com/llvm/llvm-project/issues/65689 that I've disabled inline.
Without this change a `gsl::not_null<class_type>` triggers these `noexcept` warnings:
```
.../gsl/include/gsl/pointers:162:50: warning: noexcept-expression evaluates to ‘false’ because of a call to ‘constexpr gsl::details::value_or_reference_return_t<T> gsl::not_null<T>::get() const [with T = class_type*; gsl::details::value_or_reference_return_t<T> = class_type* const]’ [-Wnoexcept]
162 | const not_null<U>& rhs) noexcept(noexcept(lhs.get() == rhs.get()))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../gsl/include/gsl/pointers:119:55: note: but ‘constexpr gsl::details::value_or_reference_return_t<T> gsl::not_null<T>::get() const [with T = class_type*; gsl::details::value_or_reference_return_t<T> = class_type* const]’ does not throw; perhaps it should be declared ‘noexcept’
119 | constexpr details::value_or_reference_return_t<T> get() const
| ^~~
```
Co-authored-by: Werner Henze <w.henze@avm.de>
Headers that were previously prefixed with `gsl_` were renamed to drop the `gsl_` prefix in https://github.com/microsoft/GSL/pull/946, and the original version deprecated.
The deprecation happened a long time ago, so it is now time to remove these headers entirely.
Using `<`,`<=`,`>`,`>=` to compare unrelated pointers gives an unspecified result according to the standard.
This PR replaces the usage of these operators in `gsl::not_null` with the STL counterparts, which would leverage any implementation-defined strict total ordering for pointers.
Resolves#880
`size_bytes()` returns the span's size in bytes.
Assuming the span was constructed with an accurate size parameter, the check `size() < dynamic_extent / sizeof(element_type)` isn't required, since `size_t(-1)` (which is `dynamic_extent`) represents the size of the address space, so the number of bytes will never exceed it and in practice won't even come close.
Otherwise, it is not actually feasible to detect cases when the size parameter does not correspond to the dimensions of the underlying data pointer. In these cases, the relationship `size() < dynamic_extent / sizeof(element_type)` is simply one of many ways in which the `size()` could be incorrect, and serves no necessary purpose.
Resolves#1012
https://github.com/microsoft/GSL/issues/1075
- Add `static_assert` because we only support C style array `at` for up to half of the address space.
- Add `std::` before `size_t`.
- tests:
- Add `#include <exception>`
- Implement `span_tests` `interop_with_gsl_at` like `at_tests` `std_span`