https://github.com/gsl-lite/gsl-lite
ISO C++ Core Guidelines Library implementation for C++98, C++11 up
https://github.com/gsl-lite/gsl-lite
cpp11 cpp14 cpp17 cpp98 gsl gsl-implementations header-only no-dependencies single-file
Last synced: 12 days ago
JSON representation
ISO C++ Core Guidelines Library implementation for C++98, C++11 up
- Host: GitHub
- URL: https://github.com/gsl-lite/gsl-lite
- Owner: gsl-lite
- License: mit
- Created: 2015-09-24T16:34:57.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2025-05-13T23:11:17.000Z (11 months ago)
- Last Synced: 2025-05-14T18:02:36.925Z (11 months ago)
- Topics: cpp11, cpp14, cpp17, cpp98, gsl, gsl-implementations, header-only, no-dependencies, single-file
- Language: C++
- Homepage:
- Size: 1.58 MB
- Stars: 927
- Watchers: 45
- Forks: 108
- Open Issues: 18
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGES.txt
- License: LICENSE
Awesome Lists containing this project
- awesome-hpp - gsl-lite - lite/gsl-lite?style=social)](https://github.com/gsl-lite/gsl-lite/stargazers/) | ISO C++ Guidelines Support Library (GSL). | [](https://opensource.org/licenses/MIT) | (Standard/Support Libraries)
README
# *gsl-lite*
| metadata | build | packages | try online |
| -------- | ------ | -------- | ---------- |
| [](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
[](https://opensource.org/license/MIT)
[](https://github.com/gsl-lite/gsl-lite/releases) | [](https://dev.azure.com/gsl-lite/gsl-lite/_build/latest?definitionId=1&branchName=master)
[](https://ci.appveyor.com/project/gsl-lite/gsl-lite) | [](https://vcpkg.io/en/package/gsl-lite)
[](https://conan.io/center/recipes/gsl-lite)
[](https://raw.githubusercontent.com/gsl-lite/gsl-lite/master/include/gsl-lite/gsl-lite.hpp) | [](https://gcc.godbolt.org/z/8jqq6P1G5)
[](https://wandbox.org/permlink/JADF95qldnpt0i0v) |
***gsl-lite*** is a portable, single-file, header-only library for defensive programming based on the [C++ Core Guidelines Support Library](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#S-gsl) specification.
## Contents
- [Example usage](#example-usage)
- [In a nutshell](#in-a-nutshell)
- [License](#license)
- [Dependencies](#dependencies)
- [Installation and use](#installation-and-use)
- [Why *gsl-lite*?](#why-gsl-lite)
- [Features](#features)
- [Reference documentation](doc/Reference.md)
- [Migration guide](#migration-guide)
- [Using *gsl-lite* in libraries](#using-gsl-lite-in-libraries)
- [Reported to work with](#reported-to-work-with)
- [Version semantics](#version-semantics)
- [Contributing](#contributing)
## Example usage
```c++
#include
#include
#include
#include
namespace my_lib {
// Define this in your own namespace.
namespace gsl = ::gsl_lite;
// `span`: contiguous range with bounds checks
double mean( gsl::span values )
{
// `gsl_Expects( cond )`: precondition check
gsl_Expects( !values.empty() );
double sum = std::accumulate( values.begin(), values.end(), 0. );
// `narrow_failfast( u )`: checked numeric cast
double num = gsl::narrow_failfast( std::ssize( values ) );
return sum / num;
}
class Resource
{
...
public:
Resource( std::size_t size );
};
// Type-encoded precondition with `not_null
`
void consumeResource( gsl::not_null> resource );
// Type-encoded postcondition with `not_null
`
gsl::not_null> acquireResource( std::size_t size )
{
// A flavor of `make_unique()` which returns `not_null>`
return gsl::make_unique( size );
}
} // namespace my_lib
```
## In a nutshell
*gsl-lite* strives to implement the [Guidelines Support Library specification](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#S-gsl) of the C++ Core Guidelines
maintained by the [Standard C++ Foundation](https://isocpp.org/).
The library is originally based on [Microsoft GSL](https://github.com/microsoft/gsl) and was adapted for C++98, C++03. It also works when compiled as C++11, C++14, C++17, C++20, or C++23.
*gsl-lite* does not interfere with Microsoft GSL since both libraries live in different namespaces (`gsl_lite` vs. `gsl`).
*gsl-lite* recognizes when it is compiled for the CUDA platform and decorates some functions with `__host__` and `__device__` accordingly.
## License
*gsl-lite* uses the [MIT](LICENSE) license.
## Dependencies
*gsl-lite* has no dependencies other than the [C++ standard library](http://en.cppreference.com/w/cpp/header).
## Installation and use
The recommended way to consume *gsl-lite* in your CMake project is to use `find_package()` to locate the package `gsl-lite`
and `target_link_libraries()` to link to the imported target `gsl-lite::gsl-lite`:
```cmake
cmake_minimum_required( VERSION 3.20 FATAL_ERROR )
project( my-program LANGUAGES CXX )
find_package( gsl-lite 1.1 REQUIRED )
add_executable( my-program main.cpp )
target_compile_features( my-program PRIVATE cxx_std_17 )
target_link_libraries( my-program PRIVATE gsl-lite::gsl-lite )
```
*gsl-lite* is available via [Vcpkg](https://vcpkg.io/en/package/gsl-lite), [Conan](https://conan.io/center/recipes/gsl-lite),
and possibly other package managers. It may also be obtained with [CPM](https://github.com/cpm-cmake/CPM.cmake):
```cmake
CPMFindPackage( NAME gsl-lite VERSION 1.1.0 GITHUB_REPOSITORY gsl-lite/gsl-lite )
```
See the directories [example/with-CPM](https://github.com/gsl-lite/gsl-lite/tree/master/example/with-CPM) and
[example/with-Vcpkg](https://github.com/gsl-lite/gsl-lite/tree/master/example/with-Vcpkg) for example projects
that use CPM and Vcpkg, respectively, to obtain *gsl-lite*.
Once the build system is set up, include the `` header file to use *gsl-lite*:
```c++
// main.cpp
#include
#include
void printCmdArgs( gsl_lite::span cmdArgs )
{
gsl_Expects( !cmdArgs.empty() );
auto argsWithoutExeName = cmdArgs.subspan( 1 );
for ( auto arg : argsWithoutExeName )
{
std::cout << arg << "\n";
}
}
int main( int argc, char* argv[] )
{
auto numArgs = gsl_lite::narrow_failfast( argc );
auto cmdArgs = gsl_lite::span( argv, numArgs );
printCmdArgs( cmdArgs );
}
```
## Why *gsl-lite*?
*gsl-lite* is different from [Microsoft GSL](https://github.com/microsoft/gsl), the default implementation of the
[C++ Core Guidelines support library (GSL)](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines), in the following ways:
- *gsl-lite* maintains support for older versions of C++ (C++98, C++03, C++11) and older compilers.
(see: [Reported to work with](#reported-to-work-with))
- *gsl-lite* supports [CUDA](https://developer.nvidia.com/cuda-toolkit), and many of its features can be used in CUDA kernel code.
- [Contract and assertion checks](doc/Reference.md#contract-and-assertion-checks) are more versatile and fine-grained, and
runtime enforcement is [configurable](doc/Reference.md#contract-checking-configuration-macros).
- In *gsl-lite*, `not_null
` retains the copyability and movability of `P` and therefore may have a [*moved-from state*](doc/Reference.md#nullability-and-the-moved-from-state),
which Microsoft GSL [expressly disallows](https://github.com/microsoft/GSL/issues/1022#issuecomment-1022713632).
As a consequence, `not_null>` is movable in *gsl-lite* but not in Microsoft GSL.
- *gsl-lite* defines [feature testing macros](doc/Reference.md#feature-checking-macros) and [polyfills](doc/Reference.md#polyfills) useful for targeting multiple versions of C++.
- *gsl-lite* comes as a single-header library.
## Features
See the [reference documentation](doc/Reference.md) for a detailed explanation of the features provided by *gsl-lite*, and
Section [GSL: Guidelines support library](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#S-gsl) of the C++ Core Guidelines
for the specification of the Guidelines support library.
Feature \\ library | GSL spec | MS GSL | *gsl‑lite* | Notes |
------------------------------------------------------------------------|:-----------:|:-------------:|:-------------------:|:-------|
[**Views:**](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#gslview-views) | | | | |
[`owner<>`](doc/Reference.md#ownerp-c11-and-higher) | ✓ | ✓ | ✓¹¹ | Annotate a raw pointer that carries ownership |
[`not_null<>`](doc/Reference.md#not_nullp) | ✓ | ✓ | ✓ | Annotate a (smart) pointer that must not be `nullptr`; enforces non-nullability at runtime
(cf. `strict_not_null<>` in Microsoft GSL) |
[`not_null_ic<>`](doc/Reference.md#not_null_icp) | - | ✓ | ✓ | Like `not_null<>` but allows implicit construction from nullable pointers
(cf. `not_null<>` in Microsoft GSL) |
[`make_unique<>()`](doc/Reference.md#not_nullp) | - | - | ✓¹¹ | Like [`std::make_unique()`](https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique) but returns `not_null>` |
[`make_shared<>()`](doc/Reference.md#not_nullp) | - | - | ✓¹¹ | Like [`std::make_shared()`](https://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared) but returns `not_null>` |
[`span<>`](doc/Reference.md#safe-contiguous-ranges) | ✓ | ✓ | ✓ | Like [`std::span<>`](https://en.cppreference.com/w/cpp/container/span) but with bounds-checking |
[`zstring`
`czstring`](doc/Reference.md#string-type-aliases) | ✓ | ✓ | ✓ | Aliases for `char *` and `char const *` to be used for 0-terminated strings (C-style strings) |
[`wzstring`
`cwzstring`](doc/Reference.md#string-type-aliases) | - | ✓ | ✓ | Aliases for `wchar_t *` and `wchar_t const *` to be used for 0-terminated strings (C-style strings) |
[`u8zstring`
`cu8zstring`](doc/Reference.md#string-type-aliases) | - | ✓ | ✓²⁰ | Aliases for `char8_t *` and `char8_t const *` to be used for 0-terminated UTF-8 strings |
[`u16zstring`
`cu16zstring`](doc/Reference.md#string-type-aliases) | - | ✓ | ✓¹¹ | Aliases for `char16_t *` and `char16_t const *` to be used for 0-terminated UTF-16 strings |
[`u32zstring`
`cu32zstring`](doc/Reference.md#string-type-aliases) | - | ✓ | ✓¹¹ | Aliases for `char32_t *` and `char32_t const *` to be used for 0-terminated UTF-32 strings |
[**Assertions:**](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#gslassert-assertions) | | | | |
[`Expects()`](doc/Reference.md#contract-and-assertion-checks) | ✓ | ✓ | (✓) | Checks precondition
(only defined in [GSL compatibility mode](doc/Reference.md#gsl_feature_gsl_compatibility_mode0)) |
[`Ensures()`](doc/Reference.md#contract-and-assertion-checks) | ✓ | ✓ | (✓) | Checks precondition
(only defined in [GSL compatibility mode](doc/Reference.md#gsl_feature_gsl_compatibility_mode0)) |
[`gsl_Expects()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓ | Checks precondition |
[`gsl_ExpectsDebug()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓ | Checks precondition unless [`NDEBUG`](https://en.cppreference.com/w/cpp/error/assert) is defined |
[`gsl_ExpectsAudit()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓ | Checks precondition if [audit mode](doc/Reference.md#runtime-enforcement) is enabled |
[`gsl_Ensures()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓ | Checks postcondition |
[`gsl_EnsuresDebug()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓ | Checks postcondition unless [`NDEBUG`](https://en.cppreference.com/w/cpp/error/assert) is defined |
[`gsl_EnsuresAudit()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓ | Checks postcondition if [audit mode](doc/Reference.md#runtime-enforcement) is enabled |
[`gsl_Assert()`
`gsl_AssertAt()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓
✓²⁰ | Checks invariant (statement) |
[`gsl_Verify()`
`gsl_VerifyAt()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓
✓²⁰ | Checks invariant (expression) |
[`gsl_AssertDebug()`
`gsl_AssertAtDebug()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓
✓²⁰ | Checks invariant unless [`NDEBUG`](https://en.cppreference.com/w/cpp/error/assert) is defined |
[`gsl_AssertAudit()`
`gsl_AssertAtAudit()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓
✓²⁰ | Checks invariant if [audit mode](doc/Reference.md#runtime-enforcement) is enabled |
[`gsl_FailFast()`
`gsl_FailFastAt()`](doc/Reference.md#contract-and-assertion-checks) | - | - | ✓
✓²⁰ | Terminates execution |
[**Utilities:**](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#gslutil-utilities) | | | | |
[`finally()`](doc/Reference.md#ad-hoc-resource-management-c11-and-higher) | ✓ | ✓ | ✓¹¹ | Returns an object that executes a given action in its destructor; use for ad hoc resource cleanup |
[`on_return()`](doc/Reference.md#ad-hoc-resource-management-c11-and-higher) | - | - | (✓¹¹) | Creates an object that executes a given action in its destructor if no exception occurred
([opt-in](doc/Reference.md#gsl_feature_experimental_return_guard0) feature) |
[`on_error()`](doc/Reference.md#ad-hoc-resource-management-c11-and-higher) | - | - | (✓¹¹) | Creates an object that executes a given action in its destructor if an exception was thrown
([opt-in](doc/Reference.md#gsl_feature_experimental_return_guard0) feature) |
[`at()`](doc/Reference.md#bounds-checked-element-access) | ✓ | ✓ | ✓ | Bounds-checked element access for C-style arrays and containers with random access |
[`index`](doc/Reference.md#integer-type-aliases) | ✓ | ✓ | ✓ | Signed integer type for indexes and subscripts |
[`dim`](doc/Reference.md#integer-type-aliases) | - | - | ✓ | Signed integer type for sizes |
[`stride`](doc/Reference.md#integer-type-aliases) | - | - | ✓ | Signed integer type for index strides |
[`diff`](doc/Reference.md#integer-type-aliases) | - | - | ✓ | Signed integer type for index differences |
[`narrow_cast<>()`](doc/Reference.md#narrow_castt-u-) | ✓ | ✓ | ✓ | Narrowing cast which tolerates lossy conversions; equivalent to `static_cast<>()` |
[`narrow<>()`](doc/Reference.md#narrowt-u-) | ✓ | ✓ | ✓ | Checked narrowing cast; throws `narrowing_error` if cast is lossy |
[`narrow_failfast<>()`](doc/Reference.md#narrow_failfastt-u-) | - | - | ✓ | Checked narrowing cast; fails assertion check if cast is lossy |
¹¹: C++11 or newer required
²⁰: C++20 or newer required
## Migration guide
Starting with v1.0, *gsl-lite* lives in the single header file ``, and all its symbols reside in namespace
`gsl_lite`. By default, *gsl-lite* no longer defines a namespace `gsl` or the unprefixed `Expects()` and `Ensures()` macros for
precondition and postcondition checking.
This change enables coexistence with [Microsoft GSL](https://github.com/microsoft/GSL) ([#194](https://github.com/gsl-lite/gsl-lite/issues/194)).
### Adapting your code
If you are migrating from *gsl-lite* v0.\*, adapt your code by referencing namespace `gsl_lite` rather than namespace `gsl`, and by
using the prefixed macros `gsl_Expects()` and `gsl_Ensures()` rather than the unprefixed macros `Expects()` and `Ensures()` for
precondition and postcondition checking.
Note that *gsl-lite* v1 also changed the defaults for many of *gsl-lite*'s configuration options. See the
[v1.0.0 release notes](https://github.com/gsl-lite/gsl-lite/releases/tag/v1.0.0) for a comprehensive list of changes.
This should not affect you if you had already opted in to version-1 defaults by setting `gsl_CONFIG_DEFAULTS_VERSION=1`
or by linking to the `gsl::gsl-lite-v1` target in CMake.
To reduce the pervasiveness of required changes, it can be useful to define a namespace alias inside your own namespace:
```c++
// my-lib.hpp
#include // instead of
namespace my_lib {
namespace gsl = ::gsl_lite; // convenience alias
inline double median( gsl::span elements )
{
gsl_Expects( !elements.empty() ); // instead of Expects()
...
}
} // namespace my_lib
```
### Using the GSL compatibility mode
To minimize the impact of the breaking changes, *gsl-lite* introduces an optional *GSL compatibility mode* controlled by the
new configuration switch [`gsl_FEATURE_GSL_COMPATIBILITY_MODE`](doc/Reference.md#feature-selection-macros), which is is disabled
by default and can be enabled by defining `gsl_FEATURE_GSL_COMPATIBILITY_MODE=1`.
If the GSL compatibility mode is enabled, *gsl-lite* additionally makes the following global definitions:
```c++
namespace gsl = ::gsl_lite;
#define Expects( x ) gsl_Expects( x )
#define Ensures( x ) gsl_Ensures( x )
```
The GSL compatibility mode precludes the use of *gsl-lite* and Microsoft GSL in the same translation unit. Therefore, **do not use
the GSL compatibility mode when using *gsl-lite* in a public header file of a library.** (See notes on
[using *gsl-lite* in libraries](#using-gsl-lite-in-libraries) below.)
The GSL compatibility mode causes no link-time interference between *gsl-lite* and as Microsoft GSL. Both libraries may be used in
the same project as long as no translation unit includes both at the same time.
The legacy header file `` now forwards to `` and implicitly enables the GSL compatibility mode.
When the legacy header is included, it emits a warning message that urges to either migrate to header ``,
namespace `gsl_lite` and the prefixed contract checking macros `gsl_Expects()` and `gsl_Ensures()`, or to explicitly request GSL
compatibility by defining `gsl_FEATURE_GSL_COMPATIBILITY_MODE=1`.
## Using *gsl-lite* in libraries
Many features of *gsl-lite* are very useful for defining library interfaces, for instance spans, contract checks, or `not_null<>`.
*gsl-lite* can coexist with Microsoft GSL. However, the GSL compatibility mode of *gsl-lite* may cause interference with Microsoft GSL.
Also, *gsl-lite* is customizable through a large number of configuration options and switches. These configuration macros may affect the API and
ABI of *gsl-lite* in ways that renders it incompatible with other code. How *gsl-lite* is configured should be the prerogative of the consumer,
not the author, of a library.
Therefore, when using *gsl-lite* in a library, please mind the following suggestions:
- Do not define, or rely on, any of *gsl-lite*'s configuration options or switches when using *gsl-lite* in a library.
- In particular, do not enable the GSL compatibility mode.
- Do not use the legacy header file ``, which implicitly enables the GSL compatibility mode; use the header `` instead.
- Use namespace `gsl_lite` rather than namespace `gsl`; if desired, define a `namespace gsl = ::gsl_lite;` alias in your own namespace.
- Use the prefixed contract checking macros `gsl_Expects()` and `gsl_Ensures()` rather than the unprefixed macros `Expects()` and `Ensures()`.
## Reported to work with
The table below mentions the compiler versions and platforms *gsl-lite* is reported to work with.
Compiler | OS | Platforms | Versions | CI |
--------------------:|:----------------|-----------|------------------:|----|
GCC | Linux | x64 | 4.7 and newer | [9, 10, 11, 12, 13, 14](https://dev.azure.com/gsl-lite/gsl-lite/_build?definitionId=1) |
GCC (MinGW) | Windows | x86, x64 | 4.8.4 and newer | |
GCC (DJGPP) | DOSBox, FreeDOS | x86 | 7.2 | |
GCC | MacOS | x64 | 6 and newer | [11, 12, 13, 14](https://dev.azure.com/gsl-lite/gsl-lite/_build?definitionId=1) |
Clang | Linux | x64 | 3.5 and newer | [11, 12, 13, 14, 15, 16, 17, 18, 19, 20](https://dev.azure.com/gsl-lite/gsl-lite/_build?definitionId=1) |
Clang with libstdc++ | Linux | x64 | 11 and newer | [20](https://dev.azure.com/gsl-lite/gsl-lite/_build?definitionId=1) |
Clang | Windows | x64 | version shipped with VS | VS [2022, 2026](https://dev.azure.com/gsl-lite/gsl-lite/_build?definitionId=1) |
MSVC (Visual Studio) | Windows | x86, x64 | VS 2010 and newer | VS [2010, 2012, 2013, 2015, 2017, 2019](https://ci.appveyor.com/project/gsl-lite/gsl-lite), [2022, 2026](https://dev.azure.com/gsl-lite/gsl-lite/_build?definitionId=1) |
AppleClang (Xcode) | MacOS | x64 | 7.3 and newer | [15, 16, 17](https://dev.azure.com/gsl-lite/gsl-lite/_build?definitionId=1) |
NVCC (CUDA Toolkit) | Linux, Windows | x64 | 10.2 and newer | [12.8, 12.9](https://dev.azure.com/gsl-lite/gsl-lite/_build?definitionId=1) |
ARMCC | | ARM | 5 and newer | |
## Version semantics
*gsl-lite* follows [Semantic Versioning](https://semver.org/) guidelines. We maintain [API](https://en.wikipedia.org/wiki/Application_programming_interface) and
[ABI](https://en.wikipedia.org/wiki/Application_binary_interface) compatibility and avoid breaking changes in minor and patch releases.
Development of *gsl-lite* happens in the `master` branch. Versioning semantics apply only to tagged releases: there is no stability guarantee between individual
commits in the `master` branch, that is, anything added since the last tagged release may be renamed, removed, or have the semantics changed without further notice.
A minor-version release will be compatible (in both ABI and API) with the previous minor-version release. Thus, once a change is released, it becomes part of the API.
Some of the [configuration options](doc/Reference.md#configuration-options-and-switches) may affect the API and ABI of *gsl-lite*.
## Contributing
Contributions to *gsl-lite* through [pull requests](https://github.com/gsl-lite/gsl-lite/pulls) or [issues](https://github.com/gsl-lite/gsl-lite/issues) are welcome.
*gsl-lite* comes with a test suite that uses an included, slightly modified copy of the [*lest* test framework](https://github.com/martinmoene/lest).
To build *gsl-lite*'s test suite, enable the CMake build option `GSL_LITE_OPT_BUILD_TESTS` when configuring the project.