GithubHelp home page GithubHelp logo

gsl's Introduction

GSL: Guidelines Support Library

Build Status

The Guidelines Support Library (GSL) contains functions and types that are suggested for use by the C++ Core Guidelines maintained by the Standard C++ Foundation. This repo contains Microsoft's implementation of GSL.

The entire implementation is provided inline in the headers under the gsl directory. The implementation generally assumes a platform that implements C++14 support.

While some types have been broken out into their own headers (e.g. gsl/span), it is simplest to just include gsl/gsl and gain access to the entire library.

NOTE: We encourage contributions that improve or refine any of the types in this library as well as ports to other platforms. Please see CONTRIBUTING.md for more information about contributing.

Project Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Usage of Third Party Libraries

This project makes use of the Google Test testing library. Please see the ThirdPartyNotices.txt file for details regarding the licensing of Google Test.

Supported features

Microsoft GSL implements the following from the C++ Core Guidelines:

Feature Supported? Description
1. Views
owner An alias for a raw pointer
not_null Restricts a pointer/smart pointer to hold non-null values
span A view over a contiguous sequence of memory. Based on the standardized version of std::span, however gsl::span enforces bounds checking.
span_p Spans a range starting from a pointer to the first place for which the predicate is true
basic_zstring A pointer to a C-string (zero-terminated array) with a templated char type
zstring An alias to basic_zstring with dynamic extent and a char type of char
czstring An alias to basic_zstring with dynamic extent and a char type of const char
wzstring An alias to basic_zstring with dynamic extent and a char type of wchar_t
cwzstring An alias to basic_zstring with dynamic extent and a char type of const wchar_t
u16zstring An alias to basic_zstring with dynamic extent and a char type of char16_t
cu16zstring An alias to basic_zstring with dynamic extent and a char type of const char16_t
u32zstring An alias to basic_zstring with dynamic extent and a char type of char32_t
cu32zstring An alias to basic_zstring with dynamic extent and a char type of const char32_t
2. Owners
unique_ptr An alias to std::unique_ptr
shared_ptr An alias to std::shared_ptr
stack_array A stack-allocated array
dyn_array A heap-allocated array
3. Assertions
Expects A precondition assertion; on failure it terminates
Ensures A postcondition assertion; on failure it terminates
4. Utilities
move_owner A helper function that moves one owner to the other
byte Either an alias to std::byte or a byte type
final_action A RAII style class that invokes a functor on its destruction
finally A helper function instantiating final_action
GSL_SUPPRESS A macro that takes an argument and turns it into [[gsl::suppress(x)]] or [[gsl::suppress("x")]]
[[implicit]] A "marker" to put on single-argument constructors to explicitly make them non-explicit
index A type to use for all container and array indexing (currently an alias for std::ptrdiff_t)
joining_thread A RAII style version of std::thread that joins
narrow A checked version of narrow_cast; it can throw narrowing_error
narrow_cast A narrowing cast for values and a synonym for static_cast
narrowing_error A custom exception type thrown by narrow
5. Concepts

The following features do not exist in or have been removed from the C++ Core Guidelines:

Feature Supported? Description
strict_not_null A stricter version of not_null with explicit constructors
multi_span Deprecated. Multi-dimensional span.
strided_span Deprecated. Support for this type has been discontinued.
basic_string_span Deprecated. Like span but for strings with a templated char type
string_span Deprecated. An alias to basic_string_span with a char type of char
cstring_span Deprecated. An alias to basic_string_span with a char type of const char
wstring_span Deprecated. An alias to basic_string_span with a char type of wchar_t
cwstring_span Deprecated. An alias to basic_string_span with a char type of const wchar_t
u16string_span Deprecated. An alias to basic_string_span with a char type of char16_t
cu16string_span Deprecated. An alias to basic_string_span with a char type of const char16_t
u32string_span Deprecated. An alias to basic_string_span with a char type of char32_t
cu32string_span Deprecated. An alias to basic_string_span with a char type of const char32_t

This is based on CppCoreGuidelines semi-specification.

Quick Start

Supported Compilers / Toolsets

The GSL officially supports the latest and previous major versions of VS with MSVC & LLVM, GCC, Clang, and XCode with Apple-Clang. Within these two major versions, we try to target the latest minor updates / revisions (although this may be affected by delays between a toolchain's release and when it becomes widely available for use). Below is a table showing the versions currently being tested.

Compiler Toolset Versions Currently Tested
XCode 13.2.1 & 12.5.1
GCC 111 & 102
Clang 122 & 112
Visual Studio with MSVC VS20223 & VS20194
Visual Studio with LLVM VS20223 & VS20194

If you successfully port GSL to another platform, we would love to hear from you!

  • Submit an issue specifying the platform and target.
  • Consider contributing your changes by filing a pull request with any necessary changes.
  • If at all possible, add a CI/CD step and add the button to the table below!
Target CI/CD Status
iOS CI_iOS
Android CI_Android

Note: These CI/CD steps are run with each pull request, however failures in them are non-blocking.

Building the tests

To build the tests, you will require the following:

  • CMake, version 3.14 or later to be installed and in your PATH.

These steps assume the source code of this repository has been cloned into a directory named c:\GSL.

  1. Create a directory to contain the build outputs for a particular architecture (we name it c:\GSL\build-x86 in this example).

     cd GSL
     md build-x86
     cd build-x86
    
  2. Configure CMake to use the compiler of your choice (you can see a list by running cmake --help).

     cmake -G "Visual Studio 15 2017" c:\GSL
    
  3. Build the test suite (in this case, in the Debug configuration, Release is another good choice).

     cmake --build . --config Debug
    
  4. Run the test suite.

     ctest -C Debug
    

All tests should pass - indicating your platform is fully supported and you are ready to use the GSL types!

Building GSL - Using vcpkg

You can download and install GSL using the vcpkg dependency manager:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install ms-gsl

The GSL port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

Using the libraries

As the types are entirely implemented inline in headers, there are no linking requirements.

You can copy the gsl directory into your source tree so it is available to your compiler, then include the appropriate headers in your program.

Alternatively set your compiler's include path flag to point to the GSL development folder (c:\GSL\include in the example above) or installation folder (after running the install). Eg.

MSVC++

/I c:\GSL\include

GCC/clang

-I$HOME/dev/GSL/include

Include the library using:

#include <gsl/gsl>

Usage in CMake

The library provides a Config file for CMake, once installed it can be found via find_package.

Which, when successful, will add library target called Microsoft.GSL::GSL which you can use via the usual target_link_libraries mechanism.

find_package(Microsoft.GSL CONFIG REQUIRED)

target_link_libraries(foobar PRIVATE Microsoft.GSL::GSL)

FetchContent

If you are using CMake version 3.11+ you can use the official FetchContent module. This allows you to easily incorporate GSL into your project.

# NOTE: This example uses CMake version 3.14 (FetchContent_MakeAvailable).
# Since it streamlines the FetchContent process
cmake_minimum_required(VERSION 3.14)

include(FetchContent)

FetchContent_Declare(GSL
    GIT_REPOSITORY "https://github.com/microsoft/GSL"
    GIT_TAG "v4.0.0"
    GIT_SHALLOW ON
)

FetchContent_MakeAvailable(GSL)

target_link_libraries(foobar PRIVATE Microsoft.GSL::GSL)

Debugging visualization support

For Visual Studio users, the file GSL.natvis in the root directory of the repository can be added to your project if you would like more helpful visualization of GSL types in the Visual Studio debugger than would be offered by default.

Footnotes

  1. Precise version may be found in the latest CI results.

  2. Precise version may be found in the latest CI results. Should be the version specified here. 2 3

  3. Precise version may be found in the latest CI results. Should be the version specified here. 2

  4. Precise version may be found in the latest CI results. Should be the version specified here. 2

gsl's People

Contributors

bashrc-real2 avatar beinhaerter avatar caseycarter avatar chfast avatar dmitrykobets-msft avatar ericlemanissier avatar farwaykorse avatar galik avatar garyfurnish avatar gdr-at-ms avatar johelegp avatar jordanmaples avatar jpr42 avatar kernhanda avatar kristc avatar londey avatar martinmoene avatar mattnewport avatar menete avatar mikegitb avatar mymedia2 avatar neilmacintosh avatar paweldac avatar rianquinn avatar stephandollberg avatar tiagomacarios avatar trebconnell avatar vladon avatar xvitaly avatar zacharyhenkel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gsl's Issues

`as_array_view` for types with alignment requirement

array_view::as_array_view() for byte arrays should either be restricted to types without alignment requirement or verify at runtime that the data pointer is properly aligned. Otherwise (according to The Standard) reinterpret_cast may adjust the data pointer and I doubt this is the desired behaviour.

Brace style is inconsistent.

There are places where we do

struct Foo {
...
};

And others where we do

struct Bar
{
...
};

We should pick one and stick with it.

does array_view assume "default char unsigned" ?

Problem when using unsigned char:
array_view.h(495): const char dynamic_range = -1;

Problem when using signed char, many of the following:
array_view.h(xxxx): warning C4245: 'initializing': conversion from 'const char' to 'const size_t', signed/unsigned mismatch

I'm not too keen on disabling the related warnings...

Works on FreeBSD 10.x

As requested, this is a report that the library builds and works with FreeBSD 10.x. The default system c++ compiler (clang 3.4) is too old, but installing the clang36 package and setting -DCMAKE_CXX_COMPILER=clang++36 or -DCMAKE_CXX_COMPILER=clang++37 when installing results in all tests passing.

Final_act can lead to program termination if the final act throws an exception

Final_act does not check that the object to be invoked is no-except invokable or try to catch any generated exceptions. This could be bad if multiple final acts are used to clear up state on scope exit.

Either Final_act should catch exceptions or there should be an requirement that the invokable object cannot throw exceptions when invoked. It may be desirable to have two implementations of Final_act:
Final_act and Final_act_noexcept which try and catch exceptions or do not depending on the noexcept status of the invokable object.

coordinate_facade doesn't verify ValueType is unsigned

coordinate_facade has a static assert with the string: "ValueType must be unsigned integral type!", but it doesn't verify that ValueType is unsigned. If I change it to verify this it fails because array_view_tests use char.

Should not_null act like an alias

Right now it's implemented like a smart pointer, with method like get(), but if I'm reading the isocpp guidelines correctly it should act like an alias. Given that it's under GSL.Views with owner and not GSL.Owner with the smart pointers.

template <class T> using not_null = T;

Docs do not explain how to use the library

AFAICS the docs are not completely self-contained. At least I was not able to find out within 30 minutes how and when to use the library. I looked at https://github.com/isocpp/CppCoreGuidelines and still did not catch the idea. Are there any short examples?

I grabbed some ideas from the unit tests, especially as_array_view, but reading all unit tests to know about features like Expect may be error prone because someone probably confuses test features with GSL features.

Any docs available beyond https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetimes%20I%20and%20II%20-%20v0.9.1.pdf ?

Another example: What is the semantics of maybe_null_dbg? Cannot grab it from this test:

    TEST(TestMaybeNull1)
    {
        int n = 5;
        maybe_null_dbg<int *> opt_n(&n);
        int result = 0;
        bool threw = false;

        CHECK_THROW(result = *opt_n, fail_fast);
    }

Design of Final_act is dependent on copy elision to avoid multiple 'final acts'

The move constructor does not flag the moved-from object as non-invokable

auto invocation_count = 0;
auto f = finally([&invocation_count]{ ++invocation_count;});
assert(invocation_count == 1);

If the copy-by-rvalue-reference is not elided (which is possible but not necessary) then the invocation count will be 2. The final_act object needs an internal bool to track its state or the C++ standard needs to require copy elision.

See: https://github.com/jbcoe/CppSandbox/blob/master/ScopeGuard/ScopeGuard.cpp

for a similar class.

Use a specific version of unittest-cpp

Currently the README says to clone https://github.com/Microsoft/unittest-cpp, which means a given SHA of GSL may produce different test results on different days if/as unittest-cpp gets new commits.

Two related questions then:

  • can we use a git submodule to pin to a particular SHA of unittest-cpp? Or some other mechanism?
  • is Microsoft going to maintain its fork of unittest-cpp or is it upstreaming its changes?

Why does fail_fast_assert throw and not assert?

I know that people have different opinions about this, but in the design by contract community most people seem to adhere to this principle:
Use asserts for invariants, preconditions and postconditions. Use exceptions when user input is involved.

The purpose is to fail fast, and an assert is a way to fail faster since exceptions can be caught and hence worked around. People should never be able to work-around these invariants. If you fail to comply with the preconditions anything can happen (which I consider a good thing) and the implementations should not continue as if nothing happened.

If you follow this principle, Expects and Ensures should assert and not throw. It also means that you shouldn't put something in an not_null when it directly comes from the user (for example input data from a text file, something coming from an edit box, ...) since you are not sure that the precondition is fulfilled and hence it doesn't make sense to let not_null throw.

Some people also follow a slightly different variant: Use asserts for logic errors in your own code and exceptions when client code is involved. The different with the previous principle is that here the we are talking about client code and not user input. Since for example a not_null can be both used internally and at the border of the interface for the client you might want to use exceptions in for not_null when (and only when) client code is involved. In this case you might want to add a policy to these classes to be able to specify the desired fail behavior.

Anyway, since (some) people would like to be able to use these libraries without having exceptions, but have asserts instead, it makes sense to let the users to this library specify what should happen when the pre- and postconditions are not met. Next to the conceptual reasons there is also a performance reason. If the code is guaranteed not to throw more optimizations can be done.

Reduce minimum required version of CMake for building

Is there any reason to require CMake 3.2.2? I tried to lower it to 3.0.0 (version I have on my machine) and gsl was built and passed all tests. It probably can be built with even older versions.

I can send a PR to lower it for 3.0.0 for now.

Final_act move constructor

Final_act(const Final_act&& other) : f_(other.f_) {}

Shouldn't that be:

Final_act(Final_act&& other) : f_(std::move(other.f_)) {}

Add generated files to .gitignore

I ran cmake to generate a VS solution and built, and got a ton of generated files not ignored by .gitignore. Would be good to add these files.

Missing directory unittest-cpp

The unites-cpp directory should be part of the main repository so that:
(1) git clone
(2) cmake configure
succeeds out of the box.

add travis testing

I added travis testing for gcc5 and clang36 on my fork
I'm ready to send in a PR if I got approval for this issue.
Let me know I need to add more compilers and which ones.

Avoid the use of macros as Expected

Having macros that are not prefixed by the library name is a bad practice as in

#define Expects(x)  Guide::fail_fast_assert((x))
#define Ensures(x)  Guide::fail_fast_assert((x))

Usually we use UPPERCASE letters for macros.

In addition, we have inline functions in C++, so no need for a macro that call another function ;-)

not_null<>: Missing assignment from related types ?

For not_null<>, if there's a constructor for related types:

template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
not_null(const not_null<U> &other);

I would also expect the assigment:

template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
not_null<T> & operator=( not_null<U> const & other );

However it's not present.

GSL.assert macros should be methods

Considering the intent of Expects/Ensures to eventually be part of declarations, I can understand why they were made macros, but until a tool (or perhaps compiler extension, since I'm not sure it's possible to implement other than a namespace colliding macro?) actually supports placing them in a declaration, I think they would be better as functions.

As in the guidelines (ES.31), macros violate the usual scope rules, they can behave oddly with parameters, and they should be avoided unless necessary. Given this, I believe that as long as Ensures/Expects are being used in their current form, they would be better suited to functions.

Prefix all the macros by GUIDE_

We can see the use of macros that can collide with the application macros as in

#if defined(SAFER_CPP_TESTING)

all the macros of the library must be prefixed by GUIDE_.

The `final_act` helper function name `finally` is misleading.

The final_act helper function function, finally, is misleadingly named as it returns an object which, if not captured, will result in instant invocation of the given function object.

The following code looks correct but database lookups and insertions will fail as the 'final-act' was invoked at [1].

auto db_handle = my_db_api_open_db("My database name");
finally([db_handle]{ db_api_close_db(db_handle); }); // [1]
// do some lookups and insertions

I propose that finally is renamed to make_final_act or is replaced by a macro that captures the return value for the user into a uniquely named temporary variable (I prefer make_final_act).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.