Compare commits

...

94 Commits
v4.0.0 ... main

Author SHA1 Message Date
Werner Henze
3325bbd33d
Fix version info (#1202)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
Just tagging as 4.2.0 is not enough, the version number must be incremented for cmake and in the readme. Compare https://github.com/microsoft/GSL/pull/1163.

Co-authored-by: Werner Henze <w.henze@avm.de>
2025-03-27 11:00:24 -05:00
Werner Henze
2828399820
replace BYTE_TYPE with a solution based on namespaces (#1201)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
- 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>
2025-02-28 08:53:25 -06:00
Werner Henze
c5fbb81ad4
documentation (#1200)
- reintroduce documentation internal links
- remove `gsl::` prefix in table so it is the same as in the other tables
- fix documentation for span::element_type

Co-authored-by: Werner Henze <w.henze@avm.de>
2025-02-28 08:49:53 -06:00
Carson Radtke
7fabaa499d
deprecate features adopted into C++ (#1198)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
* 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
2025-02-14 11:24:51 -06:00
Carson Radtke
4742bc192a
use relative path in # include (#1194)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
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".
2025-02-12 09:16:45 -06:00
Carson Radtke
ec729d63a7
introduce gsl::not_null<T>::element_type (#1196)
* introduce gsl::not_null<T>::element_type

* use std::is_same instead of is_same_v

* fix: cannot put a non-pointer in a gsl::not_null
2025-02-12 09:16:05 -06:00
Carson Radtke
7f4fc9388b
Add more gsl::span tests [copilot] (#1189)
* Add more gsl::span tests [copilot]

This PR adds comprehensive unit tests for `gsl::span` to ensure its correctness and consistency. The following tests have been added:

1. **Empty Span Tests**:
   - Tests to verify the behavior of an empty `gsl::span` and `gsl::span<const int>`.

2. **Conversion Tests**:
   - Tests to check the conversion between different types of `gsl::span`.

3. **Comparison Operator Tests**:
   - Tests to verify the comparison operators for `gsl::span`.

4. **Deduction Guide Tests**:
   - Tests to compare the behavior of `gsl::span` and `std::span` deduction guides for various types of arrays and containers.

These tests help ensure that `gsl::span` behaves correctly in various scenarios and is consistent with `std::span`.

This PR was created with the help of GitHub Copilot.

**Changes**:
- Added tests for empty span.
- Added tests for conversions.
- Added tests for comparison operators.
- Added tests for deduction guides.

**Testing**:
- All new tests have been added to the existing test suite.
- Run the test suite using `ctest` to ensure all tests pass.This PR adds comprehensive unit tests for `gsl::span` to ensure its correctness and consistency. The following tests have been added:

1. **Empty Span Tests**:
   - Tests to verify the behavior of an empty `gsl::span` and `gsl::span<const int>`.

2. **Conversion Tests**:
   - Tests to check the conversion between different types of `gsl::span`.

3. **Comparison Operator Tests**:
   - Tests to verify the comparison operators for `gsl::span`.

4. **Deduction Guide Tests**:
   - Tests to compare the behavior of `gsl::span` and `std::span` deduction guides for various types of arrays and containers.

These tests help ensure that `gsl::span` behaves correctly in various scenarios and is consistent with `std::span`.

This PR was created with the help of GitHub Copilot.

**Changes**:
- Added tests for empty span.
- Added tests for conversions.
- Added tests for comparison operators.
- Added tests for deduction guides.

**Testing**:
- All new tests have been added to the existing test suite.
- Run the test suite using `ctest` to ensure all tests pass.

* fix tests for pre-C++17
2025-02-12 09:15:43 -06:00
Tiago
355982daf6
Delete gsl/string_span (#1185)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
This has been deprecated for 2+ years.
2025-01-07 08:58:59 -06:00
Werner Henze
50aaf2efbb
remove documentation for deprecated make_span overloads (#1183)
Co-authored-by: Werner Henze <werner.henze+gitcommits@posteo.de>
2025-01-07 08:50:49 -06:00
Tiago
7b6b8013b1
Add "gsl" to #includes (#1184)
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.
2025-01-07 08:42:38 -06:00
Werner Henze
1cdb8d295e
More checks for non-compilable code, plus fix for span (#1180)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
2025-01-04 11:50:31 -06:00
Carson Radtke
c832885f15
React to ubuntu-latest changing to 24.04 (#1181)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
* React to ubuntu-latest changing to 24.04
Reacting to https://github.com/actions/runner-images/issues/10636
* update clang to 16,17,18
* update gcc to 12,13,14
2025-01-03 10:23:50 -06:00
Werner Henze
16a60199df
strict_not_null for unique_ptr (#1179)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
- `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>
2024-12-26 11:00:36 -06:00
Werner Henze
fcd55ee924
Better use of std::enable_if (#1177)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
* this commits adds tests that should fail, but don't

* Better use of std::enable_if

Replace the occurances of `class = std::enable_if_t<Cond>` and `typename = std::enable_if_t<Cond>` that have been identified in the previous commit with `std::enable_if_t<Cond, bool> = true`.

This commit is inspired by #1174, which changed one occurance in the owner header. This commit is aimed to fix all remaining occurances.

* fix failing checks

- core.cxx_gsl aktualisiert auf [](https://gitlab.avm.de/fos/repos/core.cxx_gsl/-/commit/)
- plc.access_lib aktualisiert auf [](https://gitlab.avm.de/fos/repos/plc.access_lib/-/commit/)
- plc.common aktualisiert auf [](https://gitlab.avm.de/fos/repos/plc.common/-/commit/)
- plc.daemon aktualisiert auf [](https://gitlab.avm.de/fos/repos/plc.daemon/-/commit/)
-

Test Plan:
-

---------

Co-authored-by: Werner Henze <werner.henze+gitcommits@posteo.de>
Co-authored-by: Werner Henze <w.henze@avm.de>
2024-12-23 10:40:22 -06:00
Werner Henze
b8ac820fe1
Force unit tests for byte to use GSL implementation (#1176)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
When setting `GSL_USE_STD_BYTE` to zero, then the unit test does not compile because `byte` is ambiguous (could be `std::byte` or `gsl::byte`). So `gsl::` prefix is needed for `byte`.
It looks like the unit tests never ran on a platform where `gsl::byte` is not based on `std::byte`.
It does not make much sense to test `std::byte` for compliance, so make the unit tests based on the GSL implementation of `gsl::byte` (`#define GSL_USE_STD_BYTE 0`).

Co-authored-by: Werner Henze <werner.henze+gitcommits@posteo.de>
2024-12-18 10:16:36 -06:00
Carson Radtke
272463043e
introduce gsl::swap for swapping gsl::not_null (#1160)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
fixes: https://github.com/microsoft/GSL/issues/1129

* create gsl::swap<T>(T&, T&) which wraps std::swap
* specialize gsl::swap<T>(gsl::not_null<T>&, gsl::not_null<T>&)
* add tests
2024-12-13 15:16:53 -06:00
Carson Radtke
8a0e3d8a9b
fix: direct-init const ref instead of list-init (#1175)
fixes: https://github.com/microsoft/GSL/issues/1162

gcc has a bug that generates a call to the copy constructor when list
initializing a const reference. This PR offers a workaround which is to
direct initialize the value.

see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117900
2024-12-13 10:22:16 -06:00
Alberto La Rocca
aed09c41b6
Fix SFINAE on gsl::owner. (#1174)
`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
2024-12-13 09:56:28 -06:00
Carson Radtke
4b190d2e2a
Create issue templates (#1173)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
2024-12-02 14:34:38 -06:00
Carson Radtke
ddae9d72b6
fix stale badge links in README (#1170)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
* update pipeline badge links
* add link to compilers pipeline
* add badge to vcpkg version
2024-11-25 13:06:02 -06:00
Carson Radtke
74d2bb79d4
fix various pipeline failures (#1172)
* fix failing pipeline tests
* upgrade to googletest v1.14.0 so it works with newer cmake versions
* fix android pipeline to permit new cmake versions (short-term fix)
2024-11-25 12:58:45 -06:00
Carson Radtke
f8ec309118
improve performance of span_iterator w/ clang (#1166)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
* 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
2024-11-12 15:41:21 -06:00
Carson Radtke
87f9d76886
GSL v4.1.0 (#1163)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
Fixes: #1161

Update version strings in README and CMakeLists.txt.
2024-10-21 10:19:37 -05:00
Heiko Kröger
82ba6c77ce
Added the IWYU pragma export (#1154)
Some checks failed
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Has been cancelled
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
* Added the IWYU pragma export

clang-tidy has added the check misc-include-cleaner with version 17. This check respects the IWYU pragmas.
2024-10-15 17:26:45 -05:00
mq白
32511b8de4
Delete the useless 'noexcept(false)' (#1152)
Some checks are pending
Compiler Integration Tests / xcode (Release, 23, 15.4) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 14, , Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 17, , Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 20, , Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 23, , Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Debug, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 14, , Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 14, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 17, , Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 17, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 20, , Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 16 2019, windows-2019) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 20, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 23, , Visual Studio 17 2022, windows-2022) (push) Waiting to run
Compiler Integration Tests / VisualStudio (Release, 23, -T ClangCL, Visual Studio 17 2022, windows-2022) (push) Waiting to run
CI_iOS / iOS (push) Waiting to run
2024-10-14 15:30:40 -05:00
Konstantin Akimov
84b2ca1352
Remove unused headers from gsl/pointers (#1153)
* 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
2024-10-14 15:15:46 -05:00
Carson Radtke
ce2a959e02
[ci]: add testing pipelines to github actions (#1159)
move pipeline testing from AzDO to GitHub Actions.

* update clang versions to 13-15
* update gcc versions to 10-12
* update xcode versions to 14.3.1 and 15.4
* test against C++23 (where supported)
2024-10-14 15:05:13 -05:00
Brian Kroth
11fe02d1ac
Add a MS GSL disambiguation note (#1156) 2024-10-14 09:43:43 -05:00
Werner Henze
3275f9ccb9
Fix gcc build problem (#1149)
Some checks failed
CI_Android / Android (push) Has been cancelled
cmake_find_package / Build ${{ matrix.os }} (macos-latest) (push) Has been cancelled
cmake_find_package / Build ${{ matrix.os }} (ubuntu-latest) (push) Has been cancelled
CI_iOS / iOS (push) Has been cancelled
Closes issue #1148 by fixing problems introduced in PR #1140.

Co-authored-by: Werner Henze <w.henze@avm.de>
2024-10-11 19:46:21 -05:00
Carson Radtke
b206bd163b
[ci]: fix android job (#1158)
Job has been failing for months and is preventing other PRs from getting
merged. This PR fixes the pipeline - it changed the following:
 - runs on macos-latest-large (which is a non-arm image)
 - starts the emulator under java8 (see
   https://learn.microsoft.com/en-us/java/openjdk/transition-from-java-8-to-java-11)
 - runs emulator with -no-audio

The above were requirements to get the pipeline running. Other changes
include the following:
 - The job will auto-cancel when a newer commit is pushed to the
 PR.
 - The 'Wait for emulator ready' step now has a 2 minute timeout. This
   is necessary because we get no indication on whether or not the
   command that started the emulator suceeded. I believe there is room
   for improvement here, but it is outside the scope of the PR.
2024-10-11 16:05:20 -07:00
Werner Henze
b39e7e4b09
Add documentation for to_integer(byte) (#1144)
Co-authored-by: Werner Henze <w.henze@avm.de>
2024-02-26 13:23:45 -08:00
Stephan T. Lavavej
2e0d1ba48c
Test only __cpp_lib_byte, drop _HAS_STD_BYTE. (#1145) 2024-02-26 13:22:20 -08:00
d-winsor
1b4d42ca2e
Fix initialization in test (#1140)
* Suppress unsafe-buffer-usage
2024-02-26 13:17:12 -08:00
Bruce Mitchener
caae4dd0f8
Fix some typos. (#1146) 2024-02-21 15:06:29 -08:00
Bruce Mitchener
f1a494cfd2
ci: Update to actions/checkout@v4. (#1142)
This fixes annotations on task runs like the following:

    The following actions uses node12 which is deprecated and will be forced
    to run on node16: actions/checkout@v2. For more info:
    https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/
2024-01-17 15:25:32 -08:00
Bruce Mitchener
77b2f4f3b8
Fix some typos. (#1143) 2024-01-17 15:25:07 -08:00
Nicholas Guriev
e64c97fc2c
Mark not_null constructors as noexcept when underlying type can be moved with no exception (#1135)
This enables possible optimisations for trivial types. This also avoids a bug
in std::variant::emplace from GNU's libstdc++.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106547
2023-10-18 15:15:26 -07:00
Edward Chen
52212c2d76
Update Clang GSL_SUPPRESS to stringize parameter instead of using fixed string literal. (#1133)
Fix #1130.
2023-09-11 10:52:30 -07:00
Dmitry Kobets
2940006b5c
Suppress some noisy / buggy warnings (#1136)
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.
2023-09-11 10:06:40 -07:00
Werner Henze
9695da9b38
fix and optimize documentation (#1131)
- Add anchor for `finally` in `headers.md` so that the link in `README.md` can work
- In `README.md` add code formatting for the character types of the `zstring` and `string_span` types
- In `README.md` change code formatting to links for GSL types
- Vertical alignment
2023-09-05 16:08:36 -07:00
Dmitry Kobets
4300304ef2
Remove unused macros (#1128)
This macro is a relic of the old implementation of GSL's header. It is unused and can be removed.
2023-07-26 15:07:28 -07:00
Werner Henze
b34f7350fe
get back gcc 8.4 compatibility (#1127)
Before my PR #1122 `gsl/pointers` was gcc 8.4 compatible. Now it is not. This commit makes it compatible with gcc 8.4 again.
2023-07-06 12:51:48 -07:00
Werner Henze
167c77d28e
add missing include (#1126)
The header file uses `std::declval`, so it needs to `#include <utility>`.
2023-07-03 17:20:50 -07:00
Werner Henze
87e21400dc
remove gcc noexcept warning (#1122)
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>
2023-06-28 15:17:12 -07:00
Dmitry Kobets
3549e31ba4
Deprecate <gsl/string_span> and replace with <gsl/zstring> (#1125)
With `string_span` having been deprecated (https://github.com/microsoft/GSL/pull/931, https://github.com/microsoft/GSL/pull/945) and removed (https://github.com/microsoft/GSL/pull/1074), the header `<gsl/string_span>` now only contains the definitions for the `zstring` family. Update the name accordingly from `<gsl/string_span>` to `<gsl/zstring>`. The old header is now deprecated and should no longer be used and will be removed in some future release.
2023-06-28 10:48:23 -07:00
Dmitry Kobets
65a5995035
Remove deprecated headers (#1124)
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.
2023-06-28 10:48:04 -07:00
Dmitry Kobets
303d964a24
Deprecate the Ptr make_span overloads (#1113)
These overloads don't seem to be in a usable state, and their original purpose is no longer clear. Deprecate them.
Resolves #1092
2023-05-22 10:48:41 -07:00
jpr42
afaaa71bce
Install GSL.natvis (#1112)
Turns out supporting GSL.natvis perfectly is quite difficult.

There is no universal way to consume .natvis files that would satisfy everyone.

I thought the solution was to use the /NATVIS linker option. But it turns out that actually embeds information into the PDB. So I'm not sure how to properly support the Ninja generator...

That's not even accounting for the fact target_link_options doesn't play nicely with /NATVIS

When you just add the file via target_sources the visual studio solution will just pick it up and recognize it without adding it to the PDB file. Which won't affect the binary and is what most devs want.

This all comes down to the fact that /NATVIS files have native integration with visual studio that makes it difficult to use with non-visual studio solutions. /NATVIS almost works but embeds itself into the PDB which not everyone wants, and not everyone generates PDBs either.

Docs for natvis files and /NATVIS
- https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2022
- https://learn.microsoft.com/en-us/cpp/build/reference/natvis-add-natvis-to-pdb?view=msvc-170

So my current solution is to just simplify the existing CMake code, and install the natvis so the user can decide.

closes #1084
2023-05-10 17:02:44 -07:00
Dmitry Kobets
4b5b5a1ed5
Disable std::hash<gsl::not_null<T>> if std::hash<T> is not enabled. (#1109)
Resolves #914
2023-05-10 11:25:04 -07:00
Dmitry Kobets
5dc7fae119
Use the implementation-defined strict total order for pointer comparisons with not_null (#1106)
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
2023-05-09 09:06:53 -07:00
Dmitry Kobets
9face82309
Remove unnecessary check from size_bytes() (#1105)
`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
2023-05-09 09:05:26 -07:00
Dmitry Kobets
1d036585cc
Add testcase for #1100 (#1101) 2023-03-30 11:10:15 -07:00
Werner Henze
43d60c5e38
Suppress warning C26481 (#1099)
Suppress "warning C26481: Don't use pointer arithmetic. Use span instead (bounds.1)." in the code that impements `span`.
2023-03-14 16:57:46 -07:00
Stephan T. Lavavej
50d6eef541
Add span_iterator::_Prevent_inheriting_unwrap. (#1100) 2023-03-14 13:50:34 -07:00
dmitrykobets-msft
b080081c9c
Add missing link to documentation 2023-02-27 15:49:09 -08:00
Werner Henze
9f85e4e088
minor docs improvements (#1097)
- Capitalize inital letter (make both tables consistent)
- Add links to docs/headers.md
- Latest cmake requirement is 3.14
- Mark text as code
2023-02-23 11:10:19 -08:00
dmitrykobets-msft
78eb6ca145
Document span_ext (#1098)
`<gsl/span>` is intended to mirror `<span>` in the STL. `<span_ext>` provides convenience features that aren't part of `<span>`.
Address #1095
2023-02-23 10:22:02 -08:00
Werner Henze
7f7108a076
Better links to CoreGuidelines (#1094)
The `#i13-do-not-pass-an-array-as-a-single-pointer` anchor seems to be auto generated based on the title of the section. The `#Ri-array` anchor is explicitely written in the source, so this should be a better link.
2023-02-21 17:11:30 -08:00
Werner Henze
7a297d4283
Extend docs and tests for span ctor (#1096) 2023-02-21 15:46:40 -08:00
Werner Henze
9851b94d7e
add some span test for constructor from other span (#1093)
More combinations with dynamic_extent or fixed extent for higher coverage.
2023-02-17 13:05:40 -08:00
Werner Henze
743939744c
Documentation (#1086)
Add documentation for #1071.
2023-02-17 10:38:34 -08:00
Werner Henze
3ba80d5dd4
simplify to_byte (#1090)
- to_byte_impl is not necessary, the same can be achieved with shorter code
- add test code for things that should not compile
2023-02-14 14:10:56 -08:00
Werner Henze
49c88f27bd
add not_null and strict_not_null tests for const (#1085) 2023-02-06 13:16:06 -08:00
jpr42
f7da2e41f0
Raise CMake min to 3.14 (#1083)
- Explicitly test package manager support with CMake 3.14 and Ninja
- Remove gsl_install.cmake
- Simplify installation code
2023-02-06 11:16:37 -08:00
dmitrykobets-msft
cbf5e664fc
Fix max macro collision (#1081)
PR https://github.com/microsoft/GSL/pull/1076 introduced a usage of `numeric_limits::max()` function, which seems to have [issues interacting with some Windows headers](https://github.com/skypjack/entt/wiki/Frequently-Asked-Questions#warning-c4003-the-min-the-max-and-the-macro). This PR implements [a simple fix](https://stackoverflow.com/questions/1394132/macro-and-member-function-conflict), which is to wrap the invocations in parentheses. This offloads the fix from the users of the library.
2023-01-19 13:17:39 -08:00
Werner Henze
a381a3759f
1075 Wrong Expects in gsl::at? (#1076)
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`
2023-01-18 13:33:20 -08:00
Gabriel Gerlero
0822838a7c
Add Linguist language override for include files (#1079)
Add a `linguist-language` Git attribute that matches the files at `include/gsl` and sets their language to C++. Without this override, these files are not detected as C++ code by [GitHub's Linguist](https://github.com/github/linguist) (likely due to lacking any file extensions).

This will cause GitHub.com to count these files correctly as C++ code and do syntax highlighting when browsing the repo.

**Linguist breakdown results**

Before:

<details>


```
$ docker run --rm -v $(pwd):$(pwd) -w $(pwd) -t linguist github-linguist --breakdown
91.57%  152148     C++
8.43%   14011      CMake

CMake:
CMakeLists.txt
cmake/gsl_functions.cmake
cmake/gsl_install.cmake
include/CMakeLists.txt
tests/CMakeLists.txt

C++:
tests/algorithm_tests.cpp
tests/assertion_tests.cpp
tests/at_tests.cpp
tests/byte_tests.cpp
tests/deathTestCommon.h
tests/no_exception_ensure_tests.cpp
tests/notnull_tests.cpp
tests/owner_tests.cpp
tests/span_compatibility_tests.cpp
tests/span_ext_tests.cpp
tests/span_tests.cpp
tests/strict_notnull_tests.cpp
tests/utils_tests.cpp
```

</details>

After:

<details>

```
$ docker run --rm -v $(pwd):$(pwd) -w $(pwd) -t linguist github-linguist --breakdown
94.16%  225699     C++
5.84%   14011      CMake

CMake:
CMakeLists.txt
cmake/gsl_functions.cmake
cmake/gsl_install.cmake
include/CMakeLists.txt
tests/CMakeLists.txt

C++:
include/gsl/algorithm
include/gsl/assert
include/gsl/byte
include/gsl/gsl
include/gsl/gsl_algorithm
include/gsl/gsl_assert
include/gsl/gsl_byte
include/gsl/gsl_narrow
include/gsl/gsl_util
include/gsl/narrow
include/gsl/pointers
include/gsl/span
include/gsl/span_ext
include/gsl/string_span
include/gsl/util
tests/algorithm_tests.cpp
tests/assertion_tests.cpp
tests/at_tests.cpp
tests/byte_tests.cpp
tests/deathTestCommon.h
tests/no_exception_ensure_tests.cpp
tests/notnull_tests.cpp
tests/owner_tests.cpp
tests/span_compatibility_tests.cpp
tests/span_ext_tests.cpp
tests/span_tests.cpp
tests/strict_notnull_tests.cpp
tests/utils_tests.cpp
```
</details>
2023-01-06 08:11:06 -08:00
Werner Henze
f94c1f6f2b
use code spans in README.md (#1078) 2022-12-29 10:23:30 -08:00
Werner Henze
ac26d7bc71
cleanup natvis (#1077)
- `fail_fast`,`basic_string_span` and `basic_zstring_span` are not declared in the headers any more.
- Name the exporting header file for all types in `GSL.natvis`.
2022-12-29 10:21:11 -08:00
Werner Henze
c016bdc77f
remove all deprecated string_span stuff (#1074)
This solves issue #1070 and removes the class `string_span`. The only content remaining in the header file `gsl/string_span` is the `*zstring` types.
This also removes the `string_span_tests.cpp` unit tests as these were only for the deprecated `string_span` class.

Co-authored-by: Werner Henze <werner.henze+gitcommits@posteo.de>
2022-12-27 07:22:26 -08:00
dmitrykobets-msft
46c72713f2
Document potentially confusing behavior in gsl::narrow (#1073)
NaN != Nan, so the comparisons used in gsl::narrow will always throw when attempting to cast a NaN value. This may be surprising, so document it.
2022-12-24 11:49:26 -08:00
dmitrykobets-msft
6c6111acb7
Remove null check inside not_null::get (#1067)
Guidelines issue 2006 removes the null check inside not_null::get, since the contained pointer is already guaranteed to be not-null upon construction.

Resolves #1051
2022-12-14 18:16:52 -08:00
dmitrykobets-msft
f3620bb009
Suppress false postive warning (#1068)
The Clang compiler for MSVC in Visual Studio 2022 17.4.33122.133 used by the test runner has a bug which raises -Wdeprecated "out-of-line definition of constexpr static data member is redundant in C++17 and is deprecated" in gsl/span, when compiling with C++14. Temporarily suppress this warning for MSVC Clang with C++14.
2022-12-14 15:39:34 -08:00
Changming Sun
517ed29228
Fix GSL_SUPPRESS definition when nvcc is in-use (#1064) 2022-11-07 14:00:32 -08:00
jpr42
d69e578519
clang-tidy: performance-noexcept-move-constructor (#1063)
I ran GSL through clang-tidy with the performance-* checks

https://releases.llvm.org/15.0.0/tools/clang/tools/extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.html
2022-11-01 10:07:47 -07:00
jpr42
9c4212aca4
Raise CMake min to 3.8 (#1061)
This avoids propagating -std=c++14 as a compile option

Currently if you use less than CMake 3.8 and you install the project
`-std=c++14` gets added to the INTERFACE_COMPILE_OPTIONS. This forces
users to use C++ 14 or remove the property from the imported target.

The solution is to raise the minimum and use `cxx_std_14`
2022-10-29 12:31:23 -07:00
Eli Boyarski
1e0d0446dd
README.md: fixed a typo (#1062) 2022-10-24 13:34:44 -07:00
jpr42
c52bad36aa
CMake cleanup (#1060)
- Move all install logic inside gsl_install.cmake
  - This makes reading the logic easier, and avoids the enable language
    issue with `GNUInstallDirs` by having it included after the project
    call
- Have all functions inside gsl_functions.cmake
- Use CMake idiom PROJECT_IS_TOP_LEVEL
- Update README.md
2022-10-18 11:05:09 -07:00
dmitrykobets-msft
991fa6682e
Prevent inefficient copying when using not_null::get (#1059)
Closes issue #550, which highlighted overhead in not_null::get for larger types such as shared_ptr. Every call to get would return a copy of the contained value.
This PR implements Herb's suggestion for changing the return type of not_null::get. The not_null's value will now only be copied if it is "trivially copyable"; otherwise, it will be returned by const reference.
Note: this change also forces the returned copy to be const.
2022-10-11 16:49:16 -07:00
Herb Sutter
7d49d4b45d
Clean up final_act and finally, closes #846 (#977)
Somewhere along the way, GSL's implementation of final_act and finally seems to have become way overthought. This PR is to re-simplify these facilities back to what C++ Core Guidelines C.30 said which is simple and clear and works. It just copies the invocable thing, and doesn't bother trying to optimize the copy. This should be fine, because we're typically passing something that's cheap to copy, often a stateless lambda.

The problem in #846 appears to be because finally looks like was originally written as a const&/&& overload (its state at the time that issue was opened)... to eliminate a copy when you invoke it with a temporary. If so, then the && was probably never intended to be a forwarder, but an rvalue reference that tripped over the horrid C++ syntax collision where a && parameter magically instead means a forwarding reference because the type happens to be a template parameter type here. So I suspect the original author was just trying to write an rvalue overload, and the forwarder that's there now was never intended at all.
2022-10-10 16:09:21 -07:00
Rose
849f7ceaf7
Fix Clang-tidy 15 warnings (#1058)
These warnings were found by running clang-tidy 15.
2022-10-06 09:44:39 -07:00
dmitrykobets-msft
1683d87a3f
Fix NDK version in Android CI (#1054)
This PR future-proofs the fix made in #1053, which is now outdated due to further updates to the NDK version in the Azure VMs used as part of the CI.
2022-09-27 17:04:21 -07:00
Werner Henze
10df83d292
solve span compile problem with gcc 5.5.0 (#1052)
GCC 4.8.0 - 7.0 has a bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480) involving specialization in a namespace enclosing the specialized template. This PR fixes an appearance of this bug in the span header.
2022-08-18 12:28:11 -07:00
dmitrykobets-msft
2e94541fcf
Use updated NDK version in android test suite (#1053)
https://github.com/actions/runner-images/issues/5930 recently updated the NDK version, resulting in test breakages. Update the version.
2022-08-17 12:40:45 -07:00
dmitrykobets-msft
330583f478
Resolve MSVC warning C5260 (#1049)
* Test solution

* Mark dynamic_extent as inline, compiler-version-permitting
2022-07-18 17:42:21 -07:00
microsoft-github-policy-service[bot]
d9fc52e20e
Microsoft mandatory file (#1047)
Co-authored-by: microsoft-github-policy-service[bot] <77245923+microsoft-github-policy-service[bot]@users.noreply.github.com>
2022-05-23 15:27:04 -07:00
dmitrykobets-msft
da01eb28db
Remove useless runtime checks in span implementation (#1029)
Both checks for Expects(ExtentType::size() != dynamic_extent); in storage_type are always useless. storage_type<ExtentType> is only ever created with ExtentType == extent_type<Extent>, where Extent has type std::size_t and is the extent of the span.

Looking at extent_type<std::size_t Ext>::size():

- if Ext != dynamic_extent, then size() always returns Ext, and therefore size() != dynamic_extent
- if Ext == dynamic_extent, then size() returns extent_type<dynamic_extent>::size_. size_ can only be set via one of two constructors:
  - constexpr explicit extent_type(size_type size), which already does the check in question
  - constexpr explicit extent_type(extent_type<Other> ext) : size_(ext.size()), which simply relies on the other extent's size() method
So there is no way for ExtentType::size() == dynamic_extent.
2022-04-28 14:58:25 -07:00
dmitrykobets-msft
d8c493c89f
Suppress es.46 warning in implementation of gsl::narrow (#1046)
As per the CoreGuidelines, gsl::narrow is defined in terms of static_cast.
Suppress es.46, which suggests converting the static_cast into gsl::narrow
2022-04-28 09:49:38 -07:00
dmitrykobets-msft
7fefaaf2c8
Fix reason for including assert inside gsl/narrow (#1045) 2022-04-28 09:49:10 -07:00
Juan Carlos Arevalo Baeza
f21f29d210
gsl/narrow should include <exception> (#1044)
This file uses std::exception, so it should include the appropriate header.

Normally it gets the STL's <exception> header included via the gsl/assert file, but this is skipped with _HAS_EXCEPTIONS=0. I understand _HAS_EXCEPTIONS is undocumented and unsupported, but regardless, the appropriate header should be included here.

Alternatively, gsl/narrow should be modified to support _HAS_EXCEPTIONS=0, like gsl/assert was. But I'm not proposing that change. <exception> does define std::exception even with _HAS_EXCEPTIONS=0.
2022-04-26 14:41:10 -07:00
dmitrykobets-msft
2bfd495080
Suppress -Wfloat-equal warning in implementation of gsl::narrow (#1043)
In the implementation of gsl::narrow, there is a comparison `static_cast<U>(t) != u` which may be comparing two floats.
The comparison here is done purposefully to categorize ill effects of narrowing conversion, since the values being compared *should* be the same when compared with `operator==`. 
Note, using #pragma GCC will suppress this warning for both GCC and Clang.
2022-04-14 11:08:28 -07:00
dmitrykobets-msft
383723676c
Make gsl::span's iterators use the contiguous_iterator concept (#1035)
Resolves #1016

Co-authored-by: Casey Carter <Casey@Carter.net>
2022-03-22 13:20:54 -07:00
dmitrykobets-msft
f22f524aa2
Suppress reserved identifier warning (#1041)
The following reserved identifiers are being used specifically to target certain MSVC constructs, so suppress the warning in VS 2022 (LLVM) "... is reserved because it starts with '_' followed by a capital letter":
- _Unchecked_type
- _Verify_range
- _Verify_offset
- _Unwrapped
- _Unwrap_when_unverified
- _Seek_to
- _Unchecked_begin
- _Unchecked_end
2022-03-22 12:24:23 -07:00
Werner Henze
4377f6e603
quoted form of #include when GSL includes GSL files (#1030)
[SF.12: Prefer the quoted form of #include for files relative to the including file and the angle bracket form everywhere else](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rs-incform)

Additionally changed #include order in `span` so that all `span_ext` is in the GSL include block and not in the STL include block.

Fixes issues #1025.

Co-authored-by: Werner Henze <w.henze@avm.de>
2022-01-31 13:06:42 -08:00
51 changed files with 2819 additions and 2997 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
include/gsl/* linguist-language=C++

29
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,29 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'Status: Open, Type: Bug'
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
```c++
#include <gsl>
// your repro here: ...
```
**Expected behavior**
A clear and concise description of what you expected to happen.
**Spec (please complete the following information):**
- OS: [e.g. Windows]
- Compiler: [e.g. MSVC]
- C++ Version: [e.g. C++20]
**Additional context**
Add any other context about the problem here.

View File

@ -1,4 +1,9 @@
name: CI_Android
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
on:
push:
branches: [ main ]
@ -7,39 +12,43 @@ on:
jobs:
Android:
runs-on: macos-latest
runs-on: macos-latest-large
defaults:
run:
working-directory: build
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Create build directory
run: mkdir -p build
working-directory: .
- name: Start emulator
- uses: actions/setup-java@v4
with:
java-version: 8
distribution: zulu
- name: Start Emulator
run: |
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;android-24;default;x86_64'
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd -n xamarin_android_emulator -k 'system-images;android-24;default;x86_64' --force
$ANDROID_HOME/emulator/emulator -list-avds
echo "Starting emulator"
# Start emulator in background
nohup $ANDROID_HOME/emulator/emulator -avd xamarin_android_emulator -no-snapshot > /dev/null 2>&1 &
echo "Emulator starting"
echo "Starting emulator..."
nohup $ANDROID_HOME/emulator/emulator -no-audio -no-snapshot -avd xamarin_android_emulator &> /dev/null &
echo "Emulator starting in background"
- name: Configure
run: cmake -Werror=dev -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=16 -DANDROID_ABI=x86_64 -DCMAKE_BUILD_TYPE=Debug ..
run: cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=16 -DANDROID_ABI=x86_64 -DCMAKE_BUILD_TYPE=Debug ..
- name: Build
run: cmake --build . --parallel
- name: Wait for emulator ready
timeout-minutes: 2
run: |
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 10; done; input keyevent 82'
$ANDROID_HOME/platform-tools/adb devices
$ANDROID_HOME/platform-tools/adb shell getprop ro.product.cpu.abi
echo "Emulator started"
- name: Deploy tests
run: |

56
.github/workflows/cmake/action.yml vendored Normal file
View File

@ -0,0 +1,56 @@
name: Composite CMake
inputs:
cmake_generator:
required: false
type: string
default: 'Unix Makefiles'
cmake_build_type:
required: true
type: string
default: ''
cmake_cxx_compiler:
required: false
type: string
gsl_cxx_standard:
required: true
type: number
extra_cmake_args:
required: false
type: string
default: ''
build_cmd:
required: true
type: string
default: 'make'
test_cmd:
required: false
type: string
default: 'make test'
shell:
required: false
type: string
default: 'bash'
runs:
using: composite
steps:
- name: Create build directory
run: mkdir build
shell: ${{ inputs.shell }}
- name: Configure CMake
working-directory: build
run: cmake -G "${{ inputs.cmake_generator }}" -DCMAKE_BUILD_TYPE=${{ inputs.cmake_build_type }} -DCMAKE_CXX_COMPILER=${{ inputs.cmake_cxx_compiler }} -DGSL_CXX_STANDARD=${{ inputs.gsl_cxx_standard }} -DCI_TESTING:BOOL=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -Werror=dev ${{ inputs.extra_cmake_args }} ..
shell: ${{ inputs.shell }}
- name: Build
working-directory: build
run: ${{ inputs.build_cmd }}
shell: ${{ inputs.shell }}
- name: Test
working-directory: build
run: ${{ inputs.test_cmd }}
shell: ${{ inputs.shell }}

View File

@ -0,0 +1,25 @@
name: cmake_find_package
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
cmake-find-package:
name: Build ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, macos-latest ]
steps:
- uses: actions/checkout@v4
- uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.14.0
- name: Configure GSL
run: cmake -S . -B build -G "Ninja" -D GSL_TEST=OFF -D CMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/build/install
- name: Install GSL
run: cmake --build build --target install
- name: Test GSL find_package support
run: cmake -S tests/ -B build/tests_find_package -G "Ninja" -D CMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/build/install -D CMAKE_BUILD_TYPE=Release

115
.github/workflows/compilers.yml vendored Normal file
View File

@ -0,0 +1,115 @@
name: Compiler Integration Tests
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
# These jobs are correlated with the officially supported compilers
# and toolsets. If you change any versions, please update README.md.
jobs:
gcc:
strategy:
matrix:
gcc_version: [ 12, 13, 14 ]
build_type: [ Debug, Release ]
cxx_version: [ 14, 17, 20, 23 ]
exclude:
# https://github.com/google/googletest/issues/4232
# Looks like GoogleTest is not interested in making version 1.14
# work with gcc-12.
- gcc_version: 12
cxx_version: 20
- gcc_version: 12
cxx_version: 23
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run CMake (configure, build, test)
uses: ./.github/workflows/cmake
with:
cmake_build_type: ${{ matrix.build_type }}
cmake_cxx_compiler: g++-${{ matrix.gcc_version }}
gsl_cxx_standard: ${{ matrix.cxx_version }}
clang:
strategy:
matrix:
clang_version: [ 16, 17, 18 ]
build_type: [ Debug, Release ]
cxx_version: [ 14, 17, 20, 23 ]
exclude:
# https://github.com/llvm/llvm-project/issues/93734
# Looks like clang fixed this issue in clang-18, but won't backport
# the fix.
- clang_version: 17
cxx_version: 23
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run CMake (configure, build, test)
uses: ./.github/workflows/cmake
with:
cmake_build_type: ${{ matrix.build_type }}
cmake_cxx_compiler: clang++-${{ matrix.clang_version }}
gsl_cxx_standard: ${{ matrix.cxx_version }}
xcode:
strategy:
matrix:
xcode_version: [ '15.4' ]
build_type: [ Debug, Release ]
cxx_version: [ 14, 17, 20, 23 ]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: select xcode version
run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode_version }}.app
- name: Run CMake (configure, build, test)
uses: ./.github/workflows/cmake
with:
cmake_build_type: ${{ matrix.build_type }}
cmake_cxx_compiler: clang++
gsl_cxx_standard: ${{ matrix.cxx_version }}
VisualStudio:
strategy:
matrix:
generator: [ 'Visual Studio 16 2019', 'Visual Studio 17 2022' ]
image: [ windows-2019, windows-2022 ]
build_type: [ Debug, Release ]
extra_args: [ '', '-T ClangCL' ]
cxx_version: [ 14, 17, 20, 23 ]
exclude:
- generator: 'Visual Studio 17 2022'
image: windows-2019
- generator: 'Visual Studio 16 2019'
image: windows-2022
- generator: 'Visual Studio 16 2019'
cxx_version: 23
runs-on: ${{ matrix.image }}
steps:
- uses: actions/checkout@v4
- uses: microsoft/setup-msbuild@v2
- name: Run CMake (configure, build, test)
uses: ./.github/workflows/cmake
with:
cmake_generator: ${{ matrix.generator }}
cmake_build_type: ${{ matrix.build_type }}
gsl_cxx_standard: ${{ matrix.cxx_version }}
extra_cmake_args: ${{ matrix.extra_args }}
build_cmd: msbuild GSL.sln
test_cmd: ctest . --output-on-failure --no-compress-output
shell: pwsh

View File

@ -12,7 +12,7 @@ jobs:
run:
working-directory: build
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Create build directory
run: mkdir -p build

View File

@ -1,61 +1,48 @@
cmake_minimum_required(VERSION 3.1.3...3.16)
cmake_minimum_required(VERSION 3.14...3.16)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
include(guidelineSupportLibrary)
project(GSL VERSION 4.2.0 LANGUAGES CXX)
project(GSL
VERSION 4.0.0
LANGUAGES CXX
)
# Must include after the project call due to GNUInstallDirs requiring a language be enabled (IE. CXX)
include(GNUInstallDirs)
# Creates a library GSL which is an interface (header files only)
add_library(GSL INTERFACE)
# NOTE: If you want to use GSL prefer to link against GSL using this alias target
# EX:
# target_link_libraries(foobar PRIVATE Microsoft.GSL::GSL)
#
# Add Microsoft.GSL::GSL alias for GSL so that dependents can be agnostic about
# whether GSL was added via `add_subdirectory` or `find_package`
add_library(Microsoft.GSL::GSL ALIAS GSL)
# Determine whether this is a standalone project or included by other projects
set(GSL_STANDALONE_PROJECT OFF)
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(GSL_STANDALONE_PROJECT ON)
endif()
# https://cmake.org/cmake/help/latest/variable/PROJECT_IS_TOP_LEVEL.html
string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_TOP_LEVEL)
### Project options
option(GSL_INSTALL "Generate and install GSL target" ${GSL_STANDALONE_PROJECT})
option(GSL_TEST "Build and perform GSL tests" ${GSL_STANDALONE_PROJECT})
option(GSL_INSTALL "Generate and install GSL target" ${PROJECT_IS_TOP_LEVEL})
option(GSL_TEST "Build and perform GSL tests" ${PROJECT_IS_TOP_LEVEL})
# This GSL implementation generally assumes a platform that implements C++14 support.
set(gsl_min_cxx_standard "14")
if (GSL_STANDALONE_PROJECT)
gsl_set_default_cxx_standard(${gsl_min_cxx_standard})
else()
gsl_client_set_cxx_standard(${gsl_min_cxx_standard})
endif()
# The implementation generally assumes a platform that implements C++14 support
target_compile_features(GSL INTERFACE "cxx_std_14")
# Setup include directory
add_subdirectory(include)
# Add natvis file
gsl_add_native_visualizer_support()
# Add packaging support
gsl_create_packaging_file()
if (GSL_INSTALL)
# Setup install/export logic
gsl_install_logic()
endif()
target_sources(GSL INTERFACE $<BUILD_INTERFACE:${GSL_SOURCE_DIR}/GSL.natvis>)
if (GSL_TEST)
enable_testing()
add_subdirectory(tests)
endif()
if (GSL_INSTALL)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/gsl" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
set(export_name "Microsoft.GSLConfig")
set(namespace "Microsoft.GSL::")
set(cmake_files_install_dir ${CMAKE_INSTALL_DATADIR}/cmake/Microsoft.GSL)
install(TARGETS GSL EXPORT ${export_name} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT ${export_name} NAMESPACE ${namespace} DESTINATION ${cmake_files_install_dir})
export(TARGETS GSL NAMESPACE ${namespace} FILE ${export_name}.cmake)
set(gls_config_version "${CMAKE_CURRENT_BINARY_DIR}/Microsoft.GSLConfigVersion.cmake")
write_basic_package_version_file(${gls_config_version} COMPATIBILITY SameMajorVersion ARCH_INDEPENDENT)
install(FILES ${gls_config_version} DESTINATION ${cmake_files_install_dir})
install(FILES GSL.natvis DESTINATION ${cmake_files_install_dir})
endif()

View File

@ -4,13 +4,7 @@
vim: syntax=xml
-->
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<!-- These types are from the gsl_assert header. -->
<Type Name="gsl::fail_fast">
<!-- na hides the address, otherwise it would appear as 0x.... "Message" -->
<DisplayString>{_Data._What,nasb}</DisplayString>
</Type>
<!-- These types are from the gsl_util header. -->
<!-- These types are from the util header. -->
<Type Name="gsl::final_action&lt;*&gt;">
<DisplayString>{{ invoke = {invoke_}, action = {f_} }}</DisplayString>
<Expand>
@ -19,7 +13,8 @@
</Expand>
</Type>
<Type Name="gsl::span&lt;*, *&gt;">
<!-- These types are from the span header. -->
<Type Name="gsl::span&lt;*, *&gt;">
<DisplayString>{{ extent = {storage_.size_} }}</DisplayString>
<Expand>
<ArrayItems>
@ -29,29 +24,7 @@
</Expand>
</Type>
<Type Name="gsl::basic_string_span&lt;*, *&gt;">
<DisplayString>{span_.storage_.data_,[span_.storage_.size_]na}</DisplayString>
<Expand>
<Item Name="[size]">span_.storage_.size_</Item>
<ArrayItems>
<Size>span_.storage_.size_</Size>
<ValuePointer>span_.storage_.data_</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="gsl::basic_zstring_span&lt;*, *&gt;">
<DisplayString>{span_.storage_.data_,[span_.storage_.size_]na}</DisplayString>
<Expand>
<Item Name="[size]">span_.storage_.size_</Item>
<ArrayItems>
<Size>span_.storage_.size_</Size>
<ValuePointer>span_.storage_.data_</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<!-- These types are from the gsl header. -->
<!-- These types are from the pointers header. -->
<Type Name="gsl::not_null&lt;*&gt;">
<!-- We can always dereference this since it's an invariant. -->
<DisplayString>value = {*ptr_}</DisplayString>

161
README.md
View File

@ -1,5 +1,6 @@
# GSL: Guidelines Support Library
[![Build Status](https://dev.azure.com/cppstat/GSL/_apis/build/status/microsoft.GSL?branchName=main)](https://dev.azure.com/cppstat/GSL/_build/latest?definitionId=1&branchName=main)
[![CI](https://github.com/Microsoft/GSL/actions/workflows/compilers.yml/badge.svg)](https://github.com/microsoft/GSL/actions/workflows/compilers.yml?query=branch%3Amain)
[![vcpkg](https://img.shields.io/vcpkg/v/ms-gsl)](https://vcpkg.io/en/package/ms-gsl)
The Guidelines Support Library (GSL) contains functions and types that are suggested for use by the
[C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines) maintained by the [Standard C++ Foundation](https://isocpp.org).
@ -22,59 +23,63 @@ This project makes use of the [Google Test](https://github.com/google/googletest
# Supported features
## Microsoft GSL implements the following from the C++ Core Guidelines:
Feature | Supported? | Description
-----------------------------------|:----------:|-------------
[**1. Views**][cg-views] | |
owner | &#x2611; | an alias for a raw pointer
not_null | &#x2611; | restricts a pointer / smart pointer to hold non-null values
span | &#x2611; | a view over a contiguous sequence of memory. Based on the standardized verison of `std::span`, however `gsl::span` enforces bounds checking. See the [wiki](https://github.com/microsoft/GSL/wiki/gsl::span-and-std::span) for additional information.
span_p | &#x2610; | spans a range starting from a pointer to the first place for which the predicate is true
basic_zstring | &#x2611; | A pointer to a C-string (zero-terminated array) with a templated char type
zstring | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of char
czstring | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of const char
wzstring | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of wchar_t
cwzstring | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of const wchar_t
u16zstring | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of char16_t
cu16zstring | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of const char16_t
u32zstring | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of char32_t
cu32zstring | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of const char32_t
[**2. Owners**][cg-owners] | |
unique_ptr | &#x2611; | an alias to `std::unique_ptr`
shared_ptr | &#x2611; | an alias to `std::shared_ptr`
stack_array | &#x2610; | a stack-allocated array
dyn_array | &#x2610; | a heap-allocated array
[**3. Assertions**][cg-assertions] | |
Expects | &#x2611; | a precondition assertion; on failure it terminates
Ensures | &#x2611; | a postcondition assertion; on failure it terminates
[**4. Utilities**][cg-utilities] | |
move_owner | &#x2610; | a helper function that moves one `owner` to the other
byte | &#x2611; | either an alias to std::byte or a byte type
final_action | &#x2611; | a RAII style class that invokes a functor on its destruction
finally | &#x2611; | a helper function instantiating `final_action`
GSL_SUPPRESS | &#x2611; | a macro that takes an argument and turns it into `[[gsl::suppress(x)]]` or `[[gsl::suppress("x")]]`
[[implicit]] | &#x2610; | a "marker" to put on single-argument constructors to explicitly make them non-explicit
index | &#x2611; | a type to use for all container and array indexing (currently an alias for std::ptrdiff_t)
joining_thread | &#x2610; | a RAII style version of `std::thread` that joins
narrow | &#x2611; | a checked version of narrow_cast; it can throw `narrowing_error`
narrow_cast | &#x2611; | a narrowing cast for values and a synonym for static_cast
narrowing_error | &#x2611; | a custom exception type thrown by `narrow()`
[**5. Concepts**][cg-concepts] | &#x2610; |
Feature | Supported? | Description
-------------------------------------------------------------------------|:----------:|-------------
[**1. Views**][cg-views] | |
[owner](docs/headers.md#user-content-H-pointers-owner) | &#x2611; | An alias for a raw pointer
[not_null](docs/headers.md#user-content-H-pointers-not_null) | &#x2611; | Restricts a pointer/smart pointer to hold non-null values
[span](docs/headers.md#user-content-H-span-span) | &#x2611; | A view over a contiguous sequence of memory. Based on the standardized version of `std::span`, however `gsl::span` enforces bounds checking.
span_p | &#x2610; | Spans a range starting from a pointer to the first place for which the predicate is true
[basic_zstring](docs/headers.md#user-content-H-zstring) | &#x2611; | A pointer to a C-string (zero-terminated array) with a templated char type
[zstring](docs/headers.md#user-content-H-zstring) | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of `char`
[czstring](docs/headers.md#user-content-H-zstring) | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of `const char`
[wzstring](docs/headers.md#user-content-H-zstring) | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of `wchar_t`
[cwzstring](docs/headers.md#user-content-H-zstring) | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of `const wchar_t`
[u16zstring](docs/headers.md#user-content-H-zstring) | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of `char16_t`
[cu16zstring](docs/headers.md#user-content-H-zstring) | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of `const char16_t`
[u32zstring](docs/headers.md#user-content-H-zstring) | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of `char32_t`
[cu32zstring](docs/headers.md#user-content-H-zstring) | &#x2611; | An alias to `basic_zstring` with dynamic extent and a char type of `const char32_t`
[**2. Owners**][cg-owners] | |
stack_array | &#x2610; | A stack-allocated array
dyn_array | &#x2610; | A heap-allocated array
[**3. Assertions**][cg-assertions] | |
[Expects](docs/headers.md#user-content-H-assert-expects) | &#x2611; | A precondition assertion; on failure it terminates
[Ensures](docs/headers.md#user-content-H-assert-ensures) | &#x2611; | A postcondition assertion; on failure it terminates
[**4. Utilities**][cg-utilities] | |
move_owner | &#x2610; | A helper function that moves one `owner` to the other
[final_action](docs/headers.md#user-content-H-util-final_action) | &#x2611; | A RAII style class that invokes a functor on its destruction
[finally](docs/headers.md#user-content-H-util-finally) | &#x2611; | A helper function instantiating [final_action](docs/headers.md#user-content-H-util-final_action)
[GSL_SUPPRESS](docs/headers.md#user-content-H-assert-gsl_suppress) | &#x2611; | A macro that takes an argument and turns it into `[[gsl::suppress(x)]]` or `[[gsl::suppress("x")]]`
[[implicit]] | &#x2610; | A "marker" to put on single-argument constructors to explicitly make them non-explicit
[index](docs/headers.md#user-content-H-util-index) | &#x2611; | A type to use for all container and array indexing (currently an alias for `std::ptrdiff_t`)
[narrow](docs/headers.md#user-content-H-narrow-narrow) | &#x2611; | A checked version of `narrow_cast`; it can throw [narrowing_error](docs/headers.md#user-content-H-narrow-narrowing_error)
[narrow_cast](docs/headers.md#user-content-H-util-narrow_cast) | &#x2611; | A narrowing cast for values and a synonym for `static_cast`
[narrowing_error](docs/headers.md#user-content-H-narrow-narrowing_error) | &#x2611; | A custom exception type thrown by [narrow](docs/headers.md#user-content-H-narrow-narrow)
[**5. Concepts**][cg-concepts] | &#x2610; |
## The following features do not exist in or have been removed from the C++ Core Guidelines:
Feature | Supported? | Description
-----------------------------------|:----------:|-------------
strict_not_null | &#x2611; | A stricter version of `not_null` with explicit constructors
[strict_not_null](docs/headers.md#user-content-H-pointers-strict_not_null) | &#x2611; | A stricter version of [not_null](docs/headers.md#user-content-H-pointers-not_null) with explicit constructors
multi_span | &#x2610; | Deprecated. Multi-dimensional span.
strided_span | &#x2610; | Deprecated. Support for this type has been discontinued.
basic_string_span | &#x2610; | Deprecated. Like `span` but for strings with a templated char type
string_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of char
cstring_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of const char
wstring_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of wchar_t
cwstring_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of const wchar_t
u16string_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of char16_t
cu16string_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of const char16_t
u32string_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of char32_t
cu32string_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of const char32_t
string_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of `char`
cstring_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of `const char`
wstring_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of `wchar_t`
cwstring_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of `const wchar_t`
u16string_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of `char16_t`
cu16string_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of `const char16_t`
u32string_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of `char32_t`
cu32string_span | &#x2610; | Deprecated. An alias to `basic_string_span` with a char type of `const char32_t`
## The following features have been adopted by WG21. They are deprecated in GSL.
Feature | Deprecated Since | Notes
------------------------------------------------------------------|------------------|------
[unique_ptr](docs/headers.md#user-content-H-pointers-unique_ptr) | C++11 | Use std::unique_ptr instead.
[shared_ptr](docs/headers.md#user-content-H-pointers-shared_ptr) | C++11 | Use std::shared_ptr instead.
[byte](docs/headers.md#user-content-H-byte-byte) | C++17 | Use std::byte instead.
joining_thread | C++20 (Note: Not yet implemented in GSL) | Use std::jthread instead.
This is based on [CppCoreGuidelines semi-specification](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#gsl-guidelines-support-library).
@ -86,24 +91,17 @@ This is based on [CppCoreGuidelines semi-specification](https://github.com/isocp
# 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.
The GSL officially supports recent major versions of Visual Studio with both MSVC and LLVM, GCC, Clang, and XCode with Apple-Clang.
For each of these major versions, the GSL officially supports C++14, C++17, C++20, and C++23 (when supported by the compiler).
Below is a table showing the versions currently being tested (also see [.github/workflows/compilers.yml](the workflow).)
Compiler |Toolset Versions Currently Tested
:------- |--:
XCode | 13.2.1 & 12.5.1
GCC | 11[^1] & 10[^2]
Clang | 12[^2] & 11[^2]
Visual Studio with MSVC | VS2022[^3] & VS2019[^4]
Visual Studio with LLVM | VS2022[^3] & VS2019[^4]
[^1]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26).
[^2]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26). Should be the version specified [here](https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-Readme.md#language-and-runtime).
[^3]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26). Should be the version specified [here](https://github.com/actions/virtual-environments/blob/main/images/win/Windows2022-Readme.md#visual-studio-enterprise-2022).
[^4]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26). Should be the version specified [here](https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md#visual-studio-enterprise-2019).
GCC | 12, 13, 14
XCode | 14.3.1, 15.4
Clang | 16, 17, 18
Visual Studio with MSVC | VS2019, VS2022
Visual Studio with LLVM | VS2019, VS2022
---
If you successfully port GSL to another platform, we would love to hear from you!
@ -113,19 +111,19 @@ If you successfully port GSL to another platform, we would love to hear from you
Target | CI/CD Status
:------- | -----------:
iOS | ![CI_iOS](https://github.com/microsoft/GSL/workflows/CI_iOS/badge.svg)
Android | ![CI_Android](https://github.com/microsoft/GSL/workflows/CI_Android/badge.svg)
iOS | [![CI_iOS](https://github.com/microsoft/GSL/workflows/CI_iOS/badge.svg?branch=main)](https://github.com/microsoft/GSL/actions/workflows/ios.yml?query=branch%3Amain)
Android | [![CI_Android](https://github.com/microsoft/GSL/workflows/CI_Android/badge.svg?branch=main)](https://github.com/microsoft/GSL/actions/workflows/android.yml?query=branch%3Amain)
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](http://cmake.org), version 3.1.3 (3.2.3 for AppleClang) or later to be installed and in your PATH.
* [CMake](http://cmake.org), 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).
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
@ -179,43 +177,44 @@ Include the library using:
## Usage in CMake
The library provides a Config file for CMake, once installed it can be found via
find_package(Microsoft.GSL CONFIG)
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.
```cmake
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 offical FetchContent module.
If you are using CMake version 3.11+ you can use the official [FetchContent module](https://cmake.org/cmake/help/latest/module/FetchContent.html).
This allows you to easily incorporate GSL into your project.
```cmake
# NOTE: This example uses cmake version 3.14 (FetchContent_MakeAvailable).
# NOTE: This example uses CMake version 3.14 (FetchContent_MakeAvailable).
# Since it streamlines the FetchContent process
cmake_minimum_required(VERSION 3.14)
include(FetchContent)
# In this example we are picking a specific tag.
# You can also pick a specific commit, if you need to.
FetchContent_Declare(GSL
GIT_REPOSITORY "https://github.com/microsoft/GSL"
GIT_TAG "v3.1.0"
GIT_TAG "v4.2.0"
GIT_SHALLOW ON
)
FetchContent_MakeAvailable(GSL)
# Now you can link against the GSL interface library
add_executable(foobar)
# Link against the interface library (IE header only library)
target_link_libraries(foobar PRIVATE GSL)
target_link_libraries(foobar PRIVATE Microsoft.GSL::GSL)
```
## Debugging visualization support
For Visual Studio users, the file [GSL.natvis](./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.
If you are using cmake this will be done automatically for you.
See 'GSL_VS_ADD_NATIVE_VISUALIZERS'
## See Also
For information on [Microsoft Gray Systems Lab (GSL)](https://aka.ms/gsl) of applied data management and system research see <https://aka.ms/gsl>.

41
SECURITY.md Normal file
View File

@ -0,0 +1,41 @@
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->
## Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
## Reporting Security Issues
**Please do not report security vulnerabilities through public GitHub issues.**
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
This information will help us triage your report more quickly.
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
## Preferred Languages
We prefer all communications to be in English.
## Policy
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
<!-- END MICROSOFT SECURITY.MD BLOCK -->

View File

@ -1,66 +0,0 @@
trigger:
- main
pr:
autoCancel: true
stages:
- stage: GCC
dependsOn: []
jobs:
- template: ./pipelines/jobs.yml
parameters:
compiler: gcc
image: ubuntu-20.04
compilerVersions: [ 11, 10 ]
setupfile: 'setup_gcc.yml'
- stage: Clang
dependsOn: []
jobs:
- template: ./pipelines/jobs.yml
parameters:
compiler: clang
image: ubuntu-20.04
compilerVersions: [ 12, 11 ]
setupfile: 'setup_clang.yml'
- stage: Xcode
dependsOn: []
jobs:
- template: ./pipelines/jobs.yml
parameters:
compiler: 'Xcode'
image: macOS-11
compilerVersions: [ '12.5.1', '13.2.1' ]
setupfile: 'setup_apple.yml'
- stage: VS_MSVC
dependsOn: []
jobs:
- template: ./pipelines/jobs.yml
parameters:
compiler: 'VS2019 (MSVC)'
compilerVersions: [ 'default' ]
image: windows-2019
- template: ./pipelines/jobs.yml
parameters:
compiler: 'VS2022 (MSVC)'
compilerVersions: [ 'default' ]
image: windows-2022
- stage: VS_LLVM
dependsOn: []
jobs:
- template: ./pipelines/jobs.yml
parameters:
compiler: 'VS2019 (LLVM)'
compilerVersions: [ 'default' ]
image: windows-2019
extraCmakeArgs: '-T ClangCL'
- template: ./pipelines/jobs.yml
parameters:
compiler: 'VS2022 (LLVM)'
compilerVersions: [ 'default' ]
image: windows-2022
extraCmakeArgs: '-T ClangCL'

View File

@ -1,116 +0,0 @@
# This cmake module is meant to hold helper functions/macros
# that make maintaining the cmake build system much easier.
# This is especially helpful since gsl needs to provide coverage
# for multiple versions of cmake.
#
# Any functions/macros should have a gsl_* prefix to avoid problems
if (CMAKE_VERSION VERSION_GREATER 3.10 OR CMAKE_VERSION VERSION_EQUAL 3.10)
include_guard()
else()
if (DEFINED guideline_support_library_include_guard)
return()
endif()
set(guideline_support_library_include_guard ON)
endif()
# Necessary for 'write_basic_package_version_file'
include(CMakePackageConfigHelpers)
function(gsl_set_default_cxx_standard min_cxx_standard)
set(GSL_CXX_STANDARD "${min_cxx_standard}" CACHE STRING "Use c++ standard")
set(GSL_CXX_STD "cxx_std_${GSL_CXX_STANDARD}")
if (MSVC)
set(GSL_CXX_STD_OPT "-std:c++${GSL_CXX_STANDARD}")
else()
set(GSL_CXX_STD_OPT "-std=c++${GSL_CXX_STANDARD}")
endif()
# when minimum version required is 3.8.0 remove if below
# both branches do exactly the same thing
if (CMAKE_VERSION VERSION_LESS 3.7.9)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("${GSL_CXX_STD_OPT}" COMPILER_SUPPORTS_CXX_STANDARD)
if(COMPILER_SUPPORTS_CXX_STANDARD)
target_compile_options(GSL INTERFACE "${GSL_CXX_STD_OPT}")
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no c++${GSL_CXX_STANDARD} support. Please use a different C++ compiler.")
endif()
else()
target_compile_features(GSL INTERFACE "${GSL_CXX_STD}")
# on *nix systems force the use of -std=c++XX instead of -std=gnu++XX (default)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
endfunction()
# The best way for a project to specify the GSL's C++ standard is by the client specifying
# the CMAKE_CXX_STANDARD. However, this isn't always ideal. Since the CMAKE_CXX_STANDARD is
# tied to the cmake version. And many projects have low cmake minimums.
#
# So provide an alternative approach in case that doesn't work.
function(gsl_client_set_cxx_standard min_cxx_standard)
if (DEFINED CMAKE_CXX_STANDARD)
if (${CMAKE_CXX_STANDARD} VERSION_LESS ${min_cxx_standard})
message(FATAL_ERROR "GSL: Requires at least CXX standard ${min_cxx_standard}, user provided ${CMAKE_CXX_STANDARD}")
endif()
# Set the GSL standard to what the client desires
set(GSL_CXX_STANDARD "${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
# Exit out early to avoid extra unneccessary work
return()
endif()
# Otherwise pick a reasonable default
gsl_set_default_cxx_standard(${min_cxx_standard})
endfunction()
# Adding the GSL.natvis files improves the debugging experience for users of this library.
function(gsl_add_native_visualizer_support)
if (CMAKE_VERSION VERSION_GREATER 3.7.8)
if (MSVC_IDE)
option(GSL_VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE)
else()
set(GSL_VS_ADD_NATIVE_VISUALIZERS FALSE CACHE INTERNAL "Native visualizers are Visual Studio extension" FORCE)
endif()
# add natvis file to the library so it will automatically be loaded into Visual Studio
if(GSL_VS_ADD_NATIVE_VISUALIZERS)
target_sources(GSL INTERFACE $<BUILD_INTERFACE:${GSL_SOURCE_DIR}/GSL.natvis>)
endif()
endif()
endfunction()
function(gsl_install_logic)
install(TARGETS GSL EXPORT Microsoft.GSLConfig)
install(
DIRECTORY include/gsl
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
# Make library importable by other projects
install(EXPORT Microsoft.GSLConfig NAMESPACE Microsoft.GSL:: DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/Microsoft.GSL)
export(TARGETS GSL NAMESPACE Microsoft.GSL:: FILE Microsoft.GSLConfig.cmake)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Microsoft.GSLConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/Microsoft.GSL)
endfunction()
# Add find_package() versioning support. The version for
# generated Microsoft.GSLConfigVersion.cmake will be used from
# last project() command. The version's compatibility is set between all
# minor versions (as it was in prev. GSL releases).
function(gsl_create_packaging_file)
if(${CMAKE_VERSION} VERSION_LESS "3.14.0")
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/Microsoft.GSLConfigVersion.cmake
COMPATIBILITY SameMajorVersion
)
else()
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/Microsoft.GSLConfigVersion.cmake
COMPATIBILITY SameMajorVersion
ARCH_INDEPENDENT
)
endif()
endfunction()

884
docs/headers.md Normal file
View File

@ -0,0 +1,884 @@
The Guidelines Support Library (GSL) interface is very lightweight and exposed via a header-only library. This document attempts to document all of the headers and their exposed classes and functions.
Types and functions are exported in the namespace `gsl`.
See [GSL: Guidelines support library](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#S-gsl)
# <a name="H" />Headers
- [`<algorithms>`](#user-content-H-algorithms)
- [`<assert>`](#user-content-H-assert)
- [`<byte>`](#user-content-H-byte)
- [`<gsl>`](#user-content-H-gsl)
- [`<narrow>`](#user-content-H-narrow)
- [`<pointers>`](#user-content-H-pointers)
- [`<span>`](#user-content-H-span)
- [`<span_ext>`](#user-content-H-span_ext)
- [`<zstring>`](#user-content-H-zstring)
- [`<util>`](#user-content-H-util)
## <a name="H-algorithms" />`<algorithms>`
This header contains some common algorithms that have been wrapped in GSL safety features.
- [`gsl::copy`](#user-content-H-algorithms-copy)
### <a name="H-algorithms-copy" />`gsl::copy`
```cpp
template <class SrcElementType, std::size_t SrcExtent, class DestElementType,
std::size_t DestExtent>
void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest);
```
This function copies the content from the `src` [`span`](#user-content-H-span-span) to the `dest` [`span`](#user-content-H-span-span). It [`Expects`](#user-content-H-assert-expects)
that the destination `span` is at least as large as the source `span`.
## <a name="H-assert" />`<assert>`
This header contains some macros used for contract checking and suppressing code analysis warnings.
See [GSL.assert: Assertions](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#SS-assertions)
- [`GSL_SUPPRESS`](#user-content-H-assert-gsl_suppress)
- [`Expects`](#user-content-H-assert-expects)
- [`Ensures`](#user-content-H-assert-ensures)
### <a name="H-assert-gsl_suppress" />`GSL_SUPPRESS`
This macro can be used to suppress a code analysis warning.
The core guidelines request tools that check for the rules to respect suppressing a rule by writing
`[[gsl::suppress(tag)]]` or `[[gsl::suppress(tag, justification: "message")]]`.
Clang does not use exactly that syntax, but requires `tag` to be put in double quotes `[[gsl::suppress("tag")]]`.
For portable code you can use `GSL_SUPPRESS(tag)`.
See [In.force: Enforcement](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#inforce-enforcement).
### <a name="H-assert-expects" />`Expects`
This macro can be used for expressing a precondition. If the precondition is not held, then `std::terminate` will be called.
See [I.6: Prefer `Expects()` for expressing preconditions](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#i6-prefer-expects-for-expressing-preconditions)
### <a name="H-assert-ensures" />`Ensures`
This macro can be used for expressing a postcondition. If the postcondition is not held, then `std::terminate` will be called.
See [I.8: Prefer `Ensures()` for expressing postconditions](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#i8-prefer-ensures-for-expressing-postconditions)
## <a name="H-byte" />`<byte>`
This header contains the definition of a byte type, implementing `std::byte` before it was standardized into C++17.
- [`gsl::byte`](#user-content-H-byte-byte)
### <a name="H-byte-byte" />`gsl::byte`
If `GSL_USE_STD_BYTE` is defined to be `1`, then `gsl::byte` will be an alias to `std::byte`.
If `GSL_USE_STD_BYTE` is defined to be `0`, then `gsl::byte` will be a distinct type that implements the concept of byte.
If `GSL_USE_STD_BYTE` is not defined, then the header file will check if `std::byte` is available (C\+\+17 or higher). If yes,
`gsl::byte` will be an alias to `std::byte`, otherwise `gsl::byte` will be a distinct type that implements the concept of byte.
&#x26a0; Take care when linking projects that were compiled with different language standards (before C\+\+17 and C\+\+17 or higher).
If you do so, you might want to `#define GSL_USE_STD_BYTE 0` to a fixed value to be sure that both projects use exactly
the same type. Otherwise you might get linker errors.
See [SL.str.5: Use `std::byte` to refer to byte values that do not necessarily represent characters](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rstr-byte)
### Non-member functions
```cpp
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept;
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
constexpr byte operator<<(byte b, IntegerType shift) noexcept;
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept;
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
constexpr byte operator>>(byte b, IntegerType shift) noexcept;
```
Left or right shift a `byte` by a given number of bits.
```cpp
constexpr byte& operator|=(byte& l, byte r) noexcept;
constexpr byte operator|(byte l, byte r) noexcept;
```
Bitwise "or" of two `byte`s.
```cpp
constexpr byte& operator&=(byte& l, byte r) noexcept;
constexpr byte operator&(byte l, byte r) noexcept;
```
Bitwise "and" of two `byte`s.
```cpp
constexpr byte& operator^=(byte& l, byte r) noexcept;
constexpr byte operator^(byte l, byte r) noexcept;
```
Bitwise xor of two `byte`s.
```cpp
constexpr byte operator~(byte b) noexcept;
```
Bitwise negation of a `byte`. Flips all bits. Zeroes become ones, ones become zeroes.
```cpp
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
constexpr IntegerType to_integer(byte b) noexcept;
```
Convert the given `byte` value to an integral type.
```cpp
template <typename T>
constexpr byte to_byte(T t) noexcept;
```
Convert the given value to a `byte`. The template requires `T` to be an `unsigned char` so that no data loss can occur.
If you want to convert an integer constant to a `byte` you probably want to call `to_byte<integer constant>()`.
```cpp
template <int I>
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-gsl" />`<gsl>`
This header is a convenience header that includes all other [GSL headers](#user-content-H).
Since `<narrow>` requires exceptions, it will only be included if exceptions are enabled.
## <a name="H-narrow" />`<narrow>`
This header contains utility functions and classes, for narrowing casts, which require exceptions. The narrowing-related utilities that don't require exceptions are found inside [util](#user-content-H-util).
See [GSL.util: Utilities](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#SS-utilities)
- [`gsl::narrowing_error`](#user-content-H-narrow-narrowing_error)
- [`gsl::narrow`](#user-content-H-narrow-narrow)
### <a name="H-narrow-narrowing_error" />`gsl::narrowing_error`
`gsl::narrowing_error` is the exception thrown by [`gsl::narrow`](#user-content-H-narrow-narrow) when a narrowing conversion fails. It is derived from `std::exception`.
### <a name="H-narrow-narrow" />`gsl::narrow`
`gsl::narrow<T>(x)` is a named cast that does a `static_cast<T>(x)` for narrowing conversions with no signedness promotions.
If the argument `x` cannot be represented in the target type `T`, then the function throws a [`gsl::narrowing_error`](#user-content-H-narrow-narrowing_error) (e.g., `narrow<unsigned>(-42)` and `narrow<char>(300)` throw).
Note: compare [`gsl::narrow_cast`](#user-content-H-util-narrow_cast) in header [util](#user-content-H-util).
See [ES.46: Avoid lossy (narrowing, truncating) arithmetic conversions](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-narrowing) and [ES.49: If you must use a cast, use a named cast](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-casts-named)
## <a name="H-pointers" />`<pointers>`
This header contains some pointer types.
See [GSL.view](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#SS-views)
- [`gsl::unique_ptr`](#user-content-H-pointers-unique_ptr)
- [`gsl::shared_ptr`](#user-content-H-pointers-shared_ptr)
- [`gsl::owner`](#user-content-H-pointers-owner)
- [`gsl::not_null`](#user-content-H-pointers-not_null)
- [`gsl::strict_not_null`](#user-content-H-pointers-strict_not_null)
### <a name="H-pointers-unique_ptr" />`gsl::unique_ptr`
`gsl::unique_ptr` is an alias to `std::unique_ptr`.
See [GSL.owner: Ownership pointers](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#SS-ownership)
### <a name="H-pointers-shared_ptr" />`gsl::shared_ptr`
`gsl::shared_ptr` is an alias to `std::shared_ptr`.
See [GSL.owner: Ownership pointers](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#SS-ownership)
### <a name="H-pointers-owner" />`gsl::owner`
`gsl::owner<T>` is designed as a safety mechanism for code that must deal directly with raw pointers that own memory. Ideally such code should be restricted to the implementation of low-level abstractions. `gsl::owner` can also be used as a stepping point in converting legacy code to use more modern RAII constructs such as smart pointers.
`T` must be a pointer type (`std::is_pointer<T>`).
A `gsl::owner<T>` is a typedef to `T`. It adds no runtime overhead whatsoever, as it is purely syntactic and does not add any runtime checks. Instead, it serves as an annotation for static analysis tools which check for memory safety, and as a code comprehension guide for human readers.
See Enforcement section of [C.31: All resources acquired by a class must be released by the classs destructor](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-dtor-release).
### <a name="H-pointers-not_null" />`gsl::not_null`
`gsl::not_null<T>` restricts a pointer or smart pointer to only hold non-null values. It has no size overhead over `T`.
The checks for ensuring that the pointer is not null are done in the constructor. There is no overhead when retrieving or dereferencing the checked pointer.
When a nullptr check fails, `std::terminate` is called.
See [F.23: Use a `not_null<T>` to indicate that “null” is not a valid value](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-nullptr)
#### Member Types
```cpp
using element_type = T;
```
The type of the pointer or smart pointer that is managed by this object.
#### Member functions
##### Construct/Copy
```cpp
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr not_null(U&& u);
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
constexpr not_null(T u);
```
Constructs a `gsl_owner<T>` from a pointer that is convertible to `T` or that is a `T`. It [`Expects`](#user-content-H-assert-expects) that the provided pointer is not `== nullptr`.
```cpp
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr not_null(const not_null<U>& other);
```
Constructs a `gsl_owner<T>` from another `gsl_owner` where the other pointer is convertible to `T`. It [`Expects`](#user-content-H-assert-expects) that the provided pointer is not `== nullptr`.
```cpp
not_null(const not_null& other) = default;
not_null& operator=(const not_null& other) = default;
```
Copy construction and assignment.
```cpp
not_null(std::nullptr_t) = delete;
not_null& operator=(std::nullptr_t) = delete;
```
Construction from `std::nullptr_t` and assignment of `std::nullptr_t` are explicitly deleted.
##### Modifiers
```cpp
not_null& operator++() = delete;
not_null& operator--() = delete;
not_null operator++(int) = delete;
not_null operator--(int) = delete;
not_null& operator+=(std::ptrdiff_t) = delete;
not_null& operator-=(std::ptrdiff_t) = delete;
```
Explicitly deleted operators. Pointers point to single objects ([I.13: Do not pass an array as a single pointer](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ri-array)), so don't allow these operators.
##### Observers
```cpp
constexpr details::value_or_reference_return_t<T> get() const;
constexpr operator T() const { return get(); }
```
Get the underlying pointer.
```cpp
constexpr decltype(auto) operator->() const { return get(); }
constexpr decltype(auto) operator*() const { return *get(); }
```
Dereference the underlying pointer.
```cpp
void operator[](std::ptrdiff_t) const = delete;
```
Array index operator is explicitly deleted. Pointers point to single objects ([I.13: Do not pass an array as a single pointer](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ri-array)), so don't allow treating them as an array.
```cpp
void swap(not_null<T>& other) { std::swap(ptr_, other.ptr_); }
```
Swaps contents with another `gsl::not_null` object.
#### Non-member functions
```cpp
template <class T>
auto make_not_null(T&& t) noexcept;
```
Creates a `gsl::not_null` object, deducing the target type from the type of the argument.
```cpp
template <typename T, std::enable_if_t<std::is_move_assignable<T>::value && std::is_move_constructible<T>::value, bool> = true>
void swap(not_null<T>& a, not_null<T>& b);
```
Swaps the contents of two `gsl::not_null` objects.
```cpp
template <class T, class U>
auto operator==(const not_null<T>& lhs,
const not_null<U>& rhs) noexcept(noexcept(lhs.get() == rhs.get()))
-> decltype(lhs.get() == rhs.get());
template <class T, class U>
auto operator!=(const not_null<T>& lhs,
const not_null<U>& rhs) noexcept(noexcept(lhs.get() != rhs.get()))
-> decltype(lhs.get() != rhs.get());
template <class T, class U>
auto operator<(const not_null<T>& lhs,
const not_null<U>& rhs) noexcept(noexcept(lhs.get() < rhs.get()))
-> decltype(lhs.get() < rhs.get());
template <class T, class U>
auto operator<=(const not_null<T>& lhs,
const not_null<U>& rhs) noexcept(noexcept(lhs.get() <= rhs.get()))
-> decltype(lhs.get() <= rhs.get());
template <class T, class U>
auto operator>(const not_null<T>& lhs,
const not_null<U>& rhs) noexcept(noexcept(lhs.get() > rhs.get()))
-> decltype(lhs.get() > rhs.get());
template <class T, class U>
auto operator>=(const not_null<T>& lhs,
const not_null<U>& rhs) noexcept(noexcept(lhs.get() >= rhs.get()))
-> decltype(lhs.get() >= rhs.get());
```
Comparison of pointers that are convertible to each other.
##### Input/Output
```cpp
template <class T>
std::ostream& operator<<(std::ostream& os, const not_null<T>& val);
```
Performs stream output on a `not_null` pointer, invoking `os << val.get()`. This function is only available when `GSL_NO_IOSTREAMS` is not defined.
##### Modifiers
```cpp
template <class T, class U>
std::ptrdiff_t operator-(const not_null<T>&, const not_null<U>&) = delete;
template <class T>
not_null<T> operator-(const not_null<T>&, std::ptrdiff_t) = delete;
template <class T>
not_null<T> operator+(const not_null<T>&, std::ptrdiff_t) = delete;
template <class T>
not_null<T> operator+(std::ptrdiff_t, const not_null<T>&) = delete;
```
Addition and subtraction are explicitly deleted. Pointers point to single objects ([I.13: Do not pass an array as a single pointer](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ri-array)), so don't allow these operators.
##### STL integration
```cpp
template <class T>
struct std::hash<gsl::not_null<T>> { ... };
```
Specialization of `std::hash` for `gsl::not_null`.
### <a name="H-pointers-strict_not_null" />`gsl::strict_not_null`
`strict_not_null` is the same as [`not_null`](#user-content-H-pointers-not_null) except that the constructors are `explicit`.
The free function that deduces the target type from the type of the argument and creates a `gsl::strict_not_null` object is `gsl::make_strict_not_null`.
## <a name="H-span" />`<span>`
This header file exports the class `gsl::span`, a bounds-checked implementation of `std::span`.
- [`gsl::span`](#user-content-H-span-span)
### <a name="H-span-span" />`gsl::span`
```cpp
template <class ElementType, std::size_t Extent>
class span;
```
`gsl::span` is a view over memory. It does not own the memory and is only a way to access contiguous sequences of objects.
The extent can be either a fixed size or [`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent).
The `gsl::span` is based on the standardized version of `std::span` which was added to C++20. Originally, the plan was to
deprecate `gsl::span` when `std::span` finished standardization, however that plan changed when the runtime bounds checking
was removed from `std::span`'s design.
The only difference between `gsl::span` and `std::span` is that `gsl::span` strictly enforces runtime bounds checking.
Any violations of the bounds check results in termination of the program.
Like `gsl::span`, `gsl::span`'s iterators also differ from `std::span`'s iterator in that all access operations are bounds checked.
#### Which version of span should I use?
##### Use `gsl::span` if
- you want to guarantee bounds safety in your project.
- All data accessing operations use bounds checking to ensure you are only accessing valid memory.
- your project uses C++14 or C++17.
- `std::span` is not available as it was not introduced into the STL until C++20.
##### Use `std::span` if
- your project is C++20 and you need the performance offered by `std::span`.
#### Types
```cpp
using element_type = ElementType;
using value_type = std::remove_cv_t<ElementType>;
using size_type = std::size_t;
using pointer = element_type*;
using const_pointer = const element_type*;
using reference = element_type&;
using const_reference = const element_type&;
using difference_type = std::ptrdiff_t;
using iterator = details::span_iterator<ElementType>;
using reverse_iterator = std::reverse_iterator<iterator>;
```
#### Member functions
```cpp
constexpr span() noexcept;
```
Constructs an empty `span`. This constructor is only available if `Extent` is 0 or [`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent).
`span::data()` will return `nullptr`.
```cpp
constexpr explicit(Extent != gsl::dynamic_extent) span(pointer ptr, size_type count) noexcept;
```
Constructs a `span` from a pointer and a size. If `Extent` is not [`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent),
then the constructor [`Expects`](#user-content-H-assert-expects) that `count == Extent`.
```cpp
constexpr explicit(Extent != gsl::dynamic_extent) span(pointer firstElem, pointer lastElem) noexcept;
```
Constructs a `span` from a pointer to the begin and the end of the data. If `Extent` is not [`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent),
then the constructor [`Expects`](#user-content-H-assert-expects) that `lastElem - firstElem == Extent`.
```cpp
template <std::size_t N>
constexpr span(element_type (&arr)[N]) noexcept;
```
Constructs a `span` from a C style array. This overload is available if `Extent ==`[`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent)
or `N == Extent`.
```cpp
template <class T, std::size_t N>
constexpr span(std::array<T, N>& arr) noexcept;
template <class T, std::size_t N>
constexpr span(const std::array<T, N>& arr) noexcept;
```
Constructs a `span` from a `std::array`. These overloads are available if `Extent ==`[`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent)
or `N == Extent`, and if the array can be interpreted as a `ElementType` array.
```cpp
template <class Container>
constexpr explicit(Extent != gsl::dynamic_extent) span(Container& cont) noexcept;
template <class Container>
constexpr explicit(Extent != gsl::dynamic_extent) span(const Container& cont) noexcept;
```
Constructs a `span` from a container. These overloads are available if `Extent ==`[`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent)
or `N == Extent`, and if the container can be interpreted as a contiguous `ElementType` array.
```cpp
constexpr span(const span& other) noexcept = default;
```
Copy constructor.
```cpp
template <class OtherElementType, std::size_t OtherExtent>
explicit(Extent != gsl::dynamic_extent && OtherExtent == dynamic_extent)
constexpr span(const span<OtherElementType, OtherExtent>& other) noexcept;
```
Constructs a `span` from another `span`. This constructor is available if `OtherExtent == Extent || Extent ==`[`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent)` || OtherExtent ==`[`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent)
and if `ElementType` and `OtherElementType` are compatible.
If `Extent !=`[`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent) and `OtherExtent ==`[`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent),
then the constructor [`Expects`](#user-content-H-assert-expects) that `other.size() == Extent`.
```cpp
constexpr span& operator=(const span& other) noexcept = default;
```
Copy assignment
```cpp
template <std::size_t Count>
constexpr span<element_type, Count> first() const noexcept;
constexpr span<element_type, dynamic_extent> first(size_type count) const noexcept;
template <std::size_t Count>
constexpr span<element_type, Count> last() const noexcept;
constexpr span<element_type, dynamic_extent> last(size_type count) const noexcept;
```
Return a subspan of the first/last `Count` elements. [`Expects`](#user-content-H-assert-expects) that `Count` does not exceed the `span`'s size.
```cpp
template <std::size_t offset, std::size_t count = dynamic_extent>
constexpr auto subspan() const noexcept;
constexpr span<element_type, dynamic_extent>
subspan(size_type offset, size_type count = dynamic_extent) const noexcept;
```
Return a subspan starting at `offset` and having size `count`. [`Expects`](#user-content-H-assert-expects) that `offset` does not exceed the `span`'s size,
and that `offset == `[`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent) or `offset + count` does not exceed the `span`'s size.
If `count` is `gsl::dynamic_extent`, the number of elements in the subspan is `size() - offset`.
```cpp
constexpr size_type size() const noexcept;
constexpr size_type size_bytes() const noexcept;
```
Returns the size respective the size in bytes of the `span`.
```cpp
constexpr bool empty() const noexcept;
```
Is the `span` empty?
```cpp
constexpr reference operator[](size_type idx) const noexcept;
```
Returns a reference to the element at the given index. [`Expects`](#user-content-H-assert-expects) that `idx` is less than the `span`'s size.
```cpp
constexpr reference front() const noexcept;
constexpr reference back() const noexcept;
```
Returns a reference to the first/last element in the `span`. [`Expects`](#user-content-H-assert-expects) that the `span` is not empty.
```cpp
constexpr pointer data() const noexcept;
```
Returns a pointer to the beginning of the contained data.
```cpp
constexpr iterator begin() const noexcept;
constexpr iterator end() const noexcept;
constexpr reverse_iterator rbegin() const noexcept;
constexpr reverse_iterator rend() const noexcept;
```
Returns an iterator to the first/last normal/reverse iterator.
```cpp
template <class Type, std::size_t Extent>
span(Type (&)[Extent]) -> span<Type, Extent>;
template <class Type, std::size_t Size>
span(std::array<Type, Size>&) -> span<Type, Size>;
template <class Type, std::size_t Size>
span(const std::array<Type, Size>&) -> span<const Type, Size>;
template <class Container,
class Element = std::remove_pointer_t<decltype(std::declval<Container&>().data())>>
span(Container&) -> span<Element>;
template <class Container,
class Element = std::remove_pointer_t<decltype(std::declval<const Container&>().data())>>
span(const Container&) -> span<Element>;
```
Deduction guides.
```cpp
template <class ElementType, std::size_t Extent>
span<const byte, details::calculate_byte_size<ElementType, Extent>::value>
as_bytes(span<ElementType, Extent> s) noexcept;
template <class ElementType, std::size_t Extent>
span<byte, details::calculate_byte_size<ElementType, Extent>::value>
as_writable_bytes(span<ElementType, Extent> s) noexcept;
```
Converts a `span` into a `span` of `byte`s.
`as_writable_bytes` will only be available for non-const `ElementType`s.
## <a name="H-span_ext" />`<span_ext>`
This file is a companion for and included by [`<gsl/span>`](#user-content-H-span), and should not be used on its own. It contains useful features that aren't part of the `std::span` API as found inside the STL `<span>` header (with the exception of [`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent), which is included here due to implementation constraints).
- [`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent)
- [`gsl::span`](#user-content-H-span_ext-span)
- [`gsl::span` comparison operators](#user-content-H-span_ext-span_comparison_operators)
- [`gsl::make_span`](#user-content-H-span_ext-make_span)
- [`gsl::at`](#user-content-H-span_ext-at)
- [`gsl::ssize`](#user-content-H-span_ext-ssize)
- [`gsl::span` iterator functions](#user-content-H-span_ext-span_iterator_functions)
### <a name="H-span_ext-dynamic_extent" />`gsl::dynamic_extent`
Defines the extent value to be used by all `gsl::span` with dynamic extent.
Note: `std::dynamic_extent` is exposed by the STL `<span>` header and so ideally `gsl::dynamic_extent` would be under [`<gsl/span>`](#user-content-H-span), but to avoid cyclic dependency issues it is under `<span_ext>` instead.
### <a name="H-span_ext-span" />`gsl::span`
```cpp
template <class ElementType, std::size_t Extent = dynamic_extent>
class span;
```
Forward declaration of `gsl::span`.
### <a name="H-span_ext-span_comparison_operators" />`gsl::span` comparison operators
```cpp
template <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent>
constexpr bool operator==(span<ElementType, FirstExtent> l, span<ElementType, SecondExtent> r);
template <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent>
constexpr bool operator!=(span<ElementType, FirstExtent> l, span<ElementType, SecondExtent> r);
template <class ElementType, std::size_t Extent>
constexpr bool operator<(span<ElementType, Extent> l, span<ElementType, Extent> r);
template <class ElementType, std::size_t Extent>
constexpr bool operator<=(span<ElementType, Extent> l, span<ElementType, Extent> r);
template <class ElementType, std::size_t Extent>
constexpr bool operator>(span<ElementType, Extent> l, span<ElementType, Extent> r);
template <class ElementType, std::size_t Extent>
constexpr bool operator>=(span<ElementType, Extent> l, span<ElementType, Extent> r);
```
The comparison operators for two `span`s lexicographically compare the elements in the `span`s.
### <a name="H-span_ext-make_span" />`gsl::make_span`
```cpp
template <class ElementType>
constexpr span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::size_type count);
template <class ElementType>
constexpr span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem);
template <class ElementType, std::size_t N>
constexpr span<ElementType, N> make_span(ElementType (&arr)[N]) noexcept;
template <class Container>
constexpr span<typename Container::value_type> make_span(Container& cont);
template <class Container>
constexpr span<const typename Container::value_type> make_span(const Container& cont);
```
Utility function for creating a `span` with [`gsl::dynamic_extent`](#user-content-H-span_ext-dynamic_extent) from
- pointer and length,
- pointer to start and pointer to end,
- a C style array, or
- a container.
### <a name="H-span_ext-at" />`gsl::at`
```cpp
template <class ElementType, std::size_t Extent>
constexpr ElementType& at(span<ElementType, Extent> s, index i);
```
The function `gsl::at` offers a safe way to access data with index bounds checking.
This is the specialization of [`gsl::at`](#user-content-H-util-at) for [`span`](#user-content-H-span-span). It returns a reference to the `i`th element and
[`Expects`](#user-content-H-assert-expects) that the provided index is within the bounds of the `span`.
Note: `gsl::at` supports indexes up to `PTRDIFF_MAX`.
### <a name="H-span_ext-ssize" />`gsl::ssize`
```cpp
template <class ElementType, std::size_t Extent>
constexpr std::ptrdiff_t ssize(const span<ElementType, Extent>& s) noexcept;
```
Return the size of a [`span`](#user-content-H-span-span) as a `ptrdiff_t`.
### <a name="H-span_ext-span_iterator_functions" />`gsl::span` iterator functions
```cpp
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::iterator
begin(const span<ElementType, Extent>& s) noexcept;
template <class ElementType, std::size_t Extent = dynamic_extent>
constexpr typename span<ElementType, Extent>::iterator
end(const span<ElementType, Extent>& s) noexcept;
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::reverse_iterator
rbegin(const span<ElementType, Extent>& s) noexcept;
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::reverse_iterator
rend(const span<ElementType, Extent>& s) noexcept;
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::iterator
cbegin(const span<ElementType, Extent>& s) noexcept;
template <class ElementType, std::size_t Extent = dynamic_extent>
constexpr typename span<ElementType, Extent>::iterator
cend(const span<ElementType, Extent>& s) noexcept;
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::reverse_iterator
crbegin(const span<ElementType, Extent>& s) noexcept;
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::reverse_iterator
crend(const span<ElementType, Extent>& s) noexcept;
```
Free functions for getting a non-const/const begin/end normal/reverse iterator for a [`span`](#user-content-H-span-span).
## <a name="H-zstring" />`<zstring>`
This header exports a family of `*zstring` types.
A `gsl::XXzstring<T>` is a typedef to `T`. It adds no checks whatsoever, it is just for having a syntax to describe
that a pointer points to a zero terminated C style string. This helps static code analysis, and it helps human readers.
`basic_zstring` is a pointer to a C-string (zero-terminated array) with a templated char type. Used to implement the rest of the `*zstring` family.
`zstring` is a zero terminated `char` string.
`czstring` is a const zero terminated `char` string.
`wzstring` is a zero terminated `wchar_t` string.
`cwzstring` is a const zero terminated `wchar_t` string.
`u16zstring` is a zero terminated `char16_t` string.
`cu16zstring` is a const zero terminated `char16_t` string.
`u32zstring` is a zero terminated `char32_t` string.
`cu32zstring` is a const zero terminated `char32_t` string.
See [GSL.view](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#SS-views) and [SL.str.3: Use zstring or czstring to refer to a C-style, zero-terminated, sequence of characters](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rstr-zstring).
## <a name="H-util" />`<util>`
This header contains utility functions and classes. This header works without exceptions being available. The parts that require
exceptions being available are in their own header file [narrow](#user-content-H-narrow).
See [GSL.util: Utilities](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#SS-utilities)
- [`gsl::narrow_cast`](#user-content-H-util-narrow_cast)
- [`gsl::final_action`](#user-content-H-util-final_action)
- [`gsl::at`](#user-content-H-util-at)
### <a name="H-util-index" />`gsl::index`
An alias to `std::ptrdiff_t`. It serves as the index type for all container indexes/subscripts/sizes.
### <a name="H-util-narrow_cast" />`gsl::narrow_cast`
`gsl::narrow_cast<T>(x)` is a named cast that is identical to a `static_cast<T>(x)`. It exists to make clear to static code analysis tools and to human readers that a lossy conversion is acceptable.
Note: compare the throwing version [`gsl::narrow`](#user-content-H-narrow-narrow) in header [narrow](#user-content-H-narrow).
See [ES.46: Avoid lossy (narrowing, truncating) arithmetic conversions](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-narrowing) and [ES.49: If you must use a cast, use a named cast](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-casts-named)
### <a name="H-util-final_action" />`gsl::final_action`
```cpp
template <class F>
class final_action { ... };
```
`final_action` allows you to ensure something gets run at the end of a scope.
See [E.19: Use a final_action object to express cleanup if no suitable resource handle is available](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Re-finally)
#### Member functions
```cpp
explicit final_action(const F& ff) noexcept;
explicit final_action(F&& ff) noexcept;
```
Construct an object with the action to invoke in the destructor.
```cpp
~final_action() noexcept;
```
The destructor will call the action that was passed in the constructor.
```cpp
final_action(final_action&& other) noexcept;
final_action(const final_action&) = delete;
void operator=(const final_action&) = delete;
void operator=(final_action&&) = delete;
```
Move construction is allowed. Copy construction is deleted. Copy and move assignment are also explicitly deleted.
#### <a name="H-util-finally" />Non-member functions
```cpp
template <class F>
auto finally(F&& f) noexcept;
```
Creates a `gsl::final_action` object, deducing the template argument type from the type of the argument.
### <a name="H-util-at" />`gsl::at`
The function `gsl::at` offers a safe way to access data with index bounds checking.
Note: `gsl::at` supports indexes up to `PTRDIFF_MAX`.
See [ES.42: Keep use of pointers simple and straightforward](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-ptr)
```cpp
template <class T, std::size_t N>
constexpr T& at(T (&arr)[N], const index i);
```
This overload returns a reference to the `i`s element of a C style array `arr`. It [`Expects`](#user-content-H-assert-expects) that the provided index is within the bounds of the array.
```cpp
template <class Cont>
constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()]);
```
This overload returns a reference to the `i`s element of the container `cont`. It [`Expects`](#user-content-H-assert-expects) that the provided index is within the bounds of the array.
```cpp
template <class T>
constexpr T at(const std::initializer_list<T> cont, const index i);
```
This overload returns a reference to the `i`s element of the initializer list `cont`. It [`Expects`](#user-content-H-assert-expects) that the provided index is within the bounds of the array.
```cpp
template <class T, std::size_t extent = std::dynamic_extent>
constexpr auto at(std::span<T, extent> sp, const index i) -> decltype(sp[sp.size()]);
```
This overload returns a reference to the `i`s element of the `std::span` `sp`. It [`Expects`](#user-content-H-assert-expects) that the provided index is within the bounds of the array.
For [`gsl::at`](#user-content-H-span_ext-at) for [`gsl::span`](#user-content-H-span-span) see header [`span_ext`](#user-content-H-span_ext).
```cpp
template <class T, std::enable_if_t<std::is_move_assignable<T>::value && std::is_move_constructible<T>::value>>
void swap(T& a, T& b);
```
Swaps the contents of two objects. Exists only to specialize `gsl::swap<T>(gsl::not_null<T>&, gsl::not_null<T>&)`.

View File

@ -1,4 +1,3 @@
# Add include folders to the library and targets that consume it
# the SYSTEM keyword suppresses warnings for users of the library
#
@ -7,14 +6,8 @@
#
# IE:
# #include <gsl/gsl>
if(GSL_STANDALONE_PROJECT)
target_include_directories(GSL INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
if(PROJECT_IS_TOP_LEVEL)
target_include_directories(GSL INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
else()
target_include_directories(GSL SYSTEM INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_include_directories(GSL SYSTEM INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
endif()

View File

@ -17,8 +17,8 @@
#ifndef GSL_ALGORITHM_H
#define GSL_ALGORITHM_H
#include <gsl/assert> // for Expects
#include <gsl/span> // for dynamic_extent, span
#include "./assert" // for Expects
#include "./span" // for dynamic_extent, span
#include <algorithm> // for copy_n
#include <cstddef> // for ptrdiff_t

View File

@ -14,8 +14,8 @@
//
///////////////////////////////////////////////////////////////////////////////
#ifndef GSL_CONTRACTS_H
#define GSL_CONTRACTS_H
#ifndef GSL_ASSERT_H
#define GSL_ASSERT_H
//
// Temporary until MSVC STL supports no-exceptions mode.
@ -46,18 +46,15 @@
// Hopefully temporary until suppression standardization occurs
//
#if defined(__clang__)
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]]
#define GSL_SUPPRESS(x) [[gsl::suppress(#x)]]
#else
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__NVCC__)
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
#else
#define GSL_SUPPRESS(x)
#endif // _MSC_VER
#endif // __clang__
#define GSL_STRINGIFY_DETAIL(x) #x
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
#if defined(__clang__) || defined(__GNUC__)
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
@ -133,4 +130,4 @@ namespace details
#pragma clang diagnostic pop
#endif
#endif // GSL_CONTRACTS_H
#endif // GSL_ASSERT_H

View File

@ -17,24 +17,10 @@
#ifndef GSL_BYTE_H
#define GSL_BYTE_H
//
// make suppress attributes work for some compilers
// Hopefully temporary until suppression standardization occurs
//
#if defined(__clang__)
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]]
#else
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
#else
#define GSL_SUPPRESS(x)
#endif // _MSC_VER
#endif // __clang__
#include "./util" // for GSL_DEPRECATED
#include <type_traits>
// VS2017 15.8 added support for the __cpp_lib_byte definition
// To do: drop _HAS_STD_BYTE when support for pre 15.8 expires
#ifdef _MSC_VER
#pragma warning(push)
@ -45,18 +31,15 @@
#ifndef GSL_USE_STD_BYTE
// this tests if we are under MSVC and the standard lib has std::byte and it is enabled
#if (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || \
(defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603)
#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603
#define GSL_USE_STD_BYTE 1
#else // (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >=
// 201603)
#else // defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603
#define GSL_USE_STD_BYTE 0
#endif // (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >=
// 201603)
#endif // defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603
#endif // GSL_USE_STD_BYTE
#else // _MSC_VER
@ -99,7 +82,14 @@ namespace gsl
{
#if GSL_USE_STD_BYTE
using std::byte;
namespace impl {
// impl::byte is used by gsl::as_bytes so our own code does not trigger a deprecation warning as would be the case when we used gsl::byte.
// Users of GSL should only use gsl::byte, not gsl::impl::byte.
using byte = std::byte;
}
using byte GSL_DEPRECATED("Use std::byte instead.") = std::byte;
using std::to_integer;
#else // GSL_USE_STD_BYTE
@ -110,25 +100,31 @@ enum class byte_may_alias byte : unsigned char
{
};
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
namespace impl {
// impl::byte is used by gsl::as_bytes so our own code does not trigger a deprecation warning as would be the case when we used gsl::byte.
// Users of GSL should only use gsl::byte, not gsl::impl::byte.
using byte = gsl::byte;
}
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept
{
return b = byte(static_cast<unsigned char>(b) << shift);
}
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
constexpr byte operator<<(byte b, IntegerType shift) noexcept
{
return byte(static_cast<unsigned char>(b) << shift);
}
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept
{
return b = byte(static_cast<unsigned char>(b) >> shift);
}
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
constexpr byte operator>>(byte b, IntegerType shift) noexcept
{
return byte(static_cast<unsigned char>(b) >> shift);
@ -166,7 +162,7 @@ constexpr byte operator^(byte l, byte r) noexcept
constexpr byte operator~(byte b) noexcept { return byte(~static_cast<unsigned char>(b)); }
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
constexpr IntegerType to_integer(byte b) noexcept
{
return static_cast<IntegerType>(b);
@ -174,34 +170,24 @@ constexpr IntegerType to_integer(byte b) noexcept
#endif // GSL_USE_STD_BYTE
template <bool E, typename T>
constexpr byte to_byte_impl(T t) noexcept
{
static_assert(
E, "gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. "
"If you are calling to_byte with an integer contant use: gsl::to_byte<t>() version.");
return static_cast<byte>(t);
}
template <>
// NOTE: need suppression since c++14 does not allow "return {t}"
// GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: suppression does not work
constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept
{
return byte(t);
}
template <typename T>
constexpr byte to_byte(T t) noexcept
// NOTE: need suppression since c++14 does not allow "return {t}"
// GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: suppression does not work
constexpr gsl::impl::byte to_byte(T t) noexcept
{
return to_byte_impl<std::is_same<T, unsigned char>::value, T>(t);
static_assert(std::is_same<T, unsigned char>::value,
"gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. "
"If you are calling to_byte with an integer constant use: gsl::to_byte<t>() version.");
return gsl::impl::byte(t);
}
template <int I>
constexpr byte to_byte() noexcept
constexpr gsl::impl::byte to_byte() noexcept
{
static_assert(I >= 0 && I <= 255,
"gsl::byte only has 8 bits of storage, values must be in range 0-255");
return static_cast<byte>(I);
return static_cast<gsl::impl::byte>(I);
}
} // namespace gsl

View File

@ -17,16 +17,18 @@
#ifndef GSL_GSL_H
#define GSL_GSL_H
#include <gsl/algorithm> // copy
#include <gsl/assert> // Ensures/Expects
#include <gsl/byte> // byte
#include <gsl/pointers> // owner, not_null
#include <gsl/span> // span
#include <gsl/string_span> // zstring, string_span, zstring_builder...
#include <gsl/util> // finally()/narrow_cast()...
// IWYU pragma: begin_exports
#include "./algorithm" // copy
#include "./assert" // Ensures/Expects
#include "./byte" // byte
#include "./pointers" // owner, not_null
#include "./span" // span
#include "./zstring" // zstring
#include "./util" // finally()/narrow_cast()...
#ifdef __cpp_exceptions
#include <gsl/narrow> // narrow()
#include "./narrow" // narrow()
#endif
// IWYU pragma: end_exports
#endif // GSL_GSL_H

View File

@ -1,4 +0,0 @@
#pragma once
#pragma message( \
"This header will soon be removed. Use <gsl/algorithm> instead of <gsl/gsl_algorithm>")
#include <gsl/algorithm>

View File

@ -1,3 +0,0 @@
#pragma once
#pragma message("This header will soon be removed. Use <gsl/assert> instead of <gsl/gsl_assert>")
#include <gsl/assert>

View File

@ -1,3 +0,0 @@
#pragma once
#pragma message("This header will soon be removed. Use <gsl/byte> instead of <gsl/gsl_byte>")
#include <gsl/byte>

View File

@ -1,3 +0,0 @@
#pragma once
#pragma message("This header will soon be removed. Use <gsl/narrow> instead of <gsl/gsl_narrow>")
#include <gsl/narrow>

View File

@ -1,3 +0,0 @@
#pragma once
#pragma message("This header will soon be removed. Use <gsl/util> instead of <gsl/gsl_util>")
#include <gsl/util>

View File

@ -16,8 +16,9 @@
#ifndef GSL_NARROW_H
#define GSL_NARROW_H
#include <gsl/assert> // for Expects
#include <gsl/util> // for narrow_cast
#include "./assert" // for GSL_SUPPRESS
#include "./util" // for narrow_cast
#include <exception> // for std::exception
namespace gsl
{
struct narrowing_error : public std::exception
@ -29,9 +30,12 @@ struct narrowing_error : public std::exception
template <class T, class U, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
// clang-format off
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
GSL_SUPPRESS(es.46) // NO-FORMAT: attribute // The warning suggests that a floating->unsigned conversion can occur
// in the static_cast below, and that gsl::narrow should be used instead.
// Suppress this warning, since gsl::narrow is defined in terms of
// static_cast
// clang-format on
constexpr T narrow(U u) noexcept(false)
constexpr T narrow(U u)
{
constexpr const bool is_different_signedness =
(std::is_signed<T>::value != std::is_signed<U>::value);
@ -43,10 +47,18 @@ GSL_SUPPRESS(p.2) // NO-FORMAT: attribute // don't rely on undefined behavior
// and cannot fit into the destination integral type), the resultant behavior is benign on the platforms
// that we target (i.e., no hardware trap representations are hit).
#if defined(__clang__) || defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// Note: NaN will always throw, since NaN != NaN
if (static_cast<U>(t) != u || (is_different_signedness && ((t < T{}) != (u < U{}))))
{
throw narrowing_error{};
}
#if defined(__clang__) || defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
return t;
}
@ -54,9 +66,8 @@ GSL_SUPPRESS(p.2) // NO-FORMAT: attribute // don't rely on undefined behavior
template <class T, class U, typename std::enable_if<!std::is_arithmetic<T>::value>::type* = nullptr>
// clang-format off
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
// clang-format on
constexpr T narrow(U u) noexcept(false)
constexpr T narrow(U u)
{
const T t = narrow_cast<T>(u);

View File

@ -17,13 +17,14 @@
#ifndef GSL_POINTERS_H
#define GSL_POINTERS_H
#include <gsl/assert> // for Ensures, Expects
#include "./assert" // for Ensures, Expects
#include "./util" // for GSL_DEPRECATED
#include <algorithm> // for forward
#include <cstddef> // for ptrdiff_t, nullptr_t, size_t
#include <memory> // for shared_ptr, unique_ptr
#include <system_error> // for hash
#include <functional> // for less, greater
#include <memory> // for shared_ptr, unique_ptr, hash
#include <type_traits> // for enable_if_t, is_convertible, is_assignable
#include <utility> // for declval, forward
#if !defined(GSL_NO_IOSTREAMS)
#include <iosfwd> // for ostream
@ -46,24 +47,39 @@ namespace details
: std::true_type
{
};
// Resolves to the more efficient of `const T` or `const T&`, in the context of returning a const-qualified value
// of type T.
//
// Copied from cppfront's implementation of the CppCoreGuidelines F.16 (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-in)
template<typename T>
using value_or_reference_return_t = std::conditional_t<
sizeof(T) < 2*sizeof(void*) && std::is_trivially_copy_constructible<T>::value,
const T,
const T&>;
} // namespace details
//
// GSL.owner: ownership pointers
//
using std::shared_ptr;
using std::unique_ptr;
template <typename... Ts>
using shared_ptr GSL_DEPRECATED("Use std::shared_ptr instead") = std::shared_ptr<Ts...>;
template <typename... Ts>
using unique_ptr GSL_DEPRECATED("Use std::unique_ptr instead") = std::unique_ptr<Ts...>;
//
// owner
//
// owner<T> is designed as a bridge for code that must deal directly with owning pointers for some
// reason
// `gsl::owner<T>` is designed as a safety mechanism for code that must deal directly with raw pointers that own memory.
// Ideally such code should be restricted to the implementation of low-level abstractions. `gsl::owner` can also be used
// as a stepping point in converting legacy code to use more modern RAII constructs, such as smart pointers.
//
// T must be a pointer type
// - disallow construction from any type other than pointer type
//
template <class T, class = std::enable_if_t<std::is_pointer<T>::value>>
template <class T, std::enable_if_t<std::is_pointer<T>::value, bool> = true>
using owner = T;
//
@ -86,27 +102,29 @@ class not_null
public:
static_assert(details::is_comparable_to_nullptr<T>::value, "T cannot be compared to nullptr.");
using element_type = T;
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr not_null(U&& u) : ptr_(std::forward<U>(u))
constexpr not_null(U&& u) noexcept(std::is_nothrow_move_constructible<T>::value) : ptr_(std::forward<U>(u))
{
Expects(ptr_ != nullptr);
}
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
constexpr not_null(T u) : ptr_(std::move(u))
constexpr not_null(T u) noexcept(std::is_nothrow_move_constructible<T>::value) : ptr_(std::move(u))
{
Expects(ptr_ != nullptr);
}
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr not_null(const not_null<U>& other) : not_null(other.get())
constexpr not_null(const not_null<U>& other) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null(other.get())
{}
not_null(const not_null& other) = default;
not_null& operator=(const not_null& other) = default;
constexpr std::conditional_t<std::is_copy_constructible<T>::value, T, const T&> get() const
constexpr details::value_or_reference_return_t<T> get() const
noexcept(noexcept(details::value_or_reference_return_t<T>(std::declval<T&>())))
{
Ensures(ptr_ != nullptr);
return ptr_;
}
@ -127,10 +145,18 @@ public:
not_null& operator-=(std::ptrdiff_t) = delete;
void operator[](std::ptrdiff_t) const = delete;
void swap(not_null<T>& other) { std::swap(ptr_, other.ptr_); }
private:
T ptr_;
};
template <typename T, std::enable_if_t<std::is_move_assignable<T>::value && std::is_move_constructible<T>::value, bool> = true>
void swap(not_null<T>& a, not_null<T>& b)
{
a.swap(b);
}
template <class T>
auto make_not_null(T&& t) noexcept
{
@ -164,34 +190,34 @@ auto operator!=(const not_null<T>& lhs,
template <class T, class U>
auto operator<(const not_null<T>& lhs,
const not_null<U>& rhs) noexcept(noexcept(lhs.get() < rhs.get()))
-> decltype(lhs.get() < rhs.get())
const not_null<U>& rhs) noexcept(noexcept(std::less<>{}(lhs.get(), rhs.get())))
-> decltype(std::less<>{}(lhs.get(), rhs.get()))
{
return lhs.get() < rhs.get();
return std::less<>{}(lhs.get(), rhs.get());
}
template <class T, class U>
auto operator<=(const not_null<T>& lhs,
const not_null<U>& rhs) noexcept(noexcept(lhs.get() <= rhs.get()))
-> decltype(lhs.get() <= rhs.get())
const not_null<U>& rhs) noexcept(noexcept(std::less_equal<>{}(lhs.get(), rhs.get())))
-> decltype(std::less_equal<>{}(lhs.get(), rhs.get()))
{
return lhs.get() <= rhs.get();
return std::less_equal<>{}(lhs.get(), rhs.get());
}
template <class T, class U>
auto operator>(const not_null<T>& lhs,
const not_null<U>& rhs) noexcept(noexcept(lhs.get() > rhs.get()))
-> decltype(lhs.get() > rhs.get())
const not_null<U>& rhs) noexcept(noexcept(std::greater<>{}(lhs.get(), rhs.get())))
-> decltype(std::greater<>{}(lhs.get(), rhs.get()))
{
return lhs.get() > rhs.get();
return std::greater<>{}(lhs.get(), rhs.get());
}
template <class T, class U>
auto operator>=(const not_null<T>& lhs,
const not_null<U>& rhs) noexcept(noexcept(lhs.get() >= rhs.get()))
-> decltype(lhs.get() >= rhs.get())
const not_null<U>& rhs) noexcept(noexcept(std::greater_equal<>{}(lhs.get(), rhs.get())))
-> decltype(std::greater_equal<>{}(lhs.get(), rhs.get()))
{
return lhs.get() >= rhs.get();
return std::greater_equal<>{}(lhs.get(), rhs.get());
}
// more unwanted operators
@ -204,14 +230,28 @@ not_null<T> operator+(const not_null<T>&, std::ptrdiff_t) = delete;
template <class T>
not_null<T> operator+(std::ptrdiff_t, const not_null<T>&) = delete;
template <class T, class U = decltype(std::declval<const T&>().get()), bool = std::is_default_constructible<std::hash<U>>::value>
struct not_null_hash
{
std::size_t operator()(const T& value) const { return std::hash<U>{}(value.get()); }
};
template <class T, class U>
struct not_null_hash<T, U, false>
{
not_null_hash() = delete;
not_null_hash(const not_null_hash&) = delete;
not_null_hash& operator=(const not_null_hash&) = delete;
};
} // namespace gsl
namespace std
{
template <class T>
struct hash<gsl::not_null<T>>
struct hash<gsl::not_null<T>> : gsl::not_null_hash<gsl::not_null<T>>
{
std::size_t operator()(const gsl::not_null<T>& value) const { return hash<T>{}(value.get()); }
};
} // namespace std
@ -241,22 +281,24 @@ class strict_not_null : public not_null<T>
{
public:
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr explicit strict_not_null(U&& u) : not_null<T>(std::forward<U>(u))
constexpr explicit strict_not_null(U&& u) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null<T>(std::forward<U>(u))
{}
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
constexpr explicit strict_not_null(T u) : not_null<T>(u)
constexpr explicit strict_not_null(T u) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null<T>(std::move(u))
{}
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr strict_not_null(const not_null<U>& other) : not_null<T>(other)
constexpr strict_not_null(const not_null<U>& other) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null<T>(other)
{}
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr strict_not_null(const strict_not_null<U>& other) : not_null<T>(other)
constexpr strict_not_null(const strict_not_null<U>& other) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null<T>(other)
{}
strict_not_null(strict_not_null&& other) = default;
// To avoid invalidating the "not null" invariant, the contained pointer is actually copied
// instead of moved. If it is a custom pointer, its constructor could in theory throw exceptions.
strict_not_null(strict_not_null&& other) noexcept(std::is_nothrow_copy_constructible<T>::value) = default;
strict_not_null(const strict_not_null& other) = default;
strict_not_null& operator=(const strict_not_null& other) = default;
strict_not_null& operator=(const not_null<T>& other)
@ -310,12 +352,8 @@ strict_not_null(T) -> strict_not_null<T>;
namespace std
{
template <class T>
struct hash<gsl::strict_not_null<T>>
struct hash<gsl::strict_not_null<T>> : gsl::not_null_hash<gsl::strict_not_null<T>>
{
std::size_t operator()(const gsl::strict_not_null<T>& value) const
{
return hash<T>{}(value.get());
}
};
} // namespace std

View File

@ -17,15 +17,20 @@
#ifndef GSL_SPAN_H
#define GSL_SPAN_H
#include <gsl/assert> // for Expects
#include <gsl/byte> // for byte
#include <gsl/util> // for narrow_cast
#include "./assert" // for Expects
#include "./byte" // for gsl::impl::byte
#include "./span_ext" // for span specialization of gsl::at and other span-related extensions
#include "./util" // for narrow_cast
#include <array> // for array
#include <cstddef> // for ptrdiff_t, size_t, nullptr_t
#include <gsl/span_ext> // for span specialization of gsl::at and other span-related extensions
#include <iterator> // for reverse_iterator, distance, random_access_...
#include <type_traits> // for enable_if_t, declval, is_convertible, inte...
#include <array> // for array
#include <cstddef> // for ptrdiff_t, size_t, nullptr_t
#include <iterator> // for reverse_iterator, distance, random_access_...
#include <memory> // for pointer_traits
#include <type_traits> // for enable_if_t, declval, is_convertible, inte...
#if defined(__has_include) && __has_include(<version>)
#include <version>
#endif
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
@ -37,7 +42,7 @@
#pragma warning(disable : 4702) // unreachable code
// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool.
#pragma warning(disable : 26495) // uninitalized member when constructor calls constructor
#pragma warning(disable : 26495) // uninitialized member when constructor calls constructor
#pragma warning(disable : 26446) // parser bug does not allow attributes on some templates
#endif // _MSC_VER
@ -48,7 +53,7 @@
#define GSL_USE_STATIC_CONSTEXPR_WORKAROUND
#endif // !(defined(__cplusplus) && (__cplusplus >= 201703L))
// GCC 7 does not like the signed unsigned missmatch (size_t ptrdiff_t)
// GCC 7 does not like the signed unsigned mismatch (size_t ptrdiff_t)
// While there is a conversion from signed to unsigned, it happens at
// compiletime, so the compiler wouldn't have to warn indiscriminately, but
// could check if the source value actually doesn't fit into the target type
@ -58,6 +63,14 @@
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
// Turn off clang unsafe buffer warnings as all accessed are guarded by runtime checks
#if defined(__clang__)
#if __has_warning("-Wunsafe-buffer-usage")
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#endif // __has_warning("-Wunsafe-buffer-usage")
#endif // defined(__clang__)
namespace gsl
{
@ -110,6 +123,9 @@ namespace details
class span_iterator
{
public:
#if defined(__cpp_lib_ranges) || (defined(_MSVC_STL_VERSION) && defined(__cpp_lib_concepts))
using iterator_concept = std::contiguous_iterator_tag;
#endif // __cpp_lib_ranges
using iterator_category = std::random_access_iterator_tag;
using value_type = std::remove_cv_t<Type>;
using difference_type = std::ptrdiff_t;
@ -118,12 +134,15 @@ namespace details
#ifdef _MSC_VER
using _Unchecked_type = pointer;
using _Prevent_inheriting_unwrap = span_iterator;
#endif // _MSC_VER
constexpr span_iterator() = default;
constexpr span_iterator(pointer begin, pointer end, pointer current)
: begin_(begin), end_(end), current_(current)
{}
{
Expects(begin_ <= current_ && current <= end_);
}
constexpr operator span_iterator<const Type>() const noexcept
{
@ -132,21 +151,18 @@ namespace details
constexpr reference operator*() const noexcept
{
Expects(begin_ && end_);
Expects(begin_ <= current_ && current_ < end_);
Expects(current_ != end_);
return *current_;
}
constexpr pointer operator->() const noexcept
{
Expects(begin_ && end_);
Expects(begin_ <= current_ && current_ < end_);
Expects(current_ != end_);
return current_;
}
constexpr span_iterator& operator++() noexcept
{
Expects(begin_ && current_ && end_);
Expects(current_ < end_);
Expects(current_ != end_);
// clang-format off
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
// clang-format on
@ -163,8 +179,7 @@ namespace details
constexpr span_iterator& operator--() noexcept
{
Expects(begin_ && end_);
Expects(begin_ < current_);
Expects(begin_ != current_);
--current_;
return *this;
}
@ -206,6 +221,7 @@ namespace details
if (n != 0) Expects(begin_ && current_ && end_);
if (n > 0) Expects(current_ - begin_ >= n);
if (n < 0) Expects(end_ - current_ >= -n);
GSL_SUPPRESS(bounds .1)
current_ -= n;
return *this;
}
@ -329,8 +345,26 @@ namespace details
pointer begin_ = nullptr;
pointer end_ = nullptr;
pointer current_ = nullptr;
};
template <typename Ptr>
friend struct std::pointer_traits;
};
}} // namespace gsl::details
namespace std
{
template <class Type>
struct pointer_traits<::gsl::details::span_iterator<Type>>
{
using pointer = ::gsl::details::span_iterator<Type>;
using element_type = Type;
using difference_type = ptrdiff_t;
static constexpr element_type* to_address(const pointer i) noexcept { return i.current_; }
};
} // namespace std
namespace gsl { namespace details {
template <std::size_t Ext>
class extent_type
{
@ -548,6 +582,8 @@ public:
template <std::size_t Count>
constexpr span<element_type, Count> first() const noexcept
{
static_assert(Extent == dynamic_extent || Count <= Extent,
"first() cannot extract more elements from a span than it contains.");
Expects(Count <= size());
return span<element_type, Count>{data(), Count};
}
@ -558,6 +594,8 @@ public:
// clang-format on
constexpr span<element_type, Count> last() const noexcept
{
static_assert(Extent == dynamic_extent || Count <= Extent,
"last() cannot extract more elements from a span than it contains.");
Expects(Count <= size());
return span<element_type, Count>{data() + (size() - Count), Count};
}
@ -569,6 +607,9 @@ public:
constexpr auto subspan() const noexcept ->
typename details::calculate_subspan_type<ElementType, Extent, Offset, Count>::type
{
static_assert(Extent == dynamic_extent || (Extent >= Offset && (Count == dynamic_extent ||
Count <= Extent - Offset)),
"subspan() cannot extract more elements from a span than it contains.");
Expects((size() >= Offset) && (Count == dynamic_extent || (Count <= size() - Offset)));
using type =
typename details::calculate_subspan_type<ElementType, Extent, Offset, Count>::type;
@ -596,11 +637,7 @@ public:
// [span.obs], span observers
constexpr size_type size() const noexcept { return storage_.size(); }
constexpr size_type size_bytes() const noexcept
{
Expects(size() < dynamic_extent / sizeof(element_type));
return size() * sizeof(element_type);
}
constexpr size_type size_bytes() const noexcept { return size() * sizeof(element_type); }
constexpr bool empty() const noexcept { return size() == 0; }
@ -682,14 +719,11 @@ private:
template <class OtherExtentType>
constexpr storage_type(KnownNotNull data, OtherExtentType ext)
: ExtentType(ext), data_(data.p)
{
Expects(ExtentType::size() != dynamic_extent);
}
{}
template <class OtherExtentType>
constexpr storage_type(pointer data, OtherExtentType ext) : ExtentType(ext), data_(data)
{
Expects(ExtentType::size() != dynamic_extent);
Expects(data || ExtentType::size() == 0);
}
@ -756,8 +790,15 @@ span(const Container&) -> span<Element>;
#endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) )
#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
#if defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated" // Bug in clang-cl.exe which raises a C++17 -Wdeprecated warning about this static constexpr workaround in C++14 mode.
#endif // defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
template <class ElementType, std::size_t Extent>
constexpr const typename span<ElementType, Extent>::size_type span<ElementType, Extent>::extent;
#if defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
#pragma clang diagnostic pop
#endif // defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
#endif
namespace details
@ -783,28 +824,28 @@ namespace details
// [span.objectrep], views of object representation
template <class ElementType, std::size_t Extent>
span<const byte, details::calculate_byte_size<ElementType, Extent>::value>
span<const gsl::impl::byte, details::calculate_byte_size<ElementType, Extent>::value>
as_bytes(span<ElementType, Extent> s) noexcept
{
using type = span<const byte, details::calculate_byte_size<ElementType, Extent>::value>;
using type = span<const gsl::impl::byte, details::calculate_byte_size<ElementType, Extent>::value>;
// clang-format off
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
// clang-format on
return type{reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
return type{reinterpret_cast<const gsl::impl::byte*>(s.data()), s.size_bytes()};
}
template <class ElementType, std::size_t Extent,
std::enable_if_t<!std::is_const<ElementType>::value, int> = 0>
span<byte, details::calculate_byte_size<ElementType, Extent>::value>
span<gsl::impl::byte, details::calculate_byte_size<ElementType, Extent>::value>
as_writable_bytes(span<ElementType, Extent> s) noexcept
{
using type = span<byte, details::calculate_byte_size<ElementType, Extent>::value>;
using type = span<gsl::impl::byte, details::calculate_byte_size<ElementType, Extent>::value>;
// clang-format off
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
// clang-format on
return type{reinterpret_cast<byte*>(s.data()), s.size_bytes()};
return type{reinterpret_cast<gsl::impl::byte*>(s.data()), s.size_bytes()};
}
} // namespace gsl
@ -818,4 +859,10 @@ as_writable_bytes(span<ElementType, Extent> s) noexcept
#pragma GCC diagnostic pop
#endif // __GNUC__ > 6
#if defined(__clang__)
#if __has_warning("-Wunsafe-buffer-usage")
#pragma clang diagnostic pop
#endif // __has_warning("-Wunsafe-buffer-usage")
#endif // defined(__clang__)
#endif // GSL_SPAN_H

View File

@ -27,8 +27,8 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <gsl/assert> // GSL_KERNEL_MODE
#include <gsl/util> // for narrow_cast, narrow
#include "./assert" // GSL_KERNEL_MODE
#include "./util" // for narrow_cast, narrow
#include <cstddef> // for ptrdiff_t, size_t
#include <utility>
@ -41,7 +41,7 @@ namespace gsl
{
// [span.views.constants], constants
constexpr const std::size_t dynamic_extent = narrow_cast<std::size_t>(-1);
GSL_INLINE constexpr const std::size_t dynamic_extent = narrow_cast<std::size_t>(-1);
template <class ElementType, std::size_t Extent = dynamic_extent>
class span;
@ -123,12 +123,14 @@ constexpr span<const typename Container::value_type> make_span(const Container&
}
template <class Ptr>
GSL_DEPRECATED("This function is deprecated. See GSL issue #1092.")
constexpr span<typename Ptr::element_type> make_span(Ptr& cont, std::size_t count)
{
return span<typename Ptr::element_type>(cont, count);
}
template <class Ptr>
GSL_DEPRECATED("This function is deprecated. See GSL issue #1092.")
constexpr span<typename Ptr::element_type> make_span(Ptr& cont)
{
return span<typename Ptr::element_type>(cont);

View File

@ -1,759 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef GSL_STRING_SPAN_H
#define GSL_STRING_SPAN_H
#include <gsl/assert> // for Ensures, Expects
#include <gsl/span_ext> // for operator!=, operator==, dynamic_extent
#include <gsl/util> // for narrow_cast
#include <algorithm> // for equal, lexicographical_compare
#include <array> // for array
#include <cstddef> // for size_t, nullptr_t
#include <cstdint> // for PTRDIFF_MAX
#include <cstring>
#include <string> // for basic_string, allocator, char_traits
#include <type_traits> // for declval, is_convertible, enable_if_t, add_...
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool.
#pragma warning(disable : 26446) // TODO: bug in parser - attributes and templates
#pragma warning(disable : 26481) // TODO: suppress does not work inside templates sometimes
#pragma warning(disable : 4996) // use of functions & classes marked [[deprecated]]
#endif // _MSC_VER
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
namespace gsl
{
//
// czstring and wzstring
//
// These are "tag" typedefs for C-style strings (i.e. null-terminated character arrays)
// that allow static analysis to help find bugs.
//
// There are no additional features/semantics that we can find a way to add inside the
// type system for these types that will not either incur significant runtime costs or
// (sometimes needlessly) break existing programs when introduced.
//
template <typename CharT, std::size_t Extent = dynamic_extent>
using basic_zstring = CharT*;
using czstring = basic_zstring<const char, dynamic_extent>;
using cwzstring = basic_zstring<const wchar_t, dynamic_extent>;
using cu16zstring = basic_zstring<const char16_t, dynamic_extent>;
using cu32zstring = basic_zstring<const char32_t, dynamic_extent>;
using zstring = basic_zstring<char, dynamic_extent>;
using wzstring = basic_zstring<wchar_t, dynamic_extent>;
using u16zstring = basic_zstring<char16_t, dynamic_extent>;
using u32zstring = basic_zstring<char32_t, dynamic_extent>;
namespace details
{
template <class CharT>
[[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see "
"isocpp/CppCoreGuidelines PR#1680")]] constexpr std::size_t
string_length(const CharT* str, std::size_t n)
{
if (str == nullptr || n == dynamic_extent) return 0;
const span<const CharT> str_span{str, n};
std::size_t len = 0;
while (len < n && str_span[len]) len++;
return len;
}
} // namespace details
//
// ensure_sentinel()
//
// Provides a way to obtain an span from a contiguous sequence
// that ends with a (non-inclusive) sentinel value.
//
// Will fail-fast if sentinel cannot be found before max elements are examined.
//
template <typename T, const T Sentinel>
[[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see "
"isocpp/CppCoreGuidelines PR#1680")]] constexpr span<T, dynamic_extent>
ensure_sentinel(T* seq, std::size_t max = static_cast<std::size_t>(-1))
{
Ensures(seq != nullptr);
// clang-format off
GSL_SUPPRESS(f.23) // TODO: false positive // TODO: suppress does not work
// clang-format on
auto cur = seq;
Ensures(cur != nullptr); // workaround for removing the warning
// clang-format off
GSL_SUPPRESS(bounds.1) // TODO: suppress does not work
// clang-format on
while (static_cast<std::size_t>(cur - seq) < max && *cur != Sentinel) ++cur;
Ensures(*cur == Sentinel);
return {seq, static_cast<std::size_t>(cur - seq)};
}
//
// ensure_z - creates a span for a zero terminated strings. The span will not contain the zero
// termination. Will fail fast if a null-terminator cannot be found before the limit of size_type.
//
template <typename CharT>
[[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see "
"isocpp/CppCoreGuidelines PR#1680")]] constexpr span<CharT, dynamic_extent>
ensure_z(CharT* const& sz, std::size_t max = static_cast<std::size_t>(-1))
{
return ensure_sentinel<CharT, CharT(0)>(sz, max);
}
template <typename CharT, std::size_t N>
constexpr span<CharT, dynamic_extent> ensure_z(CharT (&sz)[N])
{
return ensure_z(&sz[0], N);
}
template <class Cont>
[[deprecated(
"string_span was removed from the C++ Core Guidelines. For more information, see "
"isocpp/CppCoreGuidelines PR#1680")]] constexpr span<typename std::
remove_pointer<
typename Cont::pointer>::type,
dynamic_extent>
ensure_z(Cont& cont)
{
return ensure_z(cont.data(), cont.size());
}
template <typename CharT, std::size_t>
class [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, "
"see isocpp/CppCoreGuidelines PR#1680")]] basic_string_span;
namespace details
{
template <typename T>
struct [[deprecated(
"string_span was removed from the C++ Core Guidelines. For more information, "
"see isocpp/CppCoreGuidelines PR#1680")]] is_basic_string_span_oracle : std::false_type{};
template <typename CharT, std::size_t Extent>
struct [[deprecated(
"string_span was removed from the C++ Core Guidelines. For more information, see "
"isocpp/CppCoreGuidelines PR#1680")]] is_basic_string_span_oracle<basic_string_span<CharT,
Extent>>
: std::true_type{};
template <typename T>
struct [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] is_basic_string_span
: is_basic_string_span_oracle<std::remove_cv_t<T>>{};
} // namespace details
//
// string_span and relatives
//
template <typename CharT, std::size_t Extent = dynamic_extent>
class [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, "
"see isocpp/CppCoreGuidelines PR#1680")]] basic_string_span
{
public:
using element_type = CharT;
using value_type = std::remove_cv_t<element_type>;
using pointer = std::add_pointer_t<element_type>;
using reference = std::add_lvalue_reference_t<element_type>;
using const_reference = std::add_lvalue_reference_t<std::add_const_t<element_type>>;
using impl_type = span<element_type, Extent>;
using size_type = typename impl_type::size_type;
using iterator = typename impl_type::iterator;
using reverse_iterator = typename impl_type::reverse_iterator;
// default (empty)
constexpr basic_string_span() noexcept = default;
// copy
constexpr basic_string_span(const basic_string_span& other) noexcept = default;
// assign
constexpr basic_string_span& operator=(const basic_string_span& other) noexcept = default;
constexpr basic_string_span(pointer ptr, size_type length) : span_(ptr, length) {}
constexpr basic_string_span(pointer firstElem, pointer lastElem) : span_(firstElem, lastElem) {}
// From static arrays - if 0-terminated, remove 0 from the view
// All other containers allow 0s within the length, so we do not remove them
template <std::size_t N>
constexpr basic_string_span(element_type(&arr)[N]) : span_(remove_z(arr))
{}
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
constexpr basic_string_span(std::array<ArrayElementType, N> & arr) noexcept : span_(arr)
{}
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) noexcept : span_(arr)
{}
// Container signature should work for basic_string after C++17 version exists
template <class Traits, class Allocator>
// GSL_SUPPRESS(bounds.4) // TODO: parser bug
constexpr basic_string_span(std::basic_string<element_type, Traits, Allocator> & str)
: span_(&str[0], str.length())
{}
template <class Traits, class Allocator>
constexpr basic_string_span(const std::basic_string<element_type, Traits, Allocator>& str)
: span_(&str[0], str.length())
{}
// from containers. Containers must have a pointer type and data() function signatures
template <class Container,
class = std::enable_if_t<
!details::is_basic_string_span<Container>::value &&
std::is_convertible<typename Container::pointer, pointer>::value &&
std::is_convertible<typename Container::pointer,
decltype(std::declval<Container>().data())>::value>>
constexpr basic_string_span(Container & cont) : span_(cont)
{}
template <class Container,
class = std::enable_if_t<
!details::is_basic_string_span<Container>::value &&
std::is_convertible<typename Container::pointer, pointer>::value &&
std::is_convertible<typename Container::pointer,
decltype(std::declval<Container>().data())>::value>>
constexpr basic_string_span(const Container& cont) : span_(cont)
{}
// from string_span
template <
class OtherValueType, std::size_t OtherExtent,
class = std::enable_if_t<std::is_convertible<
typename basic_string_span<OtherValueType, OtherExtent>::impl_type, impl_type>::value>>
constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other)
: span_(other.data(), other.length())
{}
template <size_type Count>
constexpr basic_string_span<element_type, Count> first() const
{
return {span_.template first<Count>()};
}
constexpr basic_string_span<element_type, dynamic_extent> first(size_type count) const
{
return {span_.first(count)};
}
template <size_type Count>
constexpr basic_string_span<element_type, Count> last() const
{
return {span_.template last<Count>()};
}
constexpr basic_string_span<element_type, dynamic_extent> last(size_type count) const
{
return {span_.last(count)};
}
template <size_type Offset, size_type Count>
constexpr basic_string_span<element_type, Count> subspan() const
{
return {span_.template subspan<Offset, Count>()};
}
constexpr basic_string_span<element_type, dynamic_extent> subspan(
size_type offset, size_type count = dynamic_extent) const
{
return {span_.subspan(offset, count)};
}
constexpr reference operator[](size_type idx) const { return span_[idx]; }
constexpr reference operator()(size_type idx) const { return span_[idx]; }
constexpr pointer data() const { return span_.data(); }
constexpr size_type length() const noexcept { return span_.size(); }
constexpr size_type size() const noexcept { return span_.size(); }
constexpr size_type size_bytes() const noexcept { return span_.size_bytes(); }
constexpr size_type length_bytes() const noexcept { return span_.length_bytes(); }
constexpr bool empty() const noexcept { return size() == 0; }
constexpr iterator begin() const noexcept { return span_.begin(); }
constexpr iterator end() const noexcept { return span_.end(); }
constexpr reverse_iterator rbegin() const noexcept { return span_.rbegin(); }
constexpr reverse_iterator rend() const noexcept { return span_.rend(); }
private:
static constexpr impl_type remove_z(pointer const& sz, std::size_t max)
{
return impl_type(sz, details::string_length(sz, max));
}
template <std::size_t N>
static constexpr impl_type remove_z(element_type(&sz)[N])
{
return remove_z(&sz[0], N);
}
impl_type span_;
};
template <std::size_t Extent = dynamic_extent>
using string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_string_span<char, Extent>;
template <std::size_t Extent = dynamic_extent>
using cstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_string_span<const char, Extent>;
template <std::size_t Extent = dynamic_extent>
using wstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_string_span<wchar_t, Extent>;
template <std::size_t Extent = dynamic_extent>
using cwstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_string_span<const wchar_t, Extent>;
template <std::size_t Extent = dynamic_extent>
using u16string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_string_span<char16_t, Extent>;
template <std::size_t Extent = dynamic_extent>
using cu16string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_string_span<const char16_t, Extent>;
template <std::size_t Extent = dynamic_extent>
using u32string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_string_span<char32_t, Extent>;
template <std::size_t Extent = dynamic_extent>
using cu32string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_string_span<const char32_t, Extent>;
//
// to_string() allow (explicit) conversions from string_span to string
//
template <typename CharT, std::size_t Extent>
constexpr std::basic_string<typename std::remove_const<CharT>::type>
to_string(basic_string_span<CharT, Extent> view)
{
return {view.data(), narrow_cast<std::size_t>(view.length())};
}
template <typename CharT, typename Traits = typename std::char_traits<CharT>,
typename Allocator = std::allocator<CharT>, typename gCharT, std::size_t Extent>
constexpr std::basic_string<CharT, Traits, Allocator>
to_basic_string(basic_string_span<gCharT, Extent> view)
{
return {view.data(), narrow_cast<std::size_t>(view.length())};
}
template <class ElementType, std::size_t Extent>
constexpr basic_string_span<const byte, details::calculate_byte_size<ElementType, Extent>::value>
as_bytes(basic_string_span<ElementType, Extent> s) noexcept
{
// clang-format off
GSL_SUPPRESS(type.1)
// clang-format on
return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
}
template <class ElementType, std::size_t Extent,
class = std::enable_if_t<!std::is_const<ElementType>::value>>
constexpr basic_string_span<byte, details::calculate_byte_size<ElementType, Extent>::value>
as_writable_bytes(basic_string_span<ElementType, Extent> s) noexcept
{
// clang-format off
GSL_SUPPRESS(type.1)
// clang-format on
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
}
// zero-terminated string span, used to convert
// zero-terminated spans to legacy strings
template <typename CharT, std::size_t Extent = dynamic_extent>
class [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, "
"see isocpp/CppCoreGuidelines PR#1680")]] basic_zstring_span
{
public:
using value_type = CharT;
using const_value_type = std::add_const_t<CharT>;
using pointer = std::add_pointer_t<value_type>;
using const_pointer = std::add_pointer_t<const_value_type>;
using zstring_type = basic_zstring<value_type, Extent>;
using const_zstring_type = basic_zstring<const_value_type, Extent>;
using impl_type = span<value_type, Extent>;
using string_span_type = basic_string_span<value_type, Extent>;
constexpr basic_zstring_span(impl_type s) : span_(s)
{
// expects a zero-terminated span
Expects(s.size() > 0);
Expects(s[s.size() - 1] == value_type{});
}
// copy
constexpr basic_zstring_span(const basic_zstring_span& other) = default;
// move
constexpr basic_zstring_span(basic_zstring_span && other) = default;
// assign
constexpr basic_zstring_span& operator=(const basic_zstring_span& other) = default;
// move assign
constexpr basic_zstring_span& operator=(basic_zstring_span&& other) = default;
constexpr bool empty() const noexcept { return false; }
constexpr string_span_type as_string_span() const noexcept
{
return {span_.data(), span_.size() - 1};
}
constexpr string_span_type ensure_z() const { return gsl::ensure_z(span_); }
constexpr const_zstring_type assume_z() const noexcept { return span_.data(); }
private:
impl_type span_;
};
template <std::size_t Max = dynamic_extent>
using zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_zstring_span<char, Max>;
template <std::size_t Max = dynamic_extent>
using wzstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_zstring_span<wchar_t, Max>;
template <std::size_t Max = dynamic_extent>
using u16zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_zstring_span<char16_t, Max>;
template <std::size_t Max = dynamic_extent>
using u32zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_zstring_span<char32_t, Max>;
template <std::size_t Max = dynamic_extent>
using czstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_zstring_span<const char, Max>;
template <std::size_t Max = dynamic_extent>
using cwzstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more "
"information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_zstring_span<const wchar_t, Max>;
template <std::size_t Max = dynamic_extent>
using cu16zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For "
"more information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_zstring_span<const char16_t, Max>;
template <std::size_t Max = dynamic_extent>
using cu32zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For "
"more information, see isocpp/CppCoreGuidelines PR#1680")]] =
basic_zstring_span<const char32_t, Max>;
// operator ==
template <class CharT, std::size_t Extent, class T,
class = std::enable_if_t<
details::is_basic_string_span<T>::value ||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other)
{
const gsl::basic_string_span<std::add_const_t<CharT>> tmp(other);
return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end());
}
template <class CharT, std::size_t Extent, class T,
class = std::enable_if_t<
!details::is_basic_string_span<T>::value &&
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other)
{
const gsl::basic_string_span<std::add_const_t<CharT>> tmp(one);
return std::equal(tmp.begin(), tmp.end(), other.begin(), other.end());
}
// operator !=
template <typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename = std::enable_if_t<std::is_convertible<
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other)
{
return !(one == other);
}
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
!gsl::details::is_basic_string_span<T>::value>>
bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other)
{
return !(one == other);
}
// operator<
template <typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename = std::enable_if_t<std::is_convertible<
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other)
{
const gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
}
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
!gsl::details::is_basic_string_span<T>::value>>
bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other)
{
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end());
}
#ifndef _MSC_VER
// VS treats temp and const containers as convertible to basic_string_span,
// so the cases below are already covered by the previous operators
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename DataType = typename T::value_type,
typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>>
bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other)
{
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
}
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename DataType = typename T::value_type,
typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>>
bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other)
{
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end());
}
#endif
// operator <=
template <typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename = std::enable_if_t<std::is_convertible<
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other)
{
return !(other < one);
}
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
!gsl::details::is_basic_string_span<T>::value>>
bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other)
{
return !(other < one);
}
#ifndef _MSC_VER
// VS treats temp and const containers as convertible to basic_string_span,
// so the cases below are already covered by the previous operators
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename DataType = typename T::value_type,
typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>>
bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other)
{
return !(other < one);
}
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename DataType = typename T::value_type,
typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>>
bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other)
{
return !(other < one);
}
#endif
// operator>
template <typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename = std::enable_if_t<std::is_convertible<
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other)
{
return other < one;
}
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
!gsl::details::is_basic_string_span<T>::value>>
bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other)
{
return other < one;
}
#ifndef _MSC_VER
// VS treats temp and const containers as convertible to basic_string_span,
// so the cases below are already covered by the previous operators
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename DataType = typename T::value_type,
typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>>
bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other)
{
return other < one;
}
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename DataType = typename T::value_type,
typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>>
bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other)
{
return other < one;
}
#endif
// operator >=
template <typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename = std::enable_if_t<std::is_convertible<
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other)
{
return !(one < other);
}
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
!gsl::details::is_basic_string_span<T>::value>>
bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other)
{
return !(one < other);
}
#ifndef _MSC_VER
// VS treats temp and const containers as convertible to basic_string_span,
// so the cases below are already covered by the previous operators
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename DataType = typename T::value_type,
typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>>
bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other)
{
return !(one < other);
}
template <
typename CharT, std::size_t Extent = dynamic_extent, typename T,
typename DataType = typename T::value_type,
typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>>
bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other)
{
return !(one < other);
}
#endif
} // namespace gsl
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(pop)
#endif // _MSC_VER
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
#endif // GSL_STRING_SPAN_H

View File

@ -17,10 +17,11 @@
#ifndef GSL_UTIL_H
#define GSL_UTIL_H
#include <gsl/assert> // for Expects
#include "./assert" // for Expects
#include <array>
#include <cstddef> // for ptrdiff_t, size_t
#include <limits> // for numeric_limits
#include <initializer_list> // for initializer_list
#include <type_traits> // for is_signed, integral_constant
#include <utility> // for exchange, forward
@ -39,12 +40,52 @@
#endif // _MSC_VER
// Turn off clang unsafe buffer warnings as all accessed are guarded by runtime checks
#if defined(__clang__)
#if __has_warning("-Wunsafe-buffer-usage")
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#endif // __has_warning("-Wunsafe-buffer-usage")
#endif // defined(__clang__)
#if defined(__cplusplus) && (__cplusplus >= 201703L)
#define GSL_NODISCARD [[nodiscard]]
#else
#define GSL_NODISCARD
#endif // defined(__cplusplus) && (__cplusplus >= 201703L)
#if defined(__cpp_inline_variables)
#define GSL_INLINE inline
#else
#define GSL_INLINE
#endif
#if defined(__has_cpp_attribute)
#if __has_cpp_attribute(deprecated)
#define GSL_DEPRECATED(msg) [[deprecated(msg)]]
#endif // __has_cpp_attribute(deprecated)
#endif // defined(__has_cpp_attribute)
#if !defined(GSL_DEPRECATED)
#if defined(__cplusplus)
#if __cplusplus >= 201309L
#define GSL_DEPRECATED(msg) [[deprecated(msg)]]
#endif // __cplusplus >= 201309L
#endif // defined(__cplusplus)
#endif // !defined(GSL_DEPRECATED)
#if !defined(GSL_DEPRECATED)
#if defined(_MSC_VER)
#define GSL_DEPRECATED(msg) __declspec(deprecated(msg))
#elif defined(__GNUC__)
#define GSL_DEPRECATED(msg) __attribute__((deprecated(msg)))
#endif // defined(_MSC_VER)
#endif // !defined(GSL_DEPRECATED)
#if !defined(GSL_DEPRECATED)
#define GSL_DEPRECATED(msg)
#endif // !defined(GSL_DEPRECATED)
namespace gsl
{
//
@ -59,40 +100,29 @@ template <class F>
class final_action
{
public:
static_assert(!std::is_reference<F>::value && !std::is_const<F>::value &&
!std::is_volatile<F>::value,
"Final_action should store its callable by value");
explicit final_action(const F& ff) noexcept : f{ff} { }
explicit final_action(F&& ff) noexcept : f{std::move(ff)} { }
explicit final_action(F f) noexcept : f_(std::move(f)) {}
~final_action() noexcept { if (invoke) f(); }
final_action(final_action&& other) noexcept
: f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false))
{}
: f(std::move(other.f)), invoke(std::exchange(other.invoke, false))
{ }
final_action(const final_action&) = delete;
final_action& operator=(const final_action&) = delete;
final_action& operator=(final_action&&) = delete;
// clang-format off
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // terminate if throws
// clang-format on
~final_action() noexcept
{
if (invoke_) f_();
}
final_action(const final_action&) = delete;
void operator=(const final_action&) = delete;
void operator=(final_action&&) = delete;
private:
F f_;
bool invoke_{true};
F f;
bool invoke = true;
};
// finally() - convenience function to generate a final_action
template <class F>
GSL_NODISCARD final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>
finally(F&& f) noexcept
GSL_NODISCARD auto finally(F&& f) noexcept
{
return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(
std::forward<F>(f));
return final_action<std::decay_t<F>>{std::forward<F>(f)};
}
// narrow_cast(): a searchable way to do narrowing casts of values
@ -115,6 +145,7 @@ GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
// clang-format on
constexpr T& at(T (&arr)[N], const index i)
{
static_assert(N <= static_cast<std::size_t>((std::numeric_limits<std::ptrdiff_t>::max)()), "We only support arrays up to PTRDIFF_MAX bytes.");
Expects(i >= 0 && i < narrow_cast<index>(N));
return arr[narrow_cast<std::size_t>(i)];
}
@ -141,12 +172,15 @@ GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
return *(cont.begin() + i);
}
template <class T, std::enable_if_t<std::is_move_assignable<T>::value && std::is_move_constructible<T>::value>>
void swap(T& a, T& b) { std::swap(a, b); }
#if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
template <class T, size_t extent = std::dynamic_extent>
template <class T, std::size_t extent = std::dynamic_extent>
constexpr auto at(std::span<T, extent> sp, const index i) -> decltype(sp[sp.size()])
{
Expects(i >= 0 && i < narrow_cast<index>(sp.size()));
return sp[gsl::narrow_cast<size_t>(i)];
return sp[gsl::narrow_cast<std::size_t>(i)];
}
#endif // __cpp_lib_span >= 202002L
} // namespace gsl
@ -157,4 +191,10 @@ constexpr auto at(std::span<T, extent> sp, const index i) -> decltype(sp[sp.size
#endif // _MSC_VER
#if defined(__clang__)
#if __has_warning("-Wunsafe-buffer-usage")
#pragma clang diagnostic pop
#endif // __has_warning("-Wunsafe-buffer-usage")
#endif // defined(__clang__)
#endif // GSL_UTIL_H

58
include/gsl/zstring Normal file
View File

@ -0,0 +1,58 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef GSL_ZSTRING_H
#define GSL_ZSTRING_H
#include "./span_ext" // for dynamic_extent
#include <cstddef> // for size_t, nullptr_t
namespace gsl
{
//
// czstring and wzstring
//
// These are "tag" typedefs for C-style strings (i.e. null-terminated character arrays)
// that allow static analysis to help find bugs.
//
// There are no additional features/semantics that we can find a way to add inside the
// type system for these types that will not either incur significant runtime costs or
// (sometimes needlessly) break existing programs when introduced.
//
template <typename CharT, std::size_t Extent = dynamic_extent>
using basic_zstring = CharT*;
using czstring = basic_zstring<const char, dynamic_extent>;
using cwzstring = basic_zstring<const wchar_t, dynamic_extent>;
using cu16zstring = basic_zstring<const char16_t, dynamic_extent>;
using cu32zstring = basic_zstring<const char32_t, dynamic_extent>;
using zstring = basic_zstring<char, dynamic_extent>;
using wzstring = basic_zstring<wchar_t, dynamic_extent>;
using u16zstring = basic_zstring<char16_t, dynamic_extent>;
using u32zstring = basic_zstring<char32_t, dynamic_extent>;
} // namespace gsl
#endif // GSL_ZSTRING_H

View File

@ -1,43 +0,0 @@
parameters:
CXXVersions: [ 14, 17, 20 ]
buildTypes: [ 'Debug', 'Release' ]
image: ''
compiler: ''
compilerVersions: ["default"] # if default value, simply uses whatever version is on the machine.
# the text of this default value doesn't actually matter.
setupfile: ''
extraCmakeArgs: ''
jobs:
- ${{ each compilerVersion in parameters.compilerVersions }}:
- ${{ each CXXVersion in parameters.CXXVersions }}:
- ${{ each buildType in parameters.buildTypes }}:
- job:
displayName: ${{ format('{0} {1} C++{2} {3}', parameters.compiler, compilerVersion, CXXVersion, buildType) }}
pool:
vmImage: ${{ parameters.image }}
continueOnError: false
steps:
- ${{ if not(eq(parameters.setupfile, '')) }}:
- template: ${{ parameters.setupfile }}
parameters:
version: ${{ compilerVersion }}
- task: CMake@1
name: Configure
inputs:
workingDirectory: build
cmakeArgs: '-DGSL_CXX_STANDARD=${{ CXXVersion }} -DCMAKE_BUILD_TYPE=${{ buildType }} -DCI_TESTING:BOOL=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -Werror=dev ${{ parameters.extraCmakeArgs }} .. '
- task: CMake@1
name: Build
inputs:
workingDirectory: build
cmakeArgs: '--build . '
- script: ctest . --output-on-failure --no-compress-output
name: CTest
workingDirectory: build
failOnStderr: true

View File

@ -1,9 +0,0 @@
parameters:
version: 0
steps:
- script: |
if [ "${{ parameters.version }}" != "default" ]; then sudo xcode-select -switch /Applications/Xcode_${{ parameters.version }}.app; fi
displayName: "Setup Xcode Version"
failOnStderr: true

View File

@ -1,13 +0,0 @@
parameters:
version: 0
steps:
- script: |
echo "##vso[task.setvariable variable=CXX;]${CXX}"
echo "##vso[task.setvariable variable=CC;]${CC}"
displayName: "Setup Clang Version"
failOnStderr: true
env:
CC: clang-${{ parameters.version }}
CXX: clang++-${{ parameters.version }}

View File

@ -1,14 +0,0 @@
parameters:
version: 0
steps:
- script: |
echo "##vso[task.setvariable variable=CXX;]${CXX}"
echo "##vso[task.setvariable variable=CC;]${CC}"
if [ "${{ parameters.version }}" = "11" ]; then sudo apt-get install $CXX; fi
displayName: "Setup GCC Version"
failOnStderr: true
env:
CC: gcc-${{ parameters.version }}
CXX: g++-${{ parameters.version }}

View File

View File

@ -1,7 +1,12 @@
cmake_minimum_required(VERSION 3.0.2)
cmake_minimum_required(VERSION 3.14...3.16)
project(GSLTests CXX)
enable_testing() # again, for support standalone testing
project(GSLTests LANGUAGES CXX)
set(GSL_CXX_STANDARD "14" CACHE STRING "Use c++ standard")
set(CMAKE_CXX_STANDARD ${GSL_CXX_STANDARD})
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(FindPkgConfig)
include(ExternalProject)
@ -52,16 +57,21 @@ if (NOT GTestMain_FOUND)
endif()
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
# CMake has been started independently in this directory with tests. Do
# import the globally installed Guidelines Support Library and test it
# instead of the current version from the include/ folder.
find_package(Microsoft.GSL REQUIRED)
find_package(Microsoft.GSL CONFIG REQUIRED)
enable_testing()
if (NOT DEFINED Microsoft.GSL_VERSION)
message(FATAL_ERROR "Microsoft.GSL_VERSION not defined!")
endif()
message(STATUS "Microsoft.GSL_VERSION = ${Microsoft.GSL_VERSION}")
endif()
if (MSVC AND (GSL_CXX_STANDARD GREATER_EQUAL 17))
set(GSL_CPLUSPLUS_OPT -Zc:__cplusplus -permissive-)
endif()
include(CheckCXXCompilerFlag)
# this interface adds compile options to how the tests are run
# please try to keep entries ordered =)
add_library(gsl_tests_config INTERFACE)
@ -88,6 +98,7 @@ if(MSVC) # MSVC or simulating MSVC
>
$<$<CXX_COMPILER_ID:Clang>:
-Weverything
-Wfloat-equal
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-covered-switch-default # GTest
@ -99,12 +110,20 @@ if(MSVC) # MSVC or simulating MSVC
-Wno-shift-sign-overflow # GTest gtest-port.h
-Wno-undef # GTest
-Wno-used-but-marked-unused # GTest EXPECT_DEATH
-Wno-switch-default # GTest EXPECT_DEATH
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
-Wno-unused-member-function
-Wno-unused-variable
$<$<VERSION_EQUAL:$<CXX_COMPILER_VERSION>,15.0.1>:
-Wno-deprecated # False positive in MSVC Clang 15.0.1 raises a C++17 warning
>
>
>
)
check_cxx_compiler_flag("-Wno-reserved-identifier" WARN_RESERVED_ID)
if (WARN_RESERVED_ID)
target_compile_options(gsl_tests_config INTERFACE "-Wno-reserved-identifier")
endif()
else()
target_compile_options(gsl_tests_config INTERFACE
-fno-strict-aliasing
@ -117,6 +136,7 @@ else()
-Wpedantic
-Wshadow
-Wsign-conversion
-Wfloat-equal
-Wno-deprecated-declarations # Allow tests for [[deprecated]] elements
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
-Weverything
@ -127,6 +147,7 @@ else()
-Wno-global-constructors # GTest
-Wno-missing-prototypes
-Wno-padded
-Wno-switch-default
-Wno-unknown-attributes
-Wno-used-but-marked-unused # GTest EXPECT_DEATH
-Wno-weak-vtables
@ -167,6 +188,11 @@ else()
>
)
endif(MSVC)
check_cxx_compiler_flag("-Wno-unsafe-buffer-usage" WARN_UNSAFE_BUFFER)
if (WARN_UNSAFE_BUFFER)
# This test uses very greedy heuristics such as "no pointer arithmetic on raw buffer"
target_compile_options(gsl_tests_config INTERFACE "-Wno-unsafe-buffer-usage")
endif()
# for tests to find the gtest header
target_include_directories(gsl_tests_config SYSTEM INTERFACE
@ -180,11 +206,12 @@ add_executable(gsl_tests
byte_tests.cpp
notnull_tests.cpp
owner_tests.cpp
pointers_tests.cpp
span_compatibility_tests.cpp
span_ext_tests.cpp
span_tests.cpp
strict_notnull_tests.cpp
string_span_tests.cpp
utils_tests.cpp
)
@ -222,12 +249,22 @@ if(MSVC) # MSVC or simulating MSVC
>
$<$<CXX_COMPILER_ID:Clang>:
-Weverything
-Wfloat-equal
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-missing-prototypes
-Wno-unknown-attributes
$<$<EQUAL:${GSL_CXX_STANDARD},14>:
$<$<VERSION_EQUAL:$<CXX_COMPILER_VERSION>,15.0.1>:
-Wno-deprecated # False positive in MSVC Clang 15.0.1 raises a C++17 warning
>
>
>
)
check_cxx_compiler_flag("-Wno-reserved-identifier" WARN_RESERVED_ID)
if (WARN_RESERVED_ID)
target_compile_options(gsl_tests_config_noexcept INTERFACE "-Wno-reserved-identifier")
endif()
else()
target_compile_options(gsl_tests_config_noexcept INTERFACE
-fno-exceptions
@ -241,6 +278,7 @@ else()
-Wpedantic
-Wshadow
-Wsign-conversion
-Wfloat-equal
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
-Weverything
-Wno-c++98-compat
@ -267,6 +305,11 @@ else()
>
)
endif(MSVC)
check_cxx_compiler_flag("-Wno-unsafe-buffer-usage" WARN_UNSAFE_BUFFER)
if (WARN_UNSAFE_BUFFER)
# This test uses very greedy heuristics such as "no pointer arithmetic on raw buffer"
target_compile_options(gsl_tests_config_noexcept INTERFACE "-Wno-unsafe-buffer-usage")
endif()
add_executable(gsl_noexcept_tests no_exception_ensure_tests.cpp)
target_link_libraries(gsl_noexcept_tests

View File

@ -1,10 +1,10 @@
cmake_minimum_required(VERSION 3.0.2)
cmake_minimum_required(VERSION 3.13)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 1b18723e874b256c1e39378c6774a90701d70f7a
GIT_TAG v1.14.0
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""

View File

@ -188,7 +188,7 @@ TEST(algorithm_tests, incompatible_type)
span<int> src_span_dyn(src);
span<int, 4> src_span_static(src);
span<int*> dst_span_dyn(dst);
span<int*, 4> dst_span_static(dst);
span<int*, 4> dst_span_static(gsl::make_span(dst));
// every line should produce a compilation error
copy(src_span_dyn, dst_span_dyn);

View File

@ -15,7 +15,7 @@
///////////////////////////////////////////////////////////////////////////////
#include "deathTestCommon.h"
#include <gsl/assert> // for fail_fast (ptr only), Ensures, Expects
#include <gsl/assert> // for Ensures, Expects
#include <gtest/gtest.h>
using namespace gsl;

View File

@ -20,6 +20,7 @@
#include <array> // for array
#include <cstddef> // for size_t
#include <exception> // for terminate
#include <initializer_list> // for initializer_list
#include <vector> // for vector
#if defined(__cplusplus) && __cplusplus >= 202002L

View File

@ -16,8 +16,12 @@
#include <gtest/gtest.h>
#define GSL_USE_STD_BYTE 0
#include <gsl/byte> // for to_byte, to_integer, byte, operator&, ope...
#include <type_traits>
#include <utility>
using namespace std;
using namespace gsl;
@ -33,41 +37,46 @@ int modify_both(gsl::byte& b, int& i)
TEST(byte_tests, construction)
{
{
const byte b = static_cast<byte>(4);
const gsl::byte b = static_cast<gsl::byte>(4);
EXPECT_TRUE(static_cast<unsigned char>(b) == 4);
}
// clang-format off
GSL_SUPPRESS(es.49)
// clang-format on
{
const byte b = byte(12);
const gsl::byte b = gsl::byte(12);
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
}
{
const byte b = to_byte<12>();
const gsl::byte b = to_byte<12>();
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
}
{
const unsigned char uc = 12;
const byte b = to_byte(uc);
const gsl::byte b = to_byte(uc);
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
}
#if defined(__cplusplus) && (__cplusplus >= 201703L)
{
const byte b{14};
const gsl::byte b{14};
EXPECT_TRUE(static_cast<unsigned char>(b) == 14);
}
#endif
#ifdef CONFIRM_COMPILATION_ERRORS
to_byte(char{});
to_byte(3);
to_byte(3u);
to_byte<-1>();
to_byte<256u>();
#endif
}
TEST(byte_tests, bitwise_operations)
{
const byte b = to_byte<0xFF>();
const gsl::byte b = to_byte<0xFF>();
byte a = to_byte<0x00>();
gsl::byte a = to_byte<0x00>();
EXPECT_TRUE((b | a) == to_byte<0xFF>());
EXPECT_TRUE(a == to_byte<0x00>());
@ -101,7 +110,7 @@ TEST(byte_tests, bitwise_operations)
TEST(byte_tests, to_integer)
{
const byte b = to_byte<0x12>();
const gsl::byte b = to_byte<0x12>();
EXPECT_TRUE(0x12 == gsl::to_integer<char>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<short>(b));
@ -120,12 +129,50 @@ TEST(byte_tests, to_integer)
TEST(byte_tests, aliasing)
{
int i{0};
const int res = modify_both(reinterpret_cast<byte&>(i), i);
const int res = modify_both(reinterpret_cast<gsl::byte&>(i), i);
EXPECT_TRUE(res == i);
}
} // namespace
#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l
#ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static);
#endif
template <typename U, typename = void>
static constexpr bool LShiftCompilesFor = false;
template <typename U>
static constexpr bool LShiftCompilesFor<
U, void_t<decltype(gsl::operator<< <float>(declval<gsl::byte>(), declval<U>()))>> = true;
static_assert(!LShiftCompilesFor<float>, "!LShiftCompilesFor<float>");
template <typename U, typename = void>
static constexpr bool RShiftCompilesFor = false;
template <typename U>
static constexpr bool RShiftCompilesFor<
U, void_t<decltype(gsl::operator>> <U>(declval<gsl::byte>(), declval<U>()))>> = true;
static_assert(!RShiftCompilesFor<float>, "!RShiftCompilesFor<float>");
template <typename U, typename = void>
static constexpr bool LShiftAssignCompilesFor = false;
template <typename U>
static constexpr bool LShiftAssignCompilesFor<
U, void_t<decltype(gsl::operator<<= <U>(declval<gsl::byte&>(), declval<U>()))>> = true;
static_assert(!LShiftAssignCompilesFor<float>, "!LShiftAssignCompilesFor<float>");
template <typename U, typename = void>
static constexpr bool RShiftAssignCompilesFor = false;
template <typename U>
static constexpr bool RShiftAssignCompilesFor<
U, void_t<decltype(gsl::operator>>= <U>(declval<gsl::byte&>(), declval<U>()))>> = true;
static_assert(!RShiftAssignCompilesFor<float>, "!RShiftAssignCompilesFor<float>");
template <typename U, typename = void>
static constexpr bool ToIntegerCompilesFor = false;
template <typename U>
static constexpr bool
ToIntegerCompilesFor<U, void_t<decltype(gsl::to_integer<U>(gsl::byte{}))>> = true;
static_assert(!ToIntegerCompilesFor<float>, "!ToIntegerCompilesFor<float>");
} // namespace

View File

@ -18,16 +18,25 @@
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
#include <algorithm> // for addressof
#include <memory> // for shared_ptr, make_shared, operator<, opera...
#include <sstream> // for operator<<, ostringstream, basic_ostream:...
#include <stdint.h> // for uint16_t
#include <string> // for basic_string, operator==, string, operator<<
#include <typeinfo> // for type_info
#include <algorithm> // for addressof
#include <cstdint> // for uint16_t
#include <memory> // for shared_ptr, make_shared, operator<, opera...
#include <sstream> // for operator<<, ostringstream, basic_ostream:...
#include <string> // for basic_string, operator==, string, operator<<
#include <type_traits> // for declval
#include <typeinfo> // for type_info
#include <variant> // for variant, monostate, get
#include "deathTestCommon.h"
using namespace gsl;
#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l
struct MyBase
{
};
@ -52,7 +61,7 @@ template <typename T>
struct CustomPtr
{
CustomPtr(T* p) : p_(p) {}
operator T*() { return p_; }
operator T*() const { return p_; }
bool operator!=(std::nullptr_t) const { return p_ != nullptr; }
T* p_ = nullptr;
};
@ -140,16 +149,39 @@ bool helper_const(not_null<const int*> p) { return *p == 12; }
int* return_pointer() { return nullptr; }
} // namespace
template <typename U, typename = void>
static constexpr bool CtorCompilesFor_A = false;
template <typename U>
static constexpr bool
CtorCompilesFor_A<U, void_t<decltype(gsl::not_null<void*>{std::declval<U>()})>> = true;
template <typename U, int N, typename = void>
static constexpr bool CtorCompilesFor_B = false;
template <typename U, int N>
static constexpr bool CtorCompilesFor_B<U, N, void_t<decltype(gsl::not_null<U>{N})>> = true;
template <typename U, typename = void>
static constexpr bool DefaultCtorCompilesFor = false;
template <typename U>
static constexpr bool DefaultCtorCompilesFor<U, void_t<decltype(gsl::not_null<U>{})>> = true;
template <typename U, typename = void>
static constexpr bool CtorCompilesFor_C = false;
template <typename U>
static constexpr bool
CtorCompilesFor_C<U, void_t<decltype(gsl::not_null<U*>{std::declval<std::unique_ptr<U>>()})>> =
true;
TEST(notnull_tests, TestNotNullConstructors)
{
{
#ifdef CONFIRM_COMPILATION_ERRORS
not_null<int*> p = nullptr; // yay...does not compile!
not_null<std::vector<char>*> p1 = 0; // yay...does not compile!
not_null<int*> p2; // yay...does not compile!
std::unique_ptr<int> up = std::make_unique<int>(120);
not_null<int*> p3 = up;
static_assert(CtorCompilesFor_A<void*>, "CtorCompilesFor_A<void*>");
static_assert(!CtorCompilesFor_A<std::nullptr_t>, "!CtorCompilesFor_A<std::nullptr_t>");
static_assert(!CtorCompilesFor_B<void*, 0>, "!CtorCompilesFor_B<void*, 0>");
static_assert(!DefaultCtorCompilesFor<void*>, "!DefaultCtorCompilesFor<void*>");
static_assert(!CtorCompilesFor_C<int>, "CtorCompilesFor_C<int>");
#ifdef CONFIRM_COMPILATION_ERRORS
// Forbid non-nullptr assignable types
not_null<std::vector<int>> f(std::vector<int>{1});
not_null<int> z(10);
@ -177,6 +209,14 @@ TEST(notnull_tests, TestNotNullConstructors)
EXPECT_DEATH((not_null<decltype(pi)>(pi)), expected);
}
{
// from unique pointer
not_null<std::unique_ptr<int>> x(
std::make_unique<int>(10)); // unique_ptr<int> is nullptr assignable
EXPECT_DEATH((not_null<std::unique_ptr<int>>(std::unique_ptr<int>{})), expected);
}
{
// from pointer to local
int t = 42;
@ -267,6 +307,27 @@ TEST(notnull_tests, TestNotNullostream)
ostream_helper<std::string>("string");
}
template <typename U, typename V, typename = void>
static constexpr bool AssignmentCompilesFor = false;
template <typename U, typename V>
static constexpr bool
AssignmentCompilesFor<U, V,
void_t<decltype(std::declval<gsl::not_null<U*>&>().operator=(
std::declval<gsl::not_null<V*>&>()))>> = true;
template <typename U, typename V, typename = void>
static constexpr bool SCastCompilesFor = false;
template <typename U, typename V>
static constexpr bool
SCastCompilesFor<U, V, void_t<decltype(static_cast<U*>(std::declval<gsl::not_null<V*>&>()))>> =
true;
template <typename U, typename V, typename = void>
static constexpr bool RCastCompilesFor = false;
template <typename U, typename V>
static constexpr bool RCastCompilesFor<
U, V, void_t<decltype(reinterpret_cast<U*>(std::declval<gsl::not_null<V*>&>()))>> = true;
TEST(notnull_tests, TestNotNullCasting)
{
MyBase base;
@ -279,15 +340,30 @@ TEST(notnull_tests, TestNotNullCasting)
q = p; // allowed with heterogeneous copy ctor
EXPECT_TRUE(q == p);
#ifdef CONFIRM_COMPILATION_ERRORS
q = u; // no viable conversion possible between MyBase* and Unrelated*
p = q; // not possible to implicitly convert MyBase* to MyDerived*
static_assert(AssignmentCompilesFor<MyBase, MyDerived>,
"AssignmentCompilesFor<MyBase, MyDerived>");
static_assert(!AssignmentCompilesFor<MyBase, Unrelated>,
"!AssignmentCompilesFor<MyBase, Unrelated>");
static_assert(!AssignmentCompilesFor<Unrelated, MyDerived>,
"!AssignmentCompilesFor<Unrelated, MyDerived>");
static_assert(!AssignmentCompilesFor<MyDerived, MyBase>,
"!AssignmentCompilesFor<MyDerived, MyBase>");
static_assert(SCastCompilesFor<MyDerived, MyDerived>, "SCastCompilesFor<MyDerived, MyDerived>");
static_assert(SCastCompilesFor<MyBase, MyDerived>, "SCastCompilesFor<MyBase, MyDerived>");
static_assert(!SCastCompilesFor<MyDerived, MyBase>, "!SCastCompilesFor<MyDerived, MyBase>");
static_assert(!SCastCompilesFor<Unrelated, MyDerived>,
"!SCastCompilesFor<Unrelated, MyDerived>");
static_assert(!RCastCompilesFor<MyDerived, MyDerived>,
"!SCastCompilesFor<MyDerived, MyDerived>");
static_assert(!RCastCompilesFor<Unrelated, MyDerived>,
"!SCastCompilesFor<Unrelated, MyDerived>");
not_null<Unrelated*> r = p;
not_null<Unrelated*> s = reinterpret_cast<Unrelated*>(p);
#endif
not_null<Unrelated*> t(reinterpret_cast<Unrelated*>(p.get()));
EXPECT_TRUE(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get()));
(void) static_cast<MyDerived*>(p);
(void) static_cast<MyBase*>(p);
}
TEST(notnull_tests, TestNotNullAssignment)
@ -429,6 +505,18 @@ TEST(notnull_tests, TestNotNullCustomPtrComparison)
#if defined(__cplusplus) && (__cplusplus >= 201703L)
template <typename U, typename = void>
static constexpr bool TypeDeductionCtorCompilesFor = false;
template <typename U>
static constexpr bool
TypeDeductionCtorCompilesFor<U, void_t<decltype(not_null{std::declval<U>()})>> = true;
template <typename U, typename = void>
static constexpr bool TypeDeductionHelperCompilesFor = false;
template <typename U>
static constexpr bool
TypeDeductionHelperCompilesFor<U, void_t<decltype(helper(not_null{std::declval<U>()}))>> = true;
TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
{
{
@ -441,6 +529,18 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
EXPECT_TRUE(*x == 42);
}
{
const int i = 42;
not_null x{&i};
static_assert(TypeDeductionHelperCompilesFor<int*>, "TypeDeductionHelperCompilesFor<int*>");
static_assert(!TypeDeductionHelperCompilesFor<const int*>,
"!TypeDeductionHelperCompilesFor<const int*>");
helper_const(not_null{&i});
EXPECT_TRUE(*x == 42);
}
{
int i = 42;
int* p = &i;
@ -452,6 +552,16 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
EXPECT_TRUE(*x == 42);
}
{
const int i = 42;
const int* p = &i;
not_null x{p};
helper_const(not_null{p});
EXPECT_TRUE(*x == 42);
}
const auto terminateHandler = std::set_terminate([] {
std::cerr << "Expected Death. TestNotNullConstructorTypeDeduction";
std::abort();
@ -481,16 +591,35 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
EXPECT_DEATH(helper_const(not_null{p}), expected);
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
not_null x{nullptr};
helper(not_null{nullptr});
helper_const(not_null{nullptr});
}
static_assert(TypeDeductionCtorCompilesFor<void*>, "TypeDeductionCtorCompilesFor<void*>");
#if defined(_MSC_VER) && !defined(__clang__)
// Fails on gcc, clang, xcode, VS clang with
// "error : no type named 'type' in 'std::enable_if<false>'; 'enable_if' cannot be used to
// disable this declaration"
static_assert(!TypeDeductionCtorCompilesFor<std::nullptr_t>,
"!TypeDeductionCtorCompilesFor<std::nullptr_t>");
static_assert(!TypeDeductionHelperCompilesFor<std::nullptr_t>,
"!TypeDeductionHelperCompilesFor<std::nullptr_t>");
#endif
}
TEST(notnull_tests, TestVariantEmplace)
{
int i = 0;
std::variant<std::monostate, not_null<int*>> v;
v.emplace<not_null<int*>>(&i);
EXPECT_FALSE(v.valueless_by_exception());
EXPECT_TRUE(v.index() == 1);
EXPECT_TRUE(std::get<not_null<int*>>(v) == &i);
}
#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
template <typename U, typename = void>
static constexpr bool HelperCompilesFor = false;
template <typename U>
static constexpr bool HelperCompilesFor<U, void_t<decltype(helper(std::declval<U>()))>> = true;
TEST(notnull_tests, TestMakeNotNull)
{
{
@ -503,6 +632,17 @@ TEST(notnull_tests, TestMakeNotNull)
EXPECT_TRUE(*x == 42);
}
{
const int i = 42;
const auto x = make_not_null(&i);
static_assert(HelperCompilesFor<gsl::not_null<int*>>,
"HelperCompilesFor<gsl::not_null<int*>>");
helper_const(make_not_null(&i));
EXPECT_TRUE(*x == 42);
}
{
int i = 42;
int* p = &i;
@ -514,6 +654,18 @@ TEST(notnull_tests, TestMakeNotNull)
EXPECT_TRUE(*x == 42);
}
{
const int i = 42;
const int* p = &i;
const auto x = make_not_null(p);
static_assert(!HelperCompilesFor<gsl::not_null<const int*>>,
"!HelperCompilesFor<gsl::not_null<const int*>>");
helper_const(make_not_null(p));
EXPECT_TRUE(*x == 42);
}
const auto terminateHandler = std::set_terminate([] {
std::cerr << "Expected Death. TestMakeNotNull";
std::abort();
@ -556,15 +708,31 @@ TEST(notnull_tests, TestMakeNotNull)
TEST(notnull_tests, TestStdHash)
{
int x = 42;
int y = 99;
not_null<int*> nn{&x};
const not_null<int*> cnn{&x};
{
int x = 42;
int y = 99;
not_null<int*> nn{&x};
const not_null<int*> cnn{&x};
std::hash<not_null<int*>> hash_nn;
std::hash<int*> hash_intptr;
std::hash<not_null<int*>> hash_nn;
std::hash<int*> hash_intptr;
EXPECT_TRUE(hash_nn(nn) == hash_intptr(&x));
EXPECT_FALSE(hash_nn(nn) == hash_intptr(&y));
EXPECT_FALSE(hash_nn(nn) == hash_intptr(nullptr));
EXPECT_TRUE(hash_nn(nn) == hash_intptr(&x));
EXPECT_FALSE(hash_nn(nn) == hash_intptr(&y));
EXPECT_FALSE(hash_nn(nn) == hash_intptr(nullptr));
}
{
const int x = 42;
const int y = 99;
not_null<const int*> nn{&x};
const not_null<const int*> cnn{&x};
std::hash<not_null<const int*>> hash_nn;
std::hash<const int*> hash_intptr;
EXPECT_TRUE(hash_nn(nn) == hash_intptr(&x));
EXPECT_FALSE(hash_nn(nn) == hash_intptr(&y));
EXPECT_FALSE(hash_nn(nn) == hash_intptr(nullptr));
}
}

View File

@ -17,6 +17,7 @@
#include <gtest/gtest.h>
#include <gsl/pointers> // for owner
#include <type_traits> // for declval
using namespace gsl;
@ -32,12 +33,18 @@ TEST(owner_tests, basic_test)
delete p;
}
TEST(owner_tests, check_pointer_constraint)
{
#ifdef CONFIRM_COMPILATION_ERRORS
{
owner<int> integerTest = 10;
owner<std::shared_ptr<int>> sharedPtrTest(new int(10));
}
#endif
}
#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l
template <typename U, typename = void>
static constexpr bool OwnerCompilesFor = false;
template <typename U>
static constexpr bool OwnerCompilesFor<U, void_t<decltype(gsl::owner<U>{})>> =
true;
static_assert(OwnerCompilesFor<int*>, "OwnerCompilesFor<int*>");
static_assert(!OwnerCompilesFor<int>, "!OwnerCompilesFor<int>");
static_assert(!OwnerCompilesFor<std::shared_ptr<int>>, "!OwnerCompilesFor<std::shared_ptr<int>>");

97
tests/pointers_tests.cpp Normal file
View File

@ -0,0 +1,97 @@
#include <gtest/gtest.h>
#include <gsl/pointers>
#include <memory>
#include <type_traits>
#include <utility>
#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l
namespace
{
// Custom pointer type that can be used for gsl::not_null, but for which these cannot be swapped.
struct NotMoveAssignableCustomPtr
{
NotMoveAssignableCustomPtr() = default;
NotMoveAssignableCustomPtr(const NotMoveAssignableCustomPtr&) = default;
NotMoveAssignableCustomPtr& operator=(const NotMoveAssignableCustomPtr&) = default;
NotMoveAssignableCustomPtr(NotMoveAssignableCustomPtr&&) = default;
NotMoveAssignableCustomPtr& operator=(NotMoveAssignableCustomPtr&&) = delete;
bool operator!=(std::nullptr_t) const { return true; }
int dummy{}; // Without this clang warns, that NotMoveAssignableCustomPtr() is unneeded
};
template <typename U, typename = void>
static constexpr bool SwapCompilesFor = false;
template <typename U>
static constexpr bool
SwapCompilesFor<U, void_t<decltype(gsl::swap<U>(std::declval<gsl::not_null<U>&>(),
std::declval<gsl::not_null<U>&>()))>> = true;
TEST(pointers_test, swap)
{
// taken from gh-1129:
{
gsl::not_null<std::unique_ptr<int>> a(std::make_unique<int>(0));
gsl::not_null<std::unique_ptr<int>> b(std::make_unique<int>(1));
EXPECT_TRUE(*a == 0);
EXPECT_TRUE(*b == 1);
gsl::swap(a, b);
EXPECT_TRUE(*a == 1);
EXPECT_TRUE(*b == 0);
// Make sure our custom ptr can be used with not_null. The shared_pr is to prevent "unused"
// compiler warnings.
const auto shared_custom_ptr{std::make_shared<NotMoveAssignableCustomPtr>()};
gsl::not_null<NotMoveAssignableCustomPtr> c{*shared_custom_ptr};
EXPECT_TRUE(c.get() != nullptr);
}
{
gsl::strict_not_null<std::unique_ptr<int>> a{std::make_unique<int>(0)};
gsl::strict_not_null<std::unique_ptr<int>> b{std::make_unique<int>(1)};
EXPECT_TRUE(*a == 0);
EXPECT_TRUE(*b == 1);
gsl::swap(a, b);
EXPECT_TRUE(*a == 1);
EXPECT_TRUE(*b == 0);
}
{
gsl::not_null<std::unique_ptr<int>> a{std::make_unique<int>(0)};
gsl::strict_not_null<std::unique_ptr<int>> b{std::make_unique<int>(1)};
EXPECT_TRUE(*a == 0);
EXPECT_TRUE(*b == 1);
gsl::swap(a, b);
EXPECT_TRUE(*a == 1);
EXPECT_TRUE(*b == 0);
}
static_assert(!SwapCompilesFor<NotMoveAssignableCustomPtr>,
"!SwapCompilesFor<NotMoveAssignableCustomPtr>");
}
TEST(pointers_test, member_types)
{
static_assert(std::is_same<gsl::not_null<int*>::element_type, int*>::value,
"check member type: element_type");
}
} // namespace

View File

@ -519,7 +519,7 @@ TEST(span_compatibility_tests, assertion_tests)
// assertions for span's definition
static_assert(std::is_same<decltype(gsl::dynamic_extent), const std::size_t>::value,
"gsl::dynamic_extent must be respresented as std::size_t");
"gsl::dynamic_extent must be represented as std::size_t");
static_assert(gsl::dynamic_extent == static_cast<std::size_t>(-1),
"gsl::dynamic_extent must be defined as the max value of std::size_t");
@ -1005,12 +1005,18 @@ static_assert(std::is_convertible<const std::array<int, 3>&, gsl::span<const int
"std::is_convertible<const std::array<int, 3>&, gsl::span<const int>>");
#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l
template <typename U, typename = void>
static constexpr bool AsWritableBytesCompilesFor = false;
template <typename U>
static constexpr bool
AsWritableBytesCompilesFor<U, void_t<decltype(as_writable_bytes(declval<U>()))>> = true;
AsWritableBytesCompilesFor<U, ::void_t<decltype(as_writable_bytes(declval<U>()))>> = true;
static_assert(AsWritableBytesCompilesFor<gsl::span<int>>,
"AsWritableBytesCompilesFor<gsl::span<int>>");
@ -1020,4 +1026,3 @@ static_assert(!AsWritableBytesCompilesFor<gsl::span<const int>>,
"!AsWritableBytesCompilesFor<gsl::span<const int>>");
static_assert(!AsWritableBytesCompilesFor<gsl::span<const int, 9>>,
"!AsWritableBytesCompilesFor<gsl::span<const int, 9>>");
#endif // __cplusplus >= 201703l

View File

@ -19,9 +19,10 @@
#include <gsl/span> // for span and span_ext
#include <gsl/util> // for narrow_cast, at
#include <array> // for array
#include <iostream> // for cerr
#include <vector> // for vector
#include <array> // for array
#include <exception> // for terminate
#include <iostream> // for cerr
#include <vector> // for vector
using namespace std;
using namespace gsl;
@ -193,10 +194,28 @@ TEST(span_ext_test, make_span_from_container_constructor)
TEST(span_test, interop_with_gsl_at)
{
int arr[5] = {1, 2, 3, 4, 5};
gsl::span<int> s{arr};
EXPECT_TRUE(at(s, 0) == 1);
EXPECT_TRUE(at(s, 1) == 2);
std::vector<int> vec{1, 2, 3, 4, 5};
gsl::span<int> sp{vec};
std::vector<int> cvec{1, 2, 3, 4, 5};
gsl::span<int> csp{cvec};
for (gsl::index i = 0; i < gsl::narrow_cast<gsl::index>(vec.size()); ++i)
{
EXPECT_TRUE(&gsl::at(sp, i) == &vec[gsl::narrow_cast<size_t>(i)]);
EXPECT_TRUE(&gsl::at(csp, i) == &cvec[gsl::narrow_cast<size_t>(i)]);
}
const auto terminateHandler = std::set_terminate([] {
std::cerr << "Expected Death. interop_with_gsl_at";
std::abort();
});
const auto expected = GetExpectedDeathString(terminateHandler);
EXPECT_DEATH(gsl::at(sp, -1), expected);
EXPECT_DEATH(gsl::at(sp, gsl::narrow_cast<gsl::index>(sp.size())), expected);
EXPECT_DEATH(gsl::at(csp, -1), expected);
EXPECT_DEATH(gsl::at(csp, gsl::narrow_cast<gsl::index>(sp.size())), expected);
}
TEST(span_ext_test, iterator_free_functions)

View File

@ -40,11 +40,21 @@
#endif // __has_include(<string_view>)
#endif // __has_include
#endif // (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L))
#if defined(__cplusplus) && __cplusplus >= 202002L
#include <span>
#endif // __cplusplus >= 202002L
#include "deathTestCommon.h"
using namespace gsl;
#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l
namespace
{
@ -59,8 +69,7 @@ struct AddressOverloaded
#if (__cplusplus > 201402L)
[[maybe_unused]]
#endif
AddressOverloaded
operator&() const
AddressOverloaded operator&() const
{
return {};
}
@ -213,6 +222,12 @@ TEST(span_test, from_pointer_length_constructor)
TEST(span_test, from_pointer_pointer_construction)
{
// const auto terminateHandler = std::set_terminate([] {
// std::cerr << "Expected Death. from_pointer_pointer_construction";
// std::abort();
// });
// const auto expected = GetExpectedDeathString(terminateHandler);
int arr[4] = {1, 2, 3, 4};
{
@ -242,19 +257,11 @@ TEST(span_test, from_pointer_pointer_construction)
EXPECT_TRUE(s.data() == &arr[0]);
}
// this will fail the std::distance() precondition, which asserts on MSVC debug builds
//{
//{ // this test succeeds on all platforms, gsl::span is more relaxed than std::span where this would be UB
// auto workaround_macro = [&]() { span<int> s{&arr[1], &arr[0]}; };
// EXPECT_DEATH(workaround_macro(), expected);
//}
// this will fail the std::distance() precondition, which asserts on MSVC debug builds
//{
// int* p = nullptr;
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
// EXPECT_DEATH(workaround_macro(), expected);
//}
{
int* p = nullptr;
span<int> s{p, p};
@ -268,19 +275,21 @@ TEST(span_test, from_pointer_pointer_construction)
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr);
}
// this will fail the std::distance() precondition, which asserts on MSVC debug builds
//{
// int* p = nullptr;
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
// EXPECT_DEATH(workaround_macro(), expected);
//}
}
template <typename U, typename V, typename = void>
static constexpr bool CtorCompilesFor = false;
template <typename U, typename V>
static constexpr bool CtorCompilesFor<U, V, void_t<decltype(U{std::declval<V>()})>> = true;
TEST(span_test, from_array_constructor)
{
int arr[5] = {1, 2, 3, 4, 5};
static_assert(!CtorCompilesFor<span<int, 6>, int[5]>, "!CtorCompilesFor<span<int, 6>, int[5]>");
static_assert(!CtorCompilesFor<span<int, 0>, int[5]>, "!CtorCompilesFor<span<int, 0>, int[5]>");
static_assert(!CtorCompilesFor<span<int>, int[2][3]>, "!CtorCompilesFor<span<int>, int[2][3]>");
{
const span<int> s{arr};
EXPECT_TRUE(s.size() == 5);
@ -295,70 +304,28 @@ TEST(span_test, from_array_constructor)
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
#ifdef CONFIRM_COMPILATION_ERRORS
{
span<int, 6> s{arr};
}
static_assert(!CtorCompilesFor<span<int, 0>, int[2][3]>,
"!CtorCompilesFor<span<int, 0>, int[2][3]>");
static_assert(!CtorCompilesFor<span<int, 6>, int[2][3]>,
"!CtorCompilesFor<span<int, 6>, int[2][3]>");
{
span<int, 0> s{arr};
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == &arr[0]);
}
{
span<int> s{arr2d};
EXPECT_TRUE(s.size() == 6);
EXPECT_TRUE(s.data() == &arr2d[0][0]);
EXPECT_TRUE(s[0] == 1);
EXPECT_TRUE(s[5] == 6);
}
{
span<int, 0> s{arr2d};
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == &arr2d[0][0]);
}
{
span<int, 6> s{arr2d};
}
#endif
{
const span<int[3]> s{std::addressof(arr2d[0]), 1};
EXPECT_TRUE(s.size() == 1);
EXPECT_TRUE(s.data() == std::addressof(arr2d[0]));
}
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int arr3d[2][3][2] = {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}};
#ifdef CONFIRM_COMPILATION_ERRORS
{
span<int> s{arr3d};
EXPECT_TRUE(s.size() == 12);
EXPECT_TRUE(s.data() == &arr3d[0][0][0]);
EXPECT_TRUE(s[0] == 1);
EXPECT_TRUE(s[11] == 12);
}
static_assert(!CtorCompilesFor<span<int>, int[2][3][2]>,
"!CtorCompilesFor<span<int>, int[2][3][2]>");
static_assert(!CtorCompilesFor<span<int, 0>, int[2][3][2]>,
"!CtorCompilesFor<span<int, 0>, int[2][3][2]>");
static_assert(!CtorCompilesFor<span<int, 11>, int[2][3][2]>,
"!CtorCompilesFor<span<int, 11>, int[2][3][2]>");
static_assert(!CtorCompilesFor<span<int, 12>, int[2][3][2]>,
"!CtorCompilesFor<span<int, 12>, int[2][3][2]>");
{
span<int, 0> s{arr3d};
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == &arr3d[0][0][0]);
}
{
span<int, 11> s{arr3d};
}
{
span<int, 12> s{arr3d};
EXPECT_TRUE(s.size() == 12);
EXPECT_TRUE(s.data() == &arr3d[0][0][0]);
EXPECT_TRUE(s[0] == 1);
EXPECT_TRUE(s[5] == 6);
}
#endif
{
const span<int[3][2]> s{std::addressof(arr3d[0]), 1};
EXPECT_TRUE(s.size() == 1);
@ -386,6 +353,13 @@ TEST(span_test, from_dynamic_array_constructor)
delete[] arr;
}
template <typename U, typename V, typename = void>
static constexpr bool ConversionCompilesFor = false;
template <typename U, typename V>
static constexpr bool
ConversionCompilesFor<U, V, void_t<decltype(std::declval<void (*)(U)>()(std::declval<V>()))>> =
true;
TEST(span_test, from_std_array_constructor)
{
std::array<int, 4> arr = {1, 2, 3, 4};
@ -425,43 +399,31 @@ TEST(span_test, from_std_array_constructor)
EXPECT_TRUE(ao_arr.data() == fs.data());
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
span<int, 2> s{arr};
EXPECT_TRUE(s.size() == 2);
EXPECT_TRUE(s.data() == arr.data());
static_assert(!CtorCompilesFor<span<int, 2>, std::array<int, 4>&>,
"!CtorCompilesFor<span<int, 2>, std::array<int, 4>&>");
static_assert(!CtorCompilesFor<span<const int, 2>, std::array<int, 4>&>,
"!CtorCompilesFor<span<const int, 2>, std::array<int, 4>&>");
span<const int, 2> cs{arr};
EXPECT_TRUE(cs.size() == 2);
EXPECT_TRUE(cs.data() == arr.data());
}
static_assert(!CtorCompilesFor<span<int, 0>, std::array<int, 4>&>,
"!CtorCompilesFor<span<int, 0>, std::array<int, 4>&>");
static_assert(!CtorCompilesFor<span<const int, 0>, std::array<int, 4>&>,
"!CtorCompilesFor<span<const int, 0>, std::array<int, 4>&>");
{
span<int, 0> s{arr};
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == arr.data());
static_assert(!CtorCompilesFor<span<int, 5>, std::array<int, 4>&>,
"!CtorCompilesFor<span<int, 5>, std::array<int, 4>&>");
span<const int, 0> cs{arr};
EXPECT_TRUE(cs.size() == 0);
EXPECT_TRUE(cs.data() == arr.data());
}
{
span<int, 5> s{arr};
}
{
auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; };
auto take_a_span = [](span<int> s) { static_cast<void>(s); };
// try to take a temporary std::array
take_a_span(get_an_array());
}
#if !defined(_MSC_VER) || (_MSC_VER > 1943) || (__cplusplus >= 201703L)
// Fails on "Visual Studio 16 2019/Visual Studio 17 2022, windows-2019/2022, Debug/Release, 14".
static_assert(!ConversionCompilesFor<span<int>, std::array<int, 4>>,
"!ConversionCompilesFor<span<int>, std::array<int, 4>>");
#endif
{
auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; };
auto take_a_span = [](span<const int> s) { static_cast<void>(s); };
auto take_a_span = [](span<const int>) {};
// try to take a temporary std::array
static_assert(ConversionCompilesFor<span<const int>, std::array<int, 4>>,
"ConversionCompilesFor<span<const int>, std::array<int, 4>>");
take_a_span(get_an_array());
}
}
@ -490,23 +452,12 @@ TEST(span_test, from_const_std_array_constructor)
EXPECT_TRUE(s.data() == ao_arr.data());
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
span<const int, 2> s{arr};
EXPECT_TRUE(s.size() == 2);
EXPECT_TRUE(s.data() == arr.data());
}
{
span<const int, 0> s{arr};
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == arr.data());
}
{
span<const int, 5> s{arr};
}
#endif
static_assert(!CtorCompilesFor<span<const int, 2>, std::array<int, 4>&>,
"!CtorCompilesFor<span<const int, 2>, std::array<int, 4>&>");
static_assert(!CtorCompilesFor<span<const int, 0>, std::array<int, 4>&>,
"!CtorCompilesFor<span<const int, 0>, std::array<int, 4>&>");
static_assert(!CtorCompilesFor<span<int, 5>, std::array<int, 4>&>,
"!CtorCompilesFor<span<int, 5>, std::array<int, 4>&>");
{
auto get_an_array = []() -> const std::array<int, 4> { return {1, 2, 3, 4}; };
@ -532,27 +483,14 @@ TEST(span_test, from_std_array_const_constructor)
EXPECT_TRUE(s.data() == arr.data());
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
span<const int, 2> s{arr};
EXPECT_TRUE(s.size() == 2);
EXPECT_TRUE(s.data() == arr.data());
}
{
span<const int, 0> s{arr};
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == arr.data());
}
{
span<const int, 5> s{arr};
}
{
span<int, 4> s{arr};
}
#endif
static_assert(!CtorCompilesFor<span<const int, 2>, const std::array<int, 4>&>,
"!CtorCompilesFor<span<const int, 2>, const std::array<int, 4>&>");
static_assert(!CtorCompilesFor<span<const int, 0>, const std::array<int, 4>&>,
"!CtorCompilesFor<span<const int, 0>, const std::array<int, 4>&>");
static_assert(!CtorCompilesFor<span<const int, 5>, const std::array<int, 4>&>,
"!CtorCompilesFor<span<const int, 5>, const std::array<int, 4>&>");
static_assert(!CtorCompilesFor<span<int, 5>, const std::array<int, 4>&>,
"!CtorCompilesFor<span<int, 5>, const std::array<int, 4>&>");
}
TEST(span_test, from_container_constructor)
@ -574,32 +512,28 @@ TEST(span_test, from_container_constructor)
const std::string cstr = "hello";
{
#ifdef CONFIRM_COMPILATION_ERRORS
span<char> s{str};
EXPECT_TRUE(s.size() == str.size());
EXPECT_TRUE(s.data() == str.data()));
#endif
span<const char> cs{str};
EXPECT_TRUE(cs.size() == str.size());
EXPECT_TRUE(cs.data() == str.data());
static_assert(CtorCompilesFor<span<char>, std::string&> == (__cplusplus >= 201703L),
"CtorCompilesFor<span<char>, std::string&> == (__cplusplus >= 201703L)");
span<const char> cs{str};
EXPECT_TRUE(cs.size() == str.size());
EXPECT_TRUE(cs.data() == str.data());
}
{
#ifdef CONFIRM_COMPILATION_ERRORS
span<char> s{cstr};
#endif
static_assert(!CtorCompilesFor<span<char>, const std::string&>,
"!CtorCompilesFor<span<char>, const std::string&>");
span<const char> cs{cstr};
EXPECT_TRUE(cs.size() == cstr.size());
EXPECT_TRUE(cs.data() == cstr.data());
}
{
#ifdef CONFIRM_COMPILATION_ERRORS
auto get_temp_vector = []() -> std::vector<int> { return {}; };
auto use_span = [](span<int> s) { static_cast<void>(s); };
use_span(get_temp_vector());
#endif
}
#if !defined(_MSC_VER) || (_MSC_VER > 1943) || (__cplusplus >= 201703L)
// Fails on "Visual Studio 16 2019/Visual Studio 17 2022, windows-2019/2022, Debug/Release, 14".
static_assert(!ConversionCompilesFor<span<int>, std::vector<int>>,
"!ConversionCompilesFor<span<int>, std::vector<int>>");
#endif // !defined(_MSC_VER) || (_MSC_VER > 1942) || (__cplusplus >= 201703L)
{
auto get_temp_vector = []() -> std::vector<int> { return {}; };
@ -607,13 +541,8 @@ TEST(span_test, from_container_constructor)
use_span(get_temp_vector());
}
{
#ifdef CONFIRM_COMPILATION_ERRORS
auto get_temp_string = []() -> std::string { return {}; };
auto use_span = [](span<char> s) { static_cast<void>(s); };
use_span(get_temp_string());
#endif
}
static_assert(!ConversionCompilesFor<span<char>, std::string>,
"!ConversionCompilesFor<span<char>, std::string>");
{
auto get_temp_string = []() -> std::string { return {}; };
@ -621,13 +550,10 @@ TEST(span_test, from_container_constructor)
use_span(get_temp_string());
}
{
#ifdef CONFIRM_COMPILATION_ERRORS
auto get_temp_vector = []() -> const std::vector<int> { return {}; };
auto use_span = [](span<const char> s) { static_cast<void>(s); };
use_span(get_temp_vector());
#endif
}
static_assert(!ConversionCompilesFor<span<const char>, const std::vector<int>>,
"!ConversionCompilesFor<span<const char>, const std::vector<int>>");
static_assert(!ConversionCompilesFor<span<char>, const std::string>,
"!ConversionCompilesFor<span<char>, const std::string>");
{
auto get_temp_string = []() -> const std::string { return {}; };
@ -635,46 +561,73 @@ TEST(span_test, from_container_constructor)
use_span(get_temp_string());
}
static_assert(!CtorCompilesFor<span<int>, std::map<int, int>&>,
"!CtorCompilesFor<span<int>, std::map<int, int>&>");
}
TEST(span_test, from_convertible_span_constructor)
{
const auto terminateHandler = std::set_terminate([] {
std::cerr << "Expected Death. from_convertible_span_constructor";
std::abort();
});
const auto expected = GetExpectedDeathString(terminateHandler);
{
#ifdef CONFIRM_COMPILATION_ERRORS
std::map<int, int> m;
span<int> s{m};
#endif
span<DerivedClass> avd;
span<const DerivedClass> avcd = avd;
static_cast<void>(avcd);
}
}
TEST(span_test, from_convertible_span_constructor){{span<DerivedClass> avd;
span<const DerivedClass> avcd = avd;
static_cast<void>(avcd);
}
{
std::array<DerivedClass, 2> arr{};
span<DerivedClass, 2> avd{arr};
span<const DerivedClass, 2> avcd = avd;
static_cast<void>(avcd);
}
{
#ifdef CONFIRM_COMPILATION_ERRORS
span<DerivedClass> avd;
span<BaseClass> avb = avd;
static_cast<void>(avb);
#endif
}
{
std::array<DerivedClass, 2> arr{};
span<DerivedClass, 2> avd{arr};
span<const DerivedClass> avcd = avd;
static_cast<void>(avcd);
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
span<int> s;
span<unsigned int> s2 = s;
static_cast<void>(s2);
}
{
std::array<DerivedClass, 2> arr{};
span<DerivedClass> avd{arr};
span<const DerivedClass, 2> avcd{avd};
static_cast<void>(avcd);
}
{
span<int> s;
span<const unsigned int> s2 = s;
static_cast<void>(s2);
}
{
std::array<DerivedClass, 2> arr{};
span<DerivedClass> avd{arr};
using T = span<const DerivedClass, 1>;
EXPECT_DEATH(T{avd}, expected);
}
{
span<int> s;
span<short> s2 = s;
static_cast<void>(s2);
}
#endif
{
std::array<DerivedClass, 1> arr{};
span<DerivedClass> avd{arr};
using T = span<const DerivedClass, 2>;
EXPECT_DEATH(T{avd}, expected);
}
static_assert(!ConversionCompilesFor<span<const DerivedClass, 2>, span<DerivedClass>&>,
"!ConversionCompilesFor<span<const DerivedClass, 2>, span<DerivedClass>&>");
static_assert(!ConversionCompilesFor<span<const DerivedClass, 1>, span<DerivedClass, 2>&>,
"!ConversionCompilesFor<span<const DerivedClass, 1>, span<DerivedClass, 2>&>");
static_assert(!ConversionCompilesFor<span<const DerivedClass, 3>, span<DerivedClass, 2>&>,
"!ConversionCompilesFor<span<const DerivedClass, 3>, span<DerivedClass, 2>&>");
static_assert(!ConversionCompilesFor<span<BaseClass, 3>, span<DerivedClass>&>,
"!ConversionCompilesFor<span<BaseClass, 3>, span<DerivedClass>&>");
static_assert(!ConversionCompilesFor<span<unsigned int>, span<int>&>,
"!ConversionCompilesFor<span<unsigned int>, span<int>&>");
static_assert(!ConversionCompilesFor<span<const unsigned int>, span<int>&>,
"!ConversionCompilesFor<span<const unsigned int>, span<int>&>");
static_assert(!ConversionCompilesFor<span<short>, span<int>&>,
"!ConversionCompilesFor<span<short>, span<int>&>");
}
TEST(span_test, copy_move_and_assignment)
@ -734,10 +687,9 @@ TEST(span_test, first)
{
span<int, 5> av = arr;
#ifdef CONFIRM_COMPILATION_ERRORS
EXPECT_TRUE(av.first<6>().size() == 6);
EXPECT_TRUE(av.first<-1>().size() == -1);
(void) av.first<6>();
#endif
EXPECT_DEATH(av.first(6).size(), expected);
EXPECT_DEATH(av.first(6), expected);
}
{
@ -778,9 +730,9 @@ TEST(span_test, last)
{
span<int, 5> av = arr;
#ifdef CONFIRM_COMPILATION_ERRORS
EXPECT_TRUE(av.last<6>().size() == 6);
(void) av.last<6>();
#endif
EXPECT_DEATH(av.last(6).size(), expected);
EXPECT_DEATH(av.last(6), expected);
}
{
@ -805,6 +757,9 @@ TEST(span_test, subspan)
EXPECT_TRUE((av.subspan<2, 2>().size()) == 2);
EXPECT_TRUE(decltype(av.subspan<2, 2>())::extent == 2);
EXPECT_TRUE(av.subspan(2, 2).size() == 2);
EXPECT_TRUE((av.subspan<2, 3>().size()) == 3);
EXPECT_TRUE(decltype(av.subspan<2, 3>())::extent == 3);
EXPECT_TRUE(av.subspan(2, 3).size() == 3);
}
@ -821,8 +776,12 @@ TEST(span_test, subspan)
EXPECT_TRUE(decltype(av.subspan<0, 5>())::extent == 5);
EXPECT_TRUE(av.subspan(0, 5).size() == 5);
EXPECT_DEATH(av.subspan(0, 6).size(), expected);
EXPECT_DEATH(av.subspan(1, 5).size(), expected);
#ifdef CONFIRM_COMPILATION_ERRORS
(void) av.subspan<0, 6>();
(void) av.subspan<1, 5>();
#endif
EXPECT_DEATH(av.subspan(0, 6), expected);
EXPECT_DEATH(av.subspan(1, 5), expected);
}
{
@ -830,14 +789,22 @@ TEST(span_test, subspan)
EXPECT_TRUE((av.subspan<4, 0>().size()) == 0);
EXPECT_TRUE(decltype(av.subspan<4, 0>())::extent == 0);
EXPECT_TRUE(av.subspan(4, 0).size() == 0);
EXPECT_TRUE((av.subspan<5, 0>().size()) == 0);
EXPECT_TRUE(decltype(av.subspan<5, 0>())::extent == 0);
EXPECT_TRUE(av.subspan(5, 0).size() == 0);
EXPECT_DEATH(av.subspan(6, 0).size(), expected);
#ifdef CONFIRM_COMPILATION_ERRORS
(void) av.subspan<6, 0>();
#endif
EXPECT_DEATH(av.subspan(6, 0), expected);
}
{
span<int, 5> av = arr;
EXPECT_TRUE(av.subspan<1>().size() == 4);
EXPECT_TRUE(decltype(av.subspan<1>())::extent == 4);
EXPECT_TRUE(av.subspan(1).size() == 4);
}
{
@ -845,35 +812,58 @@ TEST(span_test, subspan)
EXPECT_TRUE((av.subspan<0, 0>().size()) == 0);
EXPECT_TRUE(decltype(av.subspan<0, 0>())::extent == 0);
EXPECT_TRUE(av.subspan(0, 0).size() == 0);
EXPECT_DEATH((av.subspan<1, 0>().size()), expected);
EXPECT_DEATH((av.subspan<1, 0>()), expected);
EXPECT_DEATH((av.subspan(1, 0)), expected);
}
{
span<int> av;
EXPECT_TRUE((av.subspan<0>().size()) == 0);
EXPECT_TRUE(decltype(av.subspan<0>())::extent == dynamic_extent);
EXPECT_TRUE(av.subspan(0).size() == 0);
EXPECT_DEATH(av.subspan(1).size(), expected);
EXPECT_DEATH(av.subspan<1>(), expected);
EXPECT_TRUE(decltype(av.subspan<1>())::extent == dynamic_extent);
EXPECT_DEATH(av.subspan(1), expected);
}
{
span<int> av = arr;
EXPECT_TRUE(av.subspan(0).size() == 5);
EXPECT_TRUE(av.subspan<0>().size() == 5);
EXPECT_TRUE(av.subspan(1).size() == 4);
EXPECT_TRUE(av.subspan<1>().size() == 4);
EXPECT_TRUE(av.subspan(4).size() == 1);
EXPECT_TRUE(av.subspan<4>().size() == 1);
EXPECT_TRUE(av.subspan(5).size() == 0);
EXPECT_DEATH(av.subspan(6).size(), expected);
EXPECT_TRUE(av.subspan<5>().size() == 0);
EXPECT_DEATH(av.subspan(6), expected);
EXPECT_DEATH(av.subspan<6>(), expected);
const auto av2 = av.subspan(1);
for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2);
const auto av3 = av.subspan<1>();
for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av3[i] == static_cast<int>(i) + 2);
}
{
span<int, 5> av = arr;
EXPECT_TRUE(av.subspan(0).size() == 5);
EXPECT_TRUE(av.subspan<0>().size() == 5);
EXPECT_TRUE(av.subspan(1).size() == 4);
EXPECT_TRUE(av.subspan<1>().size() == 4);
EXPECT_TRUE(av.subspan(4).size() == 1);
EXPECT_TRUE(av.subspan<4>().size() == 1);
EXPECT_TRUE(av.subspan(5).size() == 0);
EXPECT_DEATH(av.subspan(6).size(), expected);
EXPECT_TRUE(av.subspan<5>().size() == 0);
EXPECT_DEATH(av.subspan(6), expected);
#ifdef CONFIRM_COMPILATION_ERRORS
EXPECT_DEATH(av.subspan<6>(), expected);
#endif
const auto av2 = av.subspan(1);
for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2);
const auto av3 = av.subspan<1>();
for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av3[i] == static_cast<int>(i) + 2);
}
}
@ -1048,15 +1038,21 @@ TEST(span_test, rbegin_rend)
}
}
template <typename U, typename = void>
static constexpr bool AsWritableBytesCompilesFor = false;
template <typename U>
static constexpr bool
AsWritableBytesCompilesFor<U, void_t<decltype(as_writable_bytes(std::declval<U>()))>> = true;
TEST(span_test, as_bytes)
{
const auto terminateHandler = std::set_terminate([] {
std::cerr << "Expected Death. as_bytes";
std::abort();
});
const auto expected = GetExpectedDeathString(terminateHandler);
int a[] = {1, 2, 3, 4};
static_assert(AsWritableBytesCompilesFor<span<int>>, "AsWriteableBytesCompilesFor<span<int>>");
// you should not be able to get writeable bytes for const objects
static_assert(!AsWritableBytesCompilesFor<span<const int>>,
"!AsWriteableBytesCompilesFor<span<const int>>");
{
const span<const int> s = a;
EXPECT_TRUE(s.size() == 4);
@ -1081,29 +1077,12 @@ TEST(span_test, as_bytes)
EXPECT_TRUE(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
EXPECT_TRUE(bs.size() == s.size_bytes());
}
int b[5] = {1, 2, 3, 4, 5};
{
span<int> sp(std::begin(b), static_cast<size_t>(-2));
EXPECT_DEATH((void) sp.size_bytes(), expected);
}
}
TEST(span_test, as_writable_bytes)
{
int a[] = {1, 2, 3, 4};
{
#ifdef CONFIRM_COMPILATION_ERRORS
// you should not be able to get writeable bytes for const objects
span<const int> s = a;
EXPECT_TRUE(s.size() == 4);
span<const byte> bs = as_writable_bytes(s);
EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
EXPECT_TRUE(bs.size() == s.size_bytes());
#endif
}
{
span<int> s;
const auto bs = as_writable_bytes(s);
@ -1143,30 +1122,15 @@ TEST(span_test, fixed_size_conversions)
static_cast<void>(s);
}
// initialization or assignment to static span that REDUCES size is NOT ok
#ifdef CONFIRM_COMPILATION_ERRORS
{
span<int, 2> s = arr;
}
{
span<int, 2> s2 = s4;
static_cast<void>(s2);
}
#endif
// initialization or assignment to static span that REDUCES size is NOT ok
static_assert(!ConversionCompilesFor<span<int, 2>, int[4]>,
"!ConversionCompilesFor<span<int, 2>, int[4]>");
static_assert(!ConversionCompilesFor<span<int, 2>, span<int, 4>>,
"!ConversionCompilesFor<span<int, 2>, span<int, 4>>");
// even when done dynamically
{
/*
// this now results in a compile-time error, rather than runtime.
// There is no suitable conversion from dynamic span to fixed span.
span<int> s = arr;
auto f = [&]() {
const span<int, 2> s2 = s;
static_cast<void>(s2);
};
EXPECT_DEATH(f(), expected);
*/
}
static_assert(!ConversionCompilesFor<span<int, 2>, span<int>>,
"!ConversionCompilesFor<span<int, 2>, span<int>>");
// but doing so explicitly is ok
@ -1180,32 +1144,24 @@ TEST(span_test, fixed_size_conversions)
static_cast<void>(s1);
}
/*
// this is not a legal operation in std::span, so we are no longer supporting it
// conversion from span<int, 4> to span<int, dynamic_extent> via call to `first`
// then convert from span<int, dynamic_extent> to span<int, 1>
// The dynamic to fixed extents are not supported in the standard
// to make this work, span<int, 1> would need to be span<int>.
{
// NB: implicit conversion to span<int,1> from span<int>
span<int, 1> s1 = s4.first(1);
static_cast<void>(s1);
}
*/
// this is not a legal operation in std::span, so we are no longer supporting it
// conversion from span<int, 4> to span<int, dynamic_extent> via call to `first`
// then convert from span<int, dynamic_extent> to span<int, 1>
// The dynamic to fixed extents are not supported in the standard
// to make this work, span<int, 1> would need to be span<int>.
static_assert(!ConversionCompilesFor<span<int, 1>, span<int>>,
"!ConversionCompilesFor<span<int, 1>, span<int>>");
// initialization or assignment to static span that requires size INCREASE is not ok.
int arr2[2] = {1, 2};
#ifdef CONFIRM_COMPILATION_ERRORS
{
span<int, 4> s3 = arr2;
}
{
span<int, 2> s2 = arr2;
span<int, 4> s4a = s2;
}
#endif
static_assert(!ConversionCompilesFor<span<int, 4>, int[2]>,
"!ConversionCompilesFor<span<int, 4>, int[2]>");
static_assert(!ConversionCompilesFor<span<int, 2>, int[2]>,
"!ConversionCompilesFor<span<int, 2>, int[2]>");
static_assert(!ConversionCompilesFor<span<int, 4>, span<int, 2>>,
"!ConversionCompilesFor<span<int, 4>, span<int, 2>>");
{
auto f = [&]() {
const span<int, 4> _s4{arr2, 2};
@ -1214,16 +1170,11 @@ TEST(span_test, fixed_size_conversions)
EXPECT_DEATH(f(), expected);
}
/*
// This no longer compiles. There is no suitable conversion from dynamic span to a fixed size
span.
// this should fail - we are trying to assign a small dynamic span to a fixed_size larger one
span<int> av = arr2; auto f = [&]() {
const span<int, 4> _s4 = av;
static_cast<void>(_s4);
};
EXPECT_DEATH(f(), expected);
*/
// This no longer compiles. There is no suitable conversion from dynamic span to a fixed size
// span.
// this should fail - we are trying to assign a small dynamic span to a fixed_size larger one
static_assert(!ConversionCompilesFor<span<int, 4>, span<int>>,
"!ConversionCompilesFor<span<int, 4>, span<int>>");
}
TEST(span_test, interop_with_std_regex)
@ -1297,3 +1248,179 @@ TEST(span_test, front_back)
EXPECT_DEATH(s2.front(), expected);
EXPECT_DEATH(s2.back(), expected);
}
#if defined(FORCE_STD_SPAN_TESTS) || defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
TEST(span_test, std_span)
{
// make sure std::span can be constructed from gsl::span
int arr[5] = {1, 2, 3, 4, 5};
gsl::span<int> gsl_span{arr};
#if defined(__cpp_lib_ranges) || (defined(_MSVC_STL_VERSION) && defined(__cpp_lib_concepts))
EXPECT_TRUE(std::to_address(gsl_span.begin()) == gsl_span.data());
EXPECT_TRUE(std::to_address(gsl_span.end()) == gsl_span.data() + gsl_span.size());
#endif // __cpp_lib_ranges
std::span<int> std_span = gsl_span;
EXPECT_TRUE(std_span.data() == gsl_span.data());
EXPECT_TRUE(std_span.size() == gsl_span.size());
}
#endif // defined(FORCE_STD_SPAN_TESTS) || defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
#if defined(__cpp_lib_span) && defined(__cpp_lib_ranges)
// This test covers the changes in PR #1100
TEST(span_test, msvc_compile_error_PR1100)
{
int arr[]{1, 7, 2, 9};
gsl::span sp{arr, std::size(arr)};
std::ranges::sort(sp);
for (const auto& e : sp) { (void) e; }
}
#endif // defined(__cpp_lib_span) && defined(__cpp_lib_ranges)
TEST(span_test, empty_span)
{
span<int> s{};
EXPECT_TRUE(s.empty());
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr);
span<const int> cs{};
EXPECT_TRUE(cs.empty());
EXPECT_TRUE(cs.size() == 0);
EXPECT_TRUE(cs.data() == nullptr);
}
TEST(span_test, conversions)
{
int arr[5] = {1, 2, 3, 4, 5};
#if defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L)
span s = arr;
span cs = s;
#else
span<int, 5> s = arr;
span<int, 5> cs = s;
#endif
EXPECT_TRUE(cs.size() == s.size());
EXPECT_TRUE(cs.data() == s.data());
span<int, 5> fs = s;
EXPECT_TRUE(fs.size() == s.size());
EXPECT_TRUE(fs.data() == s.data());
span<const int, 5> cfs = s;
EXPECT_TRUE(cfs.size() == s.size());
EXPECT_TRUE(cfs.data() == s.data());
}
TEST(span_test, comparison_operators)
{
int arr1[3] = {1, 2, 3};
int arr2[3] = {1, 2, 3};
int arr3[3] = {4, 5, 6};
span<int> s1 = arr1;
span<int> s2 = arr2;
span<int> s3 = arr3;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 == s3);
EXPECT_TRUE(s1 != s3);
EXPECT_TRUE(s1 < s3);
EXPECT_FALSE(s3 < s1);
EXPECT_TRUE(s1 <= s2);
EXPECT_TRUE(s1 <= s3);
EXPECT_FALSE(s3 <= s1);
EXPECT_TRUE(s3 > s1);
EXPECT_FALSE(s1 > s3);
EXPECT_TRUE(s3 >= s1);
EXPECT_TRUE(s1 >= s2);
EXPECT_FALSE(s1 >= s3);
}
// ...existing code...
#if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
#include <span> // for std::span
TEST(span_test, compare_empty_span)
{
gsl::span<int> gsl_s{};
std::span<int> std_s{};
EXPECT_TRUE(gsl_s.empty());
EXPECT_TRUE(std_s.empty());
EXPECT_EQ(gsl_s.size(), std_s.size());
EXPECT_EQ(gsl_s.data(), std_s.data());
}
TEST(span_test, compare_subspan)
{
int arr[5] = {1, 2, 3, 4, 5};
gsl::span gsl_s = arr;
std::span std_s = arr;
auto gsl_sub1 = gsl_s.subspan(1);
auto std_sub1 = std_s.subspan(1);
EXPECT_EQ(gsl_sub1.size(), std_sub1.size());
EXPECT_EQ(gsl_sub1.data(), std_sub1.data());
auto gsl_sub2 = gsl_s.subspan(1, 2);
auto std_sub2 = std_s.subspan(1, 2);
EXPECT_EQ(gsl_sub2.size(), std_sub2.size());
EXPECT_EQ(gsl_sub2.data(), std_sub2.data());
}
TEST(span_test, compare_conversions)
{
int arr[5] = {1, 2, 3, 4, 5};
gsl::span gsl_s = arr;
std::span std_s = arr;
gsl::span gsl_cs = gsl_s;
std::span std_cs = std_s;
EXPECT_EQ(gsl_cs.size(), std_cs.size());
EXPECT_EQ(gsl_cs.data(), std_cs.data());
gsl::span<int, 5> gsl_fs = gsl_s;
std::span<int, 5> std_fs = std_s;
EXPECT_EQ(gsl_fs.size(), std_fs.size());
EXPECT_EQ(gsl_fs.data(), std_fs.data());
gsl::span<const int, 5> gsl_cfs = gsl_s;
std::span<const int, 5> std_cfs = std_s;
EXPECT_EQ(gsl_cfs.size(), std_cfs.size());
EXPECT_EQ(gsl_cfs.data(), std_cfs.data());
}
TEST(span_test, deduction_guides)
{
int arr[5] = {1, 2, 3, 4, 5};
std::array<int, 5> std_arr = {1, 2, 3, 4, 5};
std::vector<int> vec = {1, 2, 3, 4, 5};
// Test deduction guides for gsl::span
gsl::span gsl_s1 = arr;
gsl::span gsl_s2 = std_arr;
gsl::span gsl_s3 = vec;
// Test deduction guides for std::span (for sanity checks)
std::span std_s1 = arr;
std::span std_s2 = std_arr;
std::span std_s3 = vec;
// Compare sizes
EXPECT_EQ(gsl_s1.size(), std_s1.size());
EXPECT_EQ(gsl_s2.size(), std_s2.size());
EXPECT_EQ(gsl_s3.size(), std_s3.size());
// Compare data pointers
EXPECT_EQ(gsl_s1.data(), std_s1.data());
EXPECT_EQ(gsl_s2.data(), std_s2.data());
EXPECT_EQ(gsl_s3.data(), std_s3.data());
}
#endif // defined(__cpp_lib_span) && __cpp_lib_span >= 202002L

View File

@ -17,10 +17,28 @@
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
#include <gtest/gtest.h>
#include <type_traits> // for declval
#include "deathTestCommon.h"
using namespace gsl;
#if __cplusplus >= 201703l
using std::void_t;
#else // __cplusplus >= 201703l
template <class...>
using void_t = void;
#endif // __cplusplus < 201703l
// stand-in for a user-defined ref-counted class
template <typename T>
struct RefCounted
{
RefCounted(T* p) : p_(p) {}
operator T*() { return p_; }
T* p_;
};
namespace
{
// clang-format off
@ -43,12 +61,154 @@ GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
// clang-format on
bool strict_helper_const(strict_not_null<const int*> p) { return *p == 12; }
#ifdef CONFIRM_COMPILATION_ERRORS
int* return_pointer() { return nullptr; }
const int* return_pointer_const() { return nullptr; }
#endif
} // namespace
template <typename U, typename = void>
static constexpr bool CtorCompilesFor_A = false;
template <typename U>
static constexpr bool
CtorCompilesFor_A<U, void_t<decltype(gsl::strict_not_null<void*>{std::declval<U>()})>> = true;
template <typename U, int N, typename = void>
static constexpr bool CtorCompilesFor_B = false;
template <typename U, int N>
static constexpr bool CtorCompilesFor_B<U, N, void_t<decltype(gsl::strict_not_null<U>{N})>> = true;
template <typename U, typename = void>
static constexpr bool DefaultCtorCompilesFor = false;
template <typename U>
static constexpr bool DefaultCtorCompilesFor<U, void_t<decltype(gsl::strict_not_null<U>{})>> = true;
template <typename U, typename = void>
static constexpr bool CtorCompilesFor_C = false;
template <typename U>
static constexpr bool CtorCompilesFor_C<
U, void_t<decltype(gsl::strict_not_null<U*>{std::declval<std::unique_ptr<U>>()})>> = true;
TEST(strict_notnull_tests, TestStrictNotNullConstructors)
{
{
static_assert(CtorCompilesFor_A<void*>, "CtorCompilesFor_A<void*>");
static_assert(!CtorCompilesFor_A<std::nullptr_t>, "!CtorCompilesFor_A<std::nullptr_t>");
static_assert(!CtorCompilesFor_B<void*, 0>, "!CtorCompilesFor_B<void*, 0>");
static_assert(!DefaultCtorCompilesFor<void*>, "!DefaultCtorCompilesFor<void*>");
static_assert(!CtorCompilesFor_C<int>, "CtorCompilesFor_C<int>");
#ifdef CONFIRM_COMPILATION_ERRORS
// Forbid non-nullptr assignable types
strict_not_null<std::vector<int>> f(std::vector<int>{1});
strict_not_null<int> z(10);
strict_not_null<std::vector<int>> y({1, 2});
#endif
}
const auto terminateHandler = std::set_terminate([] {
std::cerr << "Expected Death. TestNotNullConstructors";
std::abort();
});
const auto expected = GetExpectedDeathString(terminateHandler);
{
// from shared pointer
int i = 12;
auto rp = RefCounted<int>(&i);
strict_not_null<int*> p(rp);
EXPECT_TRUE(p.get() == &i);
strict_not_null<std::shared_ptr<int>> x(
std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
int* pi = nullptr;
EXPECT_DEATH((strict_not_null<decltype(pi)>(pi)), expected);
}
{
// from unique pointer
strict_not_null<std::unique_ptr<int>> x(
std::make_unique<int>(10)); // unique_ptr<int> is nullptr assignable
EXPECT_DEATH((strict_not_null<std::unique_ptr<int>>(std::unique_ptr<int>{})), expected);
}
{
// from pointer to local
int t = 42;
strict_not_null<int*> x{&t};
helper(&t);
helper_const(&t);
EXPECT_TRUE(*x == 42);
}
{
// from raw pointer
// from strict_not_null pointer
int t = 42;
int* p = &t;
strict_not_null<int*> x{p};
helper(p);
helper_const(p);
helper(x);
helper_const(x);
EXPECT_TRUE(*x == 42);
}
{
// from raw const pointer
// from strict_not_null const pointer
int t = 42;
const int* cp = &t;
strict_not_null<const int*> x{cp};
helper_const(cp);
helper_const(x);
EXPECT_TRUE(*x == 42);
}
{
// from strict_not_null const pointer, using auto
int t = 42;
const int* cp = &t;
auto x = strict_not_null<const int*>{cp};
EXPECT_TRUE(*x == 42);
}
{
// from returned pointer
EXPECT_DEATH(helper(return_pointer()), expected);
EXPECT_DEATH(helper_const(return_pointer()), expected);
}
}
template <typename U, typename = void>
static constexpr bool StrictHelperCompilesFor = false;
template <typename U>
static constexpr bool
StrictHelperCompilesFor<U, void_t<decltype(strict_helper(std::declval<U>()))>> = true;
template <typename U, typename = void>
static constexpr bool StrictHelperConstCompilesFor = false;
template <typename U>
static constexpr bool
StrictHelperConstCompilesFor<U, void_t<decltype(strict_helper_const(std::declval<U>()))>> =
true;
template <typename U, typename = void>
static constexpr bool HelperCompilesFor = false;
template <typename U>
static constexpr bool HelperCompilesFor<U, void_t<decltype(helper(std::declval<U>()))>> = true;
TEST(strict_notnull_tests, TestStrictNotNull)
{
{
@ -57,20 +217,43 @@ TEST(strict_notnull_tests, TestStrictNotNull)
#ifdef CONFIRM_COMPILATION_ERRORS
strict_not_null<int*> snn = &x;
strict_helper(&x);
strict_helper_const(&x);
strict_helper(return_pointer());
strict_helper_const(return_pointer_const());
#endif
static_assert(!StrictHelperCompilesFor<int*>, "!StrictHelperCompilesFor<int*>");
static_assert(!StrictHelperConstCompilesFor<int*>,
"!StrictHelperCompilesFor<int*>");
const strict_not_null<int*> snn1{&x};
static_assert(StrictHelperCompilesFor<const strict_not_null<int*>>,
"StrictHelperCompilesFor<const strict_not_null<int*>>");
helper(snn1);
helper_const(snn1);
EXPECT_TRUE(*snn1 == 42);
}
{
// raw ptr <-> strict_not_null
const int x = 42;
#ifdef CONFIRM_COMPILATION_ERRORS
strict_not_null<int*> snn = &x;
#endif
static_assert(!StrictHelperCompilesFor<const int*>, "!StrictHelperFor<const int*>");
static_assert(!StrictHelperConstCompilesFor<const int*>,
"!StrictHelperCompilesFor<const int*>");
const strict_not_null<const int*> snn1{&x};
static_assert(!HelperCompilesFor<const strict_not_null<const int*>>,
"!HelperCompilesFor<const strict_not_null<const int*>>");
static_assert(StrictHelperConstCompilesFor<const strict_not_null<const int*>>,
"StrictHelperCompilesFor<const strict_not_null<const int*>>");
helper_const(snn1);
EXPECT_TRUE(*snn1 == 42);
}
{
// strict_not_null -> strict_not_null
int x = 42;
@ -85,6 +268,21 @@ TEST(strict_notnull_tests, TestStrictNotNull)
EXPECT_TRUE(snn1 == snn2);
}
{
// strict_not_null -> strict_not_null
const int x = 42;
strict_not_null<const int*> snn1{&x};
const strict_not_null<const int*> snn2{&x};
static_assert(!StrictHelperCompilesFor<strict_not_null<const int*>>,
"!StrictHelperCompilesFor<strict_not_null<const int*>>");
strict_helper_const(snn1);
strict_helper_const(snn2);
EXPECT_TRUE(snn1 == snn2);
}
{
// strict_not_null -> not_null
int x = 42;
@ -101,6 +299,23 @@ TEST(strict_notnull_tests, TestStrictNotNull)
EXPECT_TRUE(snn == nn2);
}
{
// strict_not_null -> not_null
const int x = 42;
strict_not_null<const int*> snn{&x};
const not_null<const int*> nn1 = snn;
const not_null<const int*> nn2{snn};
static_assert(!HelperCompilesFor<strict_not_null<const int*>>,
"!HelperCompilesFor<strict_not_null<const int*>>");
helper_const(snn);
EXPECT_TRUE(snn == nn1);
EXPECT_TRUE(snn == nn2);
}
{
// not_null -> strict_not_null
int x = 42;
@ -125,11 +340,37 @@ TEST(strict_notnull_tests, TestStrictNotNull)
EXPECT_TRUE(hash_snn(snn1) == hash_snn(nn));
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
strict_not_null<int*> p{nullptr};
// not_null -> strict_not_null
const int x = 42;
not_null<const int*> nn{&x};
const strict_not_null<const int*> snn1{nn};
const strict_not_null<const int*> snn2{nn};
static_assert(!StrictHelperCompilesFor<not_null<const int*>>,
"!StrictHelperCompilesFor<not_null<const int*>>");
strict_helper_const(nn);
EXPECT_TRUE(snn1 == nn);
EXPECT_TRUE(snn2 == nn);
std::hash<strict_not_null<const int*>> hash_snn;
std::hash<not_null<const int*>> hash_nn;
EXPECT_TRUE(hash_nn(snn1) == hash_nn(nn));
EXPECT_TRUE(hash_snn(snn1) == hash_nn(nn));
EXPECT_TRUE(hash_nn(snn1) == hash_nn(snn2));
EXPECT_TRUE(hash_snn(snn1) == hash_snn(nn));
}
#endif
}
TEST(pointers_test, member_types)
{
// make sure `element_type` is inherited from `gsl::not_null`
static_assert(std::is_same<gsl::strict_not_null<int*>::element_type, int*>::value,
"check member type: element_type");
}
#if defined(__cplusplus) && (__cplusplus >= 201703L)
@ -152,6 +393,17 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
EXPECT_TRUE(*x == 42);
}
{
const int i = 42;
strict_not_null x{&i};
static_assert(!HelperCompilesFor<strict_not_null<const int*>>,
"!HelperCompilesFor<strict_not_null<const int*>>");
helper_const(strict_not_null{&i});
EXPECT_TRUE(*x == 42);
}
{
int i = 42;
int* p = &i;
@ -163,6 +415,18 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
EXPECT_TRUE(*x == 42);
}
{
const int i = 42;
const int* p = &i;
strict_not_null x{p};
static_assert(!HelperCompilesFor<strict_not_null<const int*>>,
"!HelperCompilesFor<strict_not_null<const int*>>");
helper_const(strict_not_null{p});
EXPECT_TRUE(*x == 42);
}
{
auto workaround_macro = []() {
int* p1 = nullptr;

File diff suppressed because it is too large Load Diff

View File

@ -19,11 +19,11 @@
#include <algorithm> // for move
#include <complex>
#include <cstddef> // for std::ptrdiff_t
#include <cstdint> // for uint32_t, int32_t
#include <functional> // for reference_wrapper, _Bind_helper<>::type
#include <gsl/narrow> // for narrow, narrowing_error
#include <gsl/util> // finally, narrow_cast
#include <limits> // for numeric_limits
#include <stdint.h> // for uint32_t, int32_t
#include <type_traits> // for is_same
using namespace gsl;
@ -96,7 +96,7 @@ TEST(utils_tests, finally_function_with_bind)
{
int i = 0;
{
auto _ = finally(std::bind(&f, std::ref(i)));
auto _ = finally([&i] { return f(i); });
EXPECT_TRUE(i == 0);
}
EXPECT_TRUE(i == 1);
@ -112,6 +112,16 @@ TEST(utils_tests, finally_function_ptr)
EXPECT_TRUE(j == 1);
}
TEST(utils_tests, finally_function)
{
j = 0;
{
auto _ = finally(g);
EXPECT_TRUE(j == 0);
}
EXPECT_TRUE(j == 1);
}
TEST(utils_tests, narrow_cast)
{
int n = 120;
@ -149,5 +159,7 @@ TEST(utils_tests, narrow)
EXPECT_TRUE(
narrow<std::complex<float>>(std::complex<double>(4, 2)) == std::complex<float>(4, 2));
EXPECT_THROW(narrow<std::complex<float>>(std::complex<double>(4.2)), narrowing_error);
EXPECT_TRUE(narrow<int>(float(1)) == 1);
}
#endif // GSL_KERNEL_MODE