- Notifications
You must be signed in to change notification settings - Fork110
ISO C++ Core Guidelines Library implementation for C++98, C++11 up
License
gsl-lite/gsl-lite
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
| metadata | build | packages | try online |
|---|---|---|---|
gsl-lite is a portable, single-file, header-only library for defensive programming based on theC++ Core Guidelines Support Library specification.
- Example usage
- In a nutshell
- License
- Dependencies
- Installation and use
- Whygsl-lite?
- Features
- Reference documentation
- Migration guide
- Usinggsl-lite in libraries
- Reported to work with
- Version semantics
- Contributing
#include<memory>#include<utility>#include<numeric>#include<gsl-lite/gsl-lite.hpp>namespacemy_lib {// Define this in your own namespace.namespacegsl= ::gsl_lite;// `span<T[, Extent]>`: contiguous range with bounds checksdoublemean( gsl::span<doubleconst> values ) {// `gsl_Expects( cond )`: precondition checkgsl_Expects( !values.empty() );double sum =std::accumulate( values.begin(), values.end(),0. );// `narrow_failfast<T>( u )`: checked numeric castdouble num = gsl::narrow_failfast<double>(std::ssize( values ) );return sum / num; }classResource { ...public:Resource( std::size_t size ); };// Type-encoded precondition with `not_null<P>`voidconsumeResource( gsl::not_null<std::unique_ptr<Resource>> resource );// Type-encoded postcondition with `not_null<P>` gsl::not_null<std::unique_ptr<Resource>>acquireResource( std::size_t size ) {// A flavor of `make_unique<T>()` which returns `not_null<std::unique_ptr<T>>`return gsl::make_unique<Resource>( size ); }}// namespace my_lib
gsl-lite strives to implement theGuidelines Support Library specification of the C++ Core Guidelinesmaintained by theStandard C++ Foundation.The library is originally based onMicrosoft 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.
gsl-lite uses theMIT license.
gsl-lite has no dependencies other than theC++ standard library.
The recommended way to consumegsl-lite in your CMake project is to usefind_package() to locate the packagegsl-liteandtarget_link_libraries() to link to the imported targetgsl-lite::gsl-lite:
cmake_minimum_required(VERSION 3.20 FATAL_ERROR )project( my-program LANGUAGES CXX )find_package( gsl-lite 1.0 REQUIRED )add_executable( my-program main.cpp )target_compile_features( my-programPRIVATE cxx_std_17 )target_link_libraries( my-programPRIVATE gsl-lite::gsl-lite )
gsl-lite is available viaVcpkg,Conan,and possibly other package managers. It may also be obtained withCPM:
CPMFindPackage(NAME gsl-liteVERSION 1.0.1 GITHUB_REPOSITORY gsl-lite/gsl-lite )
See the directoriesexample/with-CPM andexample/with-Vcpkg for example projectsthat use CPM and Vcpkg, respectively, to obtaingsl-lite.
Once the build system is set up, include the<gsl-lite/gsl-lite.hpp> header file to usegsl-lite:
// main.cpp#include<iostream>#include<gsl-lite/gsl-lite.hpp>voidprintCmdArgs( gsl_lite::span<gsl_lite::zstringconst> cmdArgs ){gsl_Expects( !cmdArgs.empty() );auto argsWithoutExeName = cmdArgs.subspan(1 );for (auto arg : argsWithoutExeName ) { std::cout << arg <<"\n"; }}intmain(int argc,char* argv[] ){auto numArgs = gsl_lite::narrow_failfast<std::size_t>( argc );auto cmdArgs =gsl_lite::span( argv, numArgs );printCmdArgs( cmdArgs );}
gsl-lite is different fromMicrosoft GSL, the default implementation of theC++ Core Guidelines support library (GSL), 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) - gsl-lite supportsCUDA, and many of its features can be used in CUDA kernel code.
- Contract and assertion checks are more fine-grained, and runtime enforcement isconfigurable.
- Ingsl-lite,
not_null<P>retains the copyability and movability ofPand therefore may have amoved-from state,which Microsoft GSLexpressly disallows.As a consequence,not_null<std::unique_ptr<T>>is movable ingsl-lite but not in Microsoft GSL. - gsl-lite definesfeature testing macros andpolyfills useful for targeting multiple versions of C++.
- gsl-lite comes as a single-header library.
See thereference documentation for a detailed explanation of the features provided bygsl-lite, andSection GSL: Guidelines support library of the C++ Core Guidelinesfor the specification of the Guidelines support library.
| Feature \ library | GSL spec | MS GSL | gsl‑lite | Notes |
|---|---|---|---|---|
| Views: | ||||
owner<> | ✓ | ✓ | ✓¹¹ | Annotate a raw pointer that carries ownership |
not_null<> | ✓ | ✓ | ✓ | Annotate a (smart) pointer that must not benullptr; enforces non-nullability at runtime(cf. strict_not_null<> in Microsoft GSL) |
not_null_ic<> | - | ✓ | ✓ | Likenot_null<> but allows implicit construction from nullable pointers(cf. not_null<> in Microsoft GSL) |
make_unique<>() | - | - | ✓¹¹ | Likestd::make_unique<T>() but returnsnot_null<std::unique_ptr<T>> |
make_shared<>() | - | - | ✓¹¹ | Likestd::make_shared<T>() but returnsnot_null<std::shared_ptr<T>> |
span<> | ✓ | ✓ | ✓ | Likestd::span<> but with bounds-checking |
zstringczstring | ✓ | ✓ | ✓ | Aliases forchar * andchar const * to be used for 0-terminated strings (C-style strings) |
wzstringwczstring | - | ✓ | ✓ | Aliases forwchar_t * andwchar_t const * to be used for 0-terminated strings (C-style strings) |
| Assertions: | ||||
Expects() | ✓ | ✓ | (✓) | Checks precondition at runtime (only defined inGSL compatibility mode) |
Ensures() | ✓ | ✓ | (✓) | Checks precondition at runtime (only defined inGSL compatibility mode) |
gsl_Expects() | - | - | ✓ | Checks precondition at runtime |
gsl_ExpectsDebug() | - | - | ✓ | Checks precondition at runtime unless NDEBUG is defined |
gsl_ExpectsAudit() | - | - | ✓ | Checks precondition at runtime ifaudit mode is enabled |
gsl_Ensures() | - | - | ✓ | Checks postcondition at runtime |
gsl_EnsuresDebug() | - | - | ✓ | Checks postcondition at runtime unless NDEBUG is defined |
gsl_EnsuresAudit() | - | - | ✓ | Checks postcondition at runtime ifaudit mode is enabled |
gsl_Assert() | - | - | ✓ | Checks invariant at runtime |
gsl_AssertDebug() | - | - | ✓ | Checks invariant at runtime unless NDEBUG is defined |
gsl_AssertAudit() | - | - | ✓ | Checks invariant at runtime ifaudit mode is enabled |
| Utilities: | ||||
finally() | ✓ | ✓ | ✓¹¹ | Returns an object that executes a given action in its destructor; use for ad hoc resource cleanup |
on_return() | - | - | (✓¹¹) | Creates an object that executes a given action in its destructor if no exception occurred (opt-in feature) |
on_error() | - | - | (✓¹¹) | Creates an object that executes a given action in its destructor if an exception was thrown (opt-in feature) |
at() | ✓ | ✓ | ✓ | Bounds-checked element access for C-style arrays and containers with random access |
index | ✓ | ✓ | ✓ | Signed integer type for indexes and subscripts |
dim | - | - | ✓ | Signed integer type for sizes |
stride | - | - | ✓ | Signed integer type for index strides |
diff | - | - | ✓ | Signed integer type for index differences |
narrow_cast<>() | ✓ | ✓ | ✓ | Narrowing cast which tolerates lossy conversions; equivalent tostatic_cast<>() |
narrow<>() | ✓ | ✓ | ✓ | Checked narrowing cast; throwsnarrowing_error if cast is lossy |
narrow_failfast<>() | - | - | ✓ | Checked narrowing cast; fails assertion check if cast is lossy |
¹¹: C++11 or newer required
Starting with v1.0,gsl-lite lives in the single header file<gsl-lite/gsl-lite.hpp>, and all its symbols reside in namespacegsl_lite. By default,gsl-lite no longer defines a namespacegsl or the unprefixedExpects() andEnsures() macros forprecondition and postcondition checking.
This change enables coexistence withMicrosoft GSL (#194).
If you are migrating fromgsl-lite v0.*, adapt your code by referencing namespacegsl_lite rather than namespacegsl, and byusing the prefixed macrosgsl_Expects() andgsl_Ensures() rather than the unprefixed macrosExpects() andEnsures() forprecondition and postcondition checking.
Note thatgsl-lite v1 also changed the defaults for many ofgsl-lite's configuration options. See thev1.0.0 release notes for a comprehensive list of changes.This should not affect you if you had already opted in to version-1 defaults by settinggsl_CONFIG_DEFAULTS_VERSION=1or by linking to thegsl::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:
// my-lib.hpp#include<gsl-lite/gsl-lite.hpp>// instead of <gsl/gsl-lite.hpp>namespacemy_lib {namespacegsl= ::gsl_lite;// convenience aliasinlinedoublemedian( gsl::span<doubleconst> elements ) {gsl_Expects( !elements.empty() );// instead of Expects() ... }}// namespace my_lib
To minimize the impact of the breaking changes,gsl-lite introduces an optionalGSL compatibility mode controlled by thenew configuration switchgsl_FEATURE_GSL_COMPATIBILITY_MODE, which is is disabledby default and can be enabled by defininggsl_FEATURE_GSL_COMPATIBILITY_MODE=1.
If the GSL compatibility mode is enabled,gsl-lite additionally makes the following global definitions:
namespacegsl= ::gsl_lite;#defineExpects( x) gsl_Expects( x )#defineEnsures( x) gsl_Ensures( x )
The GSL compatibility mode precludes the use ofgsl-lite and Microsoft GSL in the same translation unit. Therefore,do not usethe GSL compatibility mode when usinggsl-lite in a public header file of a library. (See notes onusinggsl-lite in libraries below.)
The GSL compatibility mode causes no link-time interference betweengsl-lite and as Microsoft GSL. Both libraries may be used inthe same project as long as no translation unit includes both at the same time.
The legacy header file<gsl/gsl-lite.hpp> now forwards to<gsl-lite/gsl-lite.hpp> 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<gsl-lite/gsl-lite.hpp>,namespacegsl_lite and the prefixed contract checking macrosgsl_Expects() andgsl_Ensures(), or to explicitly request GSLcompatibility by defininggsl_FEATURE_GSL_COMPATIBILITY_MODE=1.
Many features ofgsl-lite are very useful for defining library interfaces, for instance spans, contract checks, ornot_null<>.
gsl-lite can coexist with Microsoft GSL. However, the GSL compatibility mode ofgsl-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 andABI ofgsl-lite in ways that renders it incompatible with other code. Howgsl-lite is configured should be the prerogative of the consumer,not the author, of a library.
Therefore, when usinggsl-lite in a library, please mind the following suggestions:
- Do not define, or rely on, any ofgsl-lite's configuration options or switches when usinggsl-lite in a library.
- In particular, do not enable the GSL compatibility mode.
- Do not use the legacy header file
<gsl/gsl-lite.hpp>, which implicitly enables the GSL compatibility mode; use the header<gsl-lite/gsl-lite.hpp>instead. - Use namespace
gsl_literather than namespacegsl; if desired, define anamespace gsl = ::gsl_lite;alias in your own namespace. - Use the prefixed contract checking macros
gsl_Expects()andgsl_Ensures()rather than the unprefixed macrosExpects()andEnsures().
The table below mentions the compiler versions and platformsgsl-lite is reported to work with.
| Compiler | OS | Platforms | Versions | CI |
|---|---|---|---|---|
| GCC | Linux | x64 | 4.7 and newer | 9, 10, 11, 12, 13, 14 |
| 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 |
| Clang | Linux | x64 | 3.5 and newer | 11, 12, 13, 14, 15, 16, 17, 18, 19 |
| Clang with libstdc++ | Linux | x64 | 11 and newer | 19 |
| Clang | Windows | x64 | version shipped with VS | VS2019, 2022 |
| MSVC (Visual Studio) | Windows | x86, x64 | VS 2010 and newer | VS2010, 2012, 2013, 2015, 2017,2019, 2022 |
| AppleClang (Xcode) | MacOS | x64 | 7.3 and newer | 14, 15, 16 |
| NVCC (CUDA Toolkit) | Linux, Windows | x64 | 10.2 and newer | 12.8 |
| ARMCC | ARM | 5 and newer |
gsl-lite followsSemantic Versioning guidelines. We maintainAPI andABI compatibility and avoid breaking changes in minor and patch releases.
Development ofgsl-lite happens in themaster branch. Versioning semantics apply only to tagged releases: there is no stability guarantee between individualcommits in themaster 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 theconfiguration options may affect the API and ABI ofgsl-lite.
Contributions togsl-lite throughpull requests orissues are welcome.
gsl-lite comes with a test suite that uses an included, slightly modified copy of thelest test framework.To buildgsl-lite's test suite, enable the CMake build optionGSL_LITE_OPT_BUILD_TESTS when configuring the project.
About
ISO C++ Core Guidelines Library implementation for C++98, C++11 up
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.