Compare commits

..

54 Commits

Author SHA1 Message Date
Jordan Maples [MSFT] 7e99e76c97 Merge pull request #826 from JordanMaples/dev/jomaples/ctad_fix_v2
fix ctad warning in llvm
2019-11-18 13:02:53 -08:00
Jordan Maples [MSFT] 263440f2a1 changing white-space in comment to get tests to rerun 2019-11-18 11:39:36 -08:00
Jordan Maples [MSFT] a7759e6d3f lower __cpp_deduction_guide version number from 201907 to 201611 2019-11-18 10:14:05 -08:00
Jordan Maples [MSFT] 128b4356ac changing check from __cplusplus 201703L to __cpp_deduction_guides 201907L 2019-11-15 16:29:41 -08:00
Jordan Maples [MSFT] 8e481ebe19 adding deduction guide for strict_not_null 2019-11-15 14:41:38 -08:00
Jordan Maples [MSFT] 4610f26b33 forgot comment 2019-11-15 12:43:33 -08:00
Jordan Maples [MSFT] d0e5daf441 fix ctad warning in llvm 2019-11-15 12:11:44 -08:00
Jordan Maples [MSFT] 9939d5889b Merge pull request #822 from JordanMaples/dev/jomaples/lib-byte-check
gsl_byte to inspect __cpp_lib_byte
2019-10-25 11:42:01 -07:00
Jordan Maples 22cba52114 update comments 2019-10-25 10:12:41 -07:00
Jordan Maples 97dc8f83fc adding check to __cpp_lib_byte, which was added to the defn for 15.8 2019-10-24 17:07:42 -07:00
Jordan Maples [MSFT] 71ec9f84d8 Merge pull request #2 from microsoft/master
updating personal branch.
2019-10-23 11:50:25 -07:00
Jordan Maples [MSFT] 3d56ba9e7f Merge pull request #813 from JordanMaples/dev/jomaples/deprecate_multispan
Deprecate multi_span, strided_span, etc
2019-10-09 15:11:59 -07:00
Jordan Maples [MSFT] cf9cc34da8 Merge pull request #815 from matt77hias/patch-1
Added std::exchange (C++14) to make the intent more explicit
2019-10-09 15:05:26 -07:00
Matthias Moulin 0a78d8ea3c Added std::exchange (C++14) to make the intent more explicit 2019-10-07 21:49:50 +02:00
Jordan Maples [MSFT] 02d1051fdd Merge pull request #814 from sizmailov/fix_typos
Fix typos in gsl/pointers
2019-10-06 14:39:57 -07:00
Sergei Izmailov 275e0176c0 Fix typos in gsl/pointers 2019-10-06 19:20:15 +03:00
Jordan Maples 4b289d4cf0 lack of nl for bounds_test 2019-10-04 14:15:24 -07:00
Jordan Maples 6ff4a5287d accidentally commented out pragma 2019-10-04 14:13:54 -07:00
Jordan Maples 2b8f7aea32 adding clang/gcc suppression of the deprecation warnings. 2019-10-04 12:38:55 -07:00
Jordan Maples 7adf7eb6fe new messages 2019-10-03 17:52:49 -07:00
Jordan Maples 5e4463a7c1 removing function deprecation, adding additional class / struct deprecations 2019-10-03 15:47:25 -07:00
Jordan Maples [MSFT] 10ce5b634f Merge pull request #812 from JordanMaples/dev/jomaples/typo_fixes
Fixing typo "Guideline" as "Guidelines"
2019-10-03 09:37:41 -07:00
Jordan Maples eb995b3671 deprecating strided_span 2019-10-02 16:17:46 -07:00
Jordan Maples b630dfe36a Guideline -> Guidelines
fixing issue as reported in issue #746
2019-10-02 15:42:40 -07:00
Jordan Maples e026971c03 deprecation, removing cassert 2019-10-02 15:40:15 -07:00
Jordan Maples bbeb0bdc91 initial deprecation of multi_span and strided_span 2019-09-28 12:54:18 -07:00
Jordan Maples [MSFT] 23066c829f Update README.md 2019-09-04 15:10:14 -07:00
Jordan Maples [MSFT] a454d295ed Merge pull request #803 from B1Z0N/master
Fixed memory leaks and out of bound access
2019-09-04 14:04:47 -07:00
B1Z0N ba9af38494 Merge branch 'master' of https://github.com/B1Z0N/GSL 2019-09-01 00:38:10 +03:00
B1Z0N d5382a293b Fixed memory leaks 2019-09-01 00:36:13 +03:00
B1Z0N 787e7ef616 Thanks to @stayprivates fixed out of bounds access in "TestNotNullostream" 2019-09-01 00:35:04 +03:00
Jordan Maples [MSFT] 1046c9d247 Merge pull request #1 from microsoft/master
updating from root
2019-08-30 12:37:36 -07:00
Jordan Maples [MSFT] b576cc6ce3 Merge pull request #769 from jack17529/patch-1
Update usage of difference_type in span
2019-08-15 14:49:12 -07:00
Jordan Maples [MSFT] 2ce3177ebd Merge pull request #800 from eyalroz/master
Fixes #798 : Dropping inclusion of `gsl/pointers` in `string_span`
2019-08-15 14:42:07 -07:00
Johel Ernesto Guerrero Peña cee1929de7 Fix GNUC typo (#780)
Resolves #779
2019-08-14 12:56:53 -07:00
beinhaerter 1d48188de9 Fixed check if std::byte is available (#764)
The check for std::byte existance fails on gcc 8.2. According to https://en.cppreference.com/w/cpp/utility/feature_test it is necessary to `#include <cstddef>` before checking `__cpp_lib_byte`.
2019-08-14 12:40:35 -07:00
Eyal Rozenberg b05a4464b9 Fixes #798 : Dropped inclusion of gsl/pointers in string_span. 2019-08-05 13:16:42 +03:00
NN 1212beae77 Add Visual Studio 2019 image for tests (#787)
* Add Visual Studio 2019 image for tests

Refer to https://github.com/appveyor/ci/issues/2907
VS2019 is enabled per request.

* Use CMake 3.14

* Fix CMake output directory

* trigger build

* Trigger build
2019-06-12 21:27:49 -07:00
Ian Taylor 66809c6852 make TypeListIndexer constexpr (#733) 2019-06-06 14:16:08 -07:00
Fei Sun b74b286d5e add value_type size_type for string_span (#727) 2019-04-11 10:40:02 -07:00
JACK_1729 2a1ef25406 Update span
About my Issue - https://github.com/Microsoft/GSL/issues/765
2019-02-20 20:25:50 +05:30
Anna Gringauze 7d78b743e4 added clang7.0 to Travis configuration and README (#763) 2019-01-16 19:58:38 -08:00
Anna Gringauze 6418b5f4de Clang cl (#762)
* Added c++17 test configurations for clang5.0 and clang6.0

* Fix #739 correct cppcorecheck warnings for clang-cl

* Add clang-cl  configurations

* Corrections Appveyor;
Temporarily disable msvc compilation for faster testing (#741)

* Add path to clang-cl.exe (#741)

* Escape backslash in path (#741)

* Update vcpkg (#741)

* Check vcpkg version; try without building vcpkg; use latest clang-cl from path (#741)

* Fix blocks in ps script (#741)

* Try accessing APPVEYOR_BUILD_FOLDER variable (#471)

* Update span size() bug confirmation test for GCC 6.5 (#741)

* MSVC flags to Clang-cl; disable c++98-compat and undefined macro warnings (#741)

* Suppress clang warning on tests (missing-prototypes) (#741)

* Fix clang warning -Wnewline-eof (#741)

* Fix clang warning -Wdouble-promotion (#741)

* Set linker explicitly

* Clean condition statement

* For Clang, fallback to the AppVeyor installed version of CMake

* Fix clang warning -Wmissing-variable-declarations

* Fallback to the MSVC linker until vcpkg has been updated

* Revert "Fallback to the MSVC linker until vcpkg has been updated"

This reverts commit 7263f3289e.

* Fix clang warning -Wunused-member-function

* Fix clang warning -Wmissing-noreturn

* Fix clang warning -Winvalid-noreturn on Windows

* Add macro block end comment on large #if blocks

* Workaround: fallback to mscv link.exe

* Workaround: get msvc paths into PowerShell through intermediate file

* Workaround: fix, remove "PATH=" from text

* Workaround: try with full-path; and return user PATH

* Workaround: fix, escape backslashes

* Revert all since "Workaround: fallback to mscv link.exe" did not work on AppVeyor

This reverts the commits:
bda3d6a428
97062933ac
0f4fb04bac
1b0c19afd1
a5739ea5f0

* Suppress output of git pull; remove vcpkg from cache

* Re-enable AppVeyor builds for all platforms

* Correct typo

Co-Authored-By: Farwaykorse <Farwaykorse@users.noreply.github.com>

* Add Clang-cl 7.0.0 to the supported platforms

* Revert "Fix clang warning -Wunused-member-function"

This reverts commit 6fe1a42035.

* Fix or locally suppress clang warning -Wunused-member-function

* format touched code and correct comment

* git pull --quiet

* fix logic error in workaround

* fix missing bracket

* Suppress output of mkdir

* Replace MSBuild with Ninja

* Suppress output of 7z

* Add architecture flags for Clang

* Drop workaround for lld-link

* 7-zip Overwrite and Alternative output suppression without suppressing errors

Replaces 3c1c0794dd

* AppVeyor setup and CMake before build

* reorder compiler configuration

* remove unnecessary

* remove -fno-strict-aliasing

* remove -Wsign-conversion, since before v4.0 part of -Wconversion

* -Wctor-dtor-privacy is GCC only

* remove -Woverloaded-virtual part of -Wmost, part of -Wall

* add -Wmissing-noreturn

* remove the pragmas for -Wunused-member-function

* Re-add MSBuild generator on AppVeyor

* Print CMake commands

* Add MSBuild toolset selection

* Separate Architecture setting

* clang-cl: add -Weverything

* clang-cl -Wno-c++98-compat

* clang-cl -Wno-c++98-compat-pedantic

* clang-cl -Wno-missing-prototypes

* clang-cl C++14 -Wno-unused-member-function

* clang-cl -Wundef __GNUC__

* clang++: add -Weverything

* clang++ -Wno-c++98-compat

* clang++ -Wno-c++98-compat-pedantic

* clang++ -Wno-missing-prototypes

* clang++ -Wno-weak-vtables

* clang++ C++14 -Wno-unused-member-function

* clang++ fix -Wundef _MSC_VER

* clang++ -Wno-padded

* clang++ solve -Wdeprecated

* Add AppleClang compiler target
Since CMake v3.0 use of Clang for both is deprecated

* clang++ v5.0 C++17 -Wno-undefined-func-template

* Add VS2015 + LLVM/clang-cl to AppVeyor

* Do not disable constexpr when compiling with clang-cl on Windows

* Clean-up clang-only warnings (now under -Weverything)

* Revert "Fix clang warning -Winvalid-noreturn on Windows"

This reverts commit 2238c4760e.

* Suppress -Winvalid-noreturn for the MS STL noexception workaround

* CMake: put preprocessor definition in target_compile_definitions

* Solve compiler warning C4668: __GNUC__ not defined
2019-01-15 10:27:34 -08:00
Johel Ernesto Guerrero Peña 6eeed739f1 Make narrow constexpr (#698) 2019-01-14 18:37:37 -08:00
Anna Gringauze 9ff6e19ea9 Dev/annagrin/remove explicit not null constructor (#743)
* Added c++17 test configurations for clang5.0 and clang6.0

* Removed explicit not_null constructor, sloppy_not_null, added strict_not_null

We added explicit not_null constructor in version 2.0.0.
It proved very difficult to switch to the new version for
large code bases that adopted previous versions of gsl,
due to not_null used extensively in the code. Still, using
explicit constructor is very benefitial for new code, since
it encorages better API design and make null checks intentional.

To resolve the issue, this change:
- removes explicit keyword from not_null constructor
- removes unneded sloppy_not_null type
- adds strict_not_null type to behave the same way as v2 not_null
- updates tests

* Removed explicit not_null constructor, sloppy_not_null, added strict_not_null

We added explicit not_null constructor in version 2.0.0.
It proved very difficult to switch to the new version for
large code bases that adopted previous versions of gsl,
due to not_null used extensively in the code. Still, using
explicit constructor is very benefitial for new code, since
it encorages better API design and make null checks intentional.

To resolve the issue, this change:
- removes explicit keyword from not_null constructor
- removes unneded sloppy_not_null type
- adds strict_not_null type to behave the same way as v2 not_null
- updates tests

* fixed build break for gcc7

* added more tests

* added more non-compiling tests

* Addressed PR comments and suppressed a code analysis warning

* Fixed test failure in not_null tests
2019-01-14 16:45:47 -08:00
Alex Green 7a7d025ffa Make CheckRange constexpr (#754) (#755) 2019-01-14 16:44:45 -08:00
k-brac be3c3c2731 Fixes CMAKE_VERSION check (#759)
* Fixes CMAKE_VERSION check

Fixes #758 by using the correct comparison operator for a version
See documentation at https://cmake.org/cmake/help/latest/command/if.html
Thanks to this change, gsl natvis is properly included in a visual studio solution

* cmake version check for cmake < 3.7
2019-01-14 16:43:17 -08:00
hannesweisbach 0f68d133fa Suppress Warnings in GSL Headers (#731)
Suppress warnings in GSL headers using the SYSTEM keyword for target_include_directories(). This enables developers to see warnings standalone builds but hides them from users in non-standalone builds.
2018-11-28 15:37:59 -08:00
beinhaerter 88aca1caf3 added noexcept to get rid off VC warning con.4 (#748) 2018-11-28 11:57:43 -08:00
Stefan Dinkelacker 2e4d0d7e22 Fix spelling of library name (#747) 2018-11-28 11:53:38 -08:00
kile0 5a7093f983 Use the c++17 constexpr if in CheckRange if possible (#753)
* change c++17 to use constexpr if in CheckRange

* remove unnecessary macro

* use the portable feature test macro rather than direct version check
2018-11-28 11:52:11 -08:00
Anna Gringauze b673375719 Dev/annagrin/fix span size test gcc (#750)
* Added c++17 test configurations for clang5.0 and clang6.0

* fixed test for broken span.size() in gcc6.5
2018-11-27 17:28:57 -08:00
Dave Hill c02ddae4bc Span can be constructed from empty std::array safely (#686)
* Span std::array c'tor uses arr.data() instead of &arr[0]
- Fixes runtime issues when constructing from an empty std::array

* Construct span with std::data if C++17 detected

* Specialize span c'tor for std::array of length 0, set storage to nullptr
2018-11-05 15:39:41 -08:00
Ian Taylor 2bf9f137a6 make BoundsRanges constexpr (#732)
* make BoundsRanges constexpr

* fix clang compilation error

* fix windows compilation
2018-11-05 15:26:27 -08:00
26 changed files with 909 additions and 608 deletions
+22
View File
@@ -163,6 +163,28 @@ matrix:
- env: COMPILER=clang++-6.0 BUILD_TYPE=Release GSL_CXX_STANDARD=17
addons: *clang60
# Clang 7.0
- env: COMPILER=clang++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang70
apt:
packages:
- clang-7
- g++-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-7
- env: COMPILER=clang++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang70
# Clang 7.0 c++17
- env: COMPILER=clang++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
addons: *clang70
- env: COMPILER=clang++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=17
addons: *clang70
##########################################################################
# GCC on Linux
##########################################################################
+16 -6
View File
@@ -51,13 +51,23 @@ target_compile_definitions(GSL INTERFACE
)
# add include folders to the library and targets that consume it
target_include_directories(GSL INTERFACE
$<BUILD_INTERFACE:
${CMAKE_CURRENT_SOURCE_DIR}/include
>
)
# the SYSTEM keyword suppresses warnings for users of the library
if(GSL_STANDALONE_PROJECT)
target_include_directories(GSL INTERFACE
$<BUILD_INTERFACE:
${CMAKE_CURRENT_SOURCE_DIR}/include
>
)
else()
target_include_directories(GSL SYSTEM INTERFACE
$<BUILD_INTERFACE:
${CMAKE_CURRENT_SOURCE_DIR}/include
>
)
endif()
if ((CMAKE_VERSION GREATER 3.7.9) OR (CMAKE_VERSION EQUAL 3.7.9))
if (CMAKE_VERSION VERSION_GREATER 3.7.8)
if (MSVC_IDE)
option(VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE)
else()
+2 -2
View File
@@ -1,6 +1,6 @@
## Contributing to the Guideline Support Library
## Contributing to the Guidelines Support Library
The Guideline Support Library (GSL) contains functions and types that are suggested for use by the
The Guidelines Support Library (GSL) contains functions and types that are suggested for use by the
[C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines). GSL design changes are made only as a result of modifications to the Guidelines.
GSL is accepting contributions that improve or refine any of the types in this library as well as ports to other platforms. Changes should have an issue
+10 -3
View File
@@ -1,6 +1,6 @@
# GSL: Guideline Support Library [![Build Status](https://travis-ci.org/Microsoft/GSL.svg?branch=master)](https://travis-ci.org/Microsoft/GSL) [![Build status](https://ci.appveyor.com/api/projects/status/github/Microsoft/GSL?svg=true)](https://ci.appveyor.com/project/neilmacintosh/GSL)
# GSL: Guidelines Support Library [![Build Status](https://travis-ci.org/Microsoft/GSL.svg?branch=master)](https://travis-ci.org/Microsoft/GSL) [![Build status](https://ci.appveyor.com/api/projects/status/github/Microsoft/GSL?svg=true)](https://ci.appveyor.com/project/neilmacintosh/GSL)
The Guideline Support Library (GSL) contains functions and types that are suggested for use by the
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).
This repo contains Microsoft's implementation of GSL.
@@ -27,10 +27,17 @@ The test suite that exercises GSL has been built and passes successfully on the
* Windows using Visual Studio 2015
* Windows using Visual Studio 2017
* Windows using Clang/LLVM 3.6
* Windows using Clang/LLVM 7.0.0
* Windows using GCC 5.1
* Windows using Intel C++ Compiler 18.0
* GNU/Linux using Clang/LLVM 3.6
* GNU/Linux using Clang/LLVM 3.6-3.9
* GNU/Linux using Clang/LLVM 4.0
* GNU/Linux using Clang/LLVM 5.0
* GNU/Linux using Clang/LLVM 6.0
* GNU/Linux using Clang/LLVM 7.0
* GNU/Linux using GCC 5.1
* OS X Mojave 10.14.4 using Apple LLVM version 10.0.0 (10.0.1.10010046)
* OS X Mojave 10.14.3 using Apple LLVM version 10.0.0 (clang-1000.11.45.5)
* OS X Yosemite using Xcode with Apple Clang 7.0.0.7000072
* OS X Yosemite using GCC-5.2.0
* OS X Sierra 10.12.4 using Apple LLVM version 8.1.0 (Clang-802.0.42)
+1 -1
View File
@@ -2,7 +2,7 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
Do Not Translate or Localize
GSL: Guideline Support Library incorporates third party material from the projects listed below. The original copyright notice and the license under which Microsoft received such third party material are set forth below. Microsoft reserves all other rights not expressly granted, whether by implication, estoppel or otherwise.
GSL: Guidelines Support Library incorporates third party material from the projects listed below. The original copyright notice and the license under which Microsoft received such third party material are set forth below. Microsoft reserves all other rights not expressly granted, whether by implication, estoppel or otherwise.
1. Catch (https://github.com/philsquared/Catch)
+86 -16
View File
@@ -11,46 +11,116 @@ configuration:
image:
- Visual Studio 2015
- Visual Studio 2017
- Visual Studio 2019
environment:
NINJA_TAG: v1.8.2
NINJA_SHA512: 9B9CE248240665FCD6404B989F3B3C27ED9682838225E6DC9B67B551774F251E4FF8A207504F941E7C811E7A8BE1945E7BCB94472A335EF15E23A0200A32E6D5
NINJA_PATH: C:\Tools\ninja\ninja-%NINJA_TAG%
VCVAR2015: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat'
VCVAR2017: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat'
VCVAR2019: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat'
matrix:
- GSL_CXX_STANDARD: 14
USE_TOOLSET: MSVC
USE_GENERATOR: MSBuild
- GSL_CXX_STANDARD: 17
USE_TOOLSET: MSVC
USE_GENERATOR: MSBuild
- GSL_CXX_STANDARD: 14
USE_TOOLSET: LLVM
USE_GENERATOR: Ninja
- GSL_CXX_STANDARD: 17
USE_TOOLSET: LLVM
USE_GENERATOR: Ninja
matrix:
exclude:
- image: Visual Studio 2015
GSL_CXX_STANDARD: 17
- image: Visual Studio 2015
USE_TOOLSET: LLVM
USE_GENERATOR: MSBuild
cache:
- C:\cmake-3.8.0-win32-x86
- C:\cmake-3.14.4-win32-x86
- C:\Tools\ninja
install:
- ps: |
if (![IO.File]::Exists("C:\cmake-3.8.0-win32-x86\bin\cmake.exe")) {
Start-FileDownload 'https://cmake.org/files/v3.8/cmake-3.8.0-win32-x86.zip'
7z x -y cmake-3.8.0-win32-x86.zip -oC:\
if (![IO.File]::Exists("$env:NINJA_PATH\ninja.exe")) {
Start-FileDownload `
"https://github.com/ninja-build/ninja/releases/download/$env:NINJA_TAG/ninja-win.zip"
$hash = (Get-FileHash ninja-win.zip -Algorithm SHA512).Hash
if ($env:NINJA_SHA512 -eq $hash) {
7z e -y -bso0 ninja-win.zip -o"$env:NINJA_PATH"
} else { Write-Warning "Ninja download hash changed!"; Write-Output "$hash" }
}
if ([IO.File]::Exists("$env:NINJA_PATH\ninja.exe")) {
$env:PATH = "$env:NINJA_PATH;$env:PATH"
} else { Write-Warning "Failed to find ninja.exe in expected location." }
if ($env:USE_TOOLSET -ne "LLVM") {
if (![IO.File]::Exists("C:\cmake-3.14.0-win32-x86\bin\cmake.exe")) {
Start-FileDownload 'https://cmake.org/files/v3.14/cmake-3.14.4-win32-x86.zip'
7z x -y -bso0 cmake-3.14.4-win32-x86.zip -oC:\
}
$env:PATH="C:\cmake-3.14.4-win32-x86\bin;$env:PATH"
}
$env:PATH="C:\cmake-3.8.0-win32-x86\bin;$env:PATH"
before_build:
- ps: |
mkdir build
cd build
if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2015") {
$env:generator="Visual Studio 14 2015"
if ("$env:USE_GENERATOR" -eq "Ninja") {
$GeneratorFlags = '-k 10'
$Architecture = $env:PLATFORM
if ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2015") {
$env:VCVARSALL = "`"$env:VCVAR2015`" $Architecture"
} elseif ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2017") {
$env:VCVARSALL = "`"$env:VCVAR2017`" $Architecture"
} else {
$env:VCVARSALL = "`"$env:VCVAR2019`" $Architecture"
}
$env:CMakeGenFlags = "-G Ninja -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
} else {
$env:generator="Visual Studio 15 2017"
$GeneratorFlags = '/m /v:minimal'
if ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2015") {
$Generator = 'Visual Studio 14 2015'
} elseif ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2017") {
$Generator = 'Visual Studio 15 2017'
} else {
$Generator = 'Visual Studio 16 2019'
}
if ("$env:PLATFORM" -eq "x86") {
$Architecture = "Win32"
} else {
$Architecture = "x64"
}
if ("$env:USE_TOOLSET" -eq "LLVM") {
$env:CMakeGenFlags = "-G `"$Generator`" -A $Architecture -T llvm -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
} else {
$env:CMakeGenFlags = "-G `"$Generator`" -A $Architecture -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
}
}
if ($env:PLATFORM -eq "x64") {
$env:generator="$env:generator Win64"
if ("$env:USE_TOOLSET" -eq "LLVM") {
$env:CC = "clang-cl"
$env:CXX = "clang-cl"
if ("$env:PLATFORM" -eq "x86") {
$env:CFLAGS = "-m32";
$env:CXXFLAGS = "-m32";
} else {
$env:CFLAGS = "-m64";
$env:CXXFLAGS = "-m64";
}
}
echo generator="$env:generator"
cmake .. -G "$env:generator" -DGSL_CXX_STANDARD="$env:GSL_CXX_STANDARD"
$env:CMakeBuildFlags = "--config $env:CONFIGURATION -- $GeneratorFlags"
- mkdir build
- cd build
- if %USE_GENERATOR%==Ninja (call %VCVARSALL%)
- echo %CMakeGenFlags%
- cmake .. %CMakeGenFlags%
build_script:
- cmake --build . --config %CONFIGURATION% -- /m /v:minimal
- echo %CMakeBuildFlags%
- cmake --build . %CMakeBuildFlags%
test_script:
- ctest -j2
+18 -8
View File
@@ -22,17 +22,17 @@
//
// make suppress attributes parse for some compilers
// Hopefully temporary until suppresion standardization occurs
// Hopefully temporary until suppression standardization occurs
//
#if defined (_MSC_VER)
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
#else
#if defined(__clang__)
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]]
#else
#if defined(_MSC_VER)
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
#else
#define GSL_SUPPRESS(x)
#endif // __clang__
#endif // _MSC_VER
#endif // __clang__
//
// Temporary until MSVC STL supports no-exceptions mode.
@@ -42,6 +42,12 @@
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
#include <intrin.h>
#define RANGE_CHECKS_FAILURE 0
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-noreturn"
#endif
#endif
//
@@ -98,7 +104,7 @@ namespace details
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
typedef void (__cdecl *terminate_handler)();
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute
[[noreturn]] inline void __cdecl default_terminate_handler()
{
@@ -138,7 +144,7 @@ namespace details
throw std::forward<Exception>(exception);
}
#endif
#endif // GSL_TERMINATE_ON_CONTRACT_VIOLATION
} // namespace details
} // namespace gsl
@@ -159,9 +165,13 @@ namespace details
#define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond)
#endif
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
#define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond)
#define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond)
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) && defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // GSL_CONTRACTS_H
+12 -10
View File
@@ -19,20 +19,22 @@
//
// make suppress attributes work for some compilers
// Hopefully temporary until suppresion standardization occurs
// Hopefully temporary until suppression standardization occurs
//
#if defined(_MSC_VER)
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
#else
#if defined(__clang__)
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]]
#else
#if defined(_MSC_VER)
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
#else
#define GSL_SUPPRESS(x)
#endif // __clang__
#endif // _MSC_VER
#endif // __clang__
#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)
@@ -42,20 +44,21 @@
#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
#if (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603)
#define GSL_USE_STD_BYTE 1
#else // defined(_HAS_STD_BYTE) && _HAS_STD_BYTE
#else // (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603)
#define GSL_USE_STD_BYTE 0
#endif // defined(_HAS_STD_BYTE) && _HAS_STD_BYTE
#endif // (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603)
#endif // GSL_USE_STD_BYTE
#else // _MSC_VER
#ifndef GSL_USE_STD_BYTE
#include <cstddef> /* __cpp_lib_byte */
// this tests if we are under GCC or Clang with enough -std:c++1z power to get us std::byte
// also check if libc++ version is sufficient (> 5.0) or libstc++ actually contains std::byte
#if defined(__cplusplus) && (__cplusplus >= 201703L) && \
@@ -63,7 +66,6 @@
defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000))
#define GSL_USE_STD_BYTE 1
#include <cstddef>
#else // defined(__cplusplus) && (__cplusplus >= 201703L) &&
// (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) ||
@@ -79,7 +81,7 @@
#endif // _MSC_VER
// Use __may_alias__ attribute on gcc and clang
#if defined __clang__ || (__GNUC__ > 5)
#if defined __clang__ || (defined(__GNUC__) && __GNUC__ > 5)
#define byte_may_alias __attribute__((__may_alias__))
#else // defined __clang__ || defined __GNUC__
#define byte_may_alias
+13 -7
View File
@@ -24,9 +24,9 @@
#include <exception> // for exception
#include <initializer_list> // for initializer_list
#include <type_traits> // for is_signed, integral_constant
#include <utility> // for forward
#include <utility> // for exchange, forward
#if defined(_MSC_VER)
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
@@ -37,6 +37,12 @@
#endif // _MSC_VER < 1910
#endif // _MSC_VER
#if (defined(_MSC_VER) && _MSC_VER < 1910) || (!defined(__clang__) && defined(__GNUC__) && __GNUC__ < 6)
#define GSL_CONSTEXPR_NARROW 0
#else
#define GSL_CONSTEXPR_NARROW 1
#endif
namespace gsl
{
//
@@ -53,10 +59,7 @@ class final_action
public:
explicit final_action(F f) noexcept : f_(std::move(f)) {}
final_action(final_action&& other) noexcept : f_(std::move(other.f_)), invoke_(other.invoke_)
{
other.invoke_ = false;
}
final_action(final_action&& other) noexcept : f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false)) {}
final_action(const final_action&) = delete;
final_action& operator=(const final_action&) = delete;
@@ -111,6 +114,9 @@ namespace details
template <class T, class U>
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
#if GSL_CONSTEXPR_NARROW
constexpr
#endif
T narrow(U u) noexcept(false)
{
T t = narrow_cast<T>(u);
@@ -152,7 +158,7 @@ constexpr T at(const std::initializer_list<T> cont, const index i)
} // namespace gsl
#if defined(_MSC_VER)
#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER < 1910
#undef constexpr
#pragma pop_macro("constexpr")
+155 -173
View File
@@ -23,7 +23,6 @@
#include <algorithm> // for transform, lexicographical_compare
#include <array> // for array
#include <cassert>
#include <cstddef> // for ptrdiff_t, size_t, nullptr_t
#include <cstdint> // for PTRDIFF_MAX
#include <functional> // for divides, multiplies, minus, negate, plus
@@ -37,7 +36,7 @@
#include <type_traits> // for enable_if_t, remove_cv_t, is_same, is_co...
#include <utility>
#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(__clang__)
// turn off some warnings that are noisy about our Expects statements
#pragma warning(push)
@@ -49,20 +48,26 @@
#pragma warning(disable : 26473) // in some instantiations we cast to the same type
#pragma warning(disable : 26490) // TODO: bug in parser - attributes and templates
#pragma warning(disable : 26465) // TODO: bug - suppression does not work on template functions
#pragma warning(disable : 4996) // use of function or classes marked [[deprecated]]
#if _MSC_VER < 1910
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
#endif // _MSC_VER < 1910
#endif // _MSC_VER
#endif // _MSC_VER < 1910
#endif // _MSC_VER
#if __clang__ || __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
// GCC 7 does not like the signed unsigned missmatch (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 indiscriminently, but
// could check if the source value actually doesn't fit into the target type
// and only warn in those cases.
#if __GNUC__ > 6
#if defined(__GNUC__) && __GNUC__ > 6
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
@@ -76,18 +81,18 @@ namespace gsl
namespace details
{
template <typename SizeType>
struct SizeTypeTraits
struct [[deprecated]] SizeTypeTraits
{
static const SizeType max_value = std::numeric_limits<SizeType>::max();
};
template <typename... Ts>
class are_integral : public std::integral_constant<bool, true>
class [[deprecated]] are_integral : public std::integral_constant<bool, true>
{
};
template <typename T, typename... Ts>
class are_integral<T, Ts...>
class [[deprecated]] are_integral<T, Ts...>
: public std::integral_constant<bool,
std::is_integral<T>::value && are_integral<Ts...>::value>
{
@@ -95,8 +100,7 @@ namespace details
} // namespace details
template <std::size_t Rank>
class multi_span_index final
{
class [[deprecated]] multi_span_index final {
static_assert(Rank > 0, "Rank must be greater than 0!");
template <std::size_t OtherRank>
@@ -111,7 +115,7 @@ public:
constexpr multi_span_index() noexcept {}
constexpr multi_span_index(const value_type (&values)[Rank]) noexcept
constexpr multi_span_index(const value_type(&values)[Rank]) noexcept
{
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute
@@ -139,7 +143,7 @@ public:
// Preconditions: component_idx < rank
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
constexpr const_reference operator[](std::size_t component_idx) const
constexpr const_reference operator[](std::size_t component_idx) const
{
Expects(component_idx < Rank); // Component index must be less than rank
return elems[component_idx];
@@ -152,10 +156,7 @@ public:
return std::equal(elems, elems + rank, rhs.elems);
}
constexpr bool operator!=(const multi_span_index& rhs) const
{
return !(*this == rhs);
}
constexpr bool operator!=(const multi_span_index& rhs) const { return !(*this == rhs); }
constexpr multi_span_index operator+() const noexcept { return *this; }
@@ -184,8 +185,7 @@ public:
{
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute
std::transform(elems, elems + rank, rhs.elems, elems,
std::plus<value_type>{});
std::transform(elems, elems + rank, rhs.elems, elems, std::plus<value_type>{});
return *this;
}
@@ -240,7 +240,7 @@ private:
#if !defined(_MSC_VER) || _MSC_VER >= 1910
struct static_bounds_dynamic_range_t
struct [[deprecated]] static_bounds_dynamic_range_t
{
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
constexpr operator T() const noexcept
@@ -288,25 +288,22 @@ constexpr static_bounds_dynamic_range_t dynamic_range{};
const std::ptrdiff_t dynamic_range = -1;
#endif
struct generalized_mapping_tag
{
};
struct contiguous_mapping_tag : generalized_mapping_tag
struct [[deprecated]] generalized_mapping_tag
{
};
struct[[deprecated]] contiguous_mapping_tag : generalized_mapping_tag{};
namespace details
{
template <std::ptrdiff_t Left, std::ptrdiff_t Right>
struct LessThan
struct [[deprecated]] LessThan
{
static const bool value = Left < Right;
};
template <std::ptrdiff_t... Ranges>
struct BoundsRanges
{
struct [[deprecated]] BoundsRanges {
using size_type = std::ptrdiff_t;
static const size_type Depth = 0;
static const size_type DynamicNum = 0;
@@ -315,37 +312,37 @@ namespace details
// TODO : following signature is for work around VS bug
template <typename OtherRange>
BoundsRanges(const OtherRange&, bool /* firstLevel */)
constexpr BoundsRanges(const OtherRange&, bool /* firstLevel */)
{}
BoundsRanges(const std::ptrdiff_t* const) {}
BoundsRanges() noexcept = default;
constexpr BoundsRanges(const std::ptrdiff_t* const) {}
constexpr BoundsRanges() noexcept = default;
template <typename T, std::size_t Dim>
void serialize(T&) const
constexpr void serialize(T&) const
{}
template <typename T, std::size_t Dim>
size_type linearize(const T&) const
constexpr size_type linearize(const T&) const
{
return 0;
}
template <typename T, std::size_t Dim>
size_type contains(const T&) const
constexpr size_type contains(const T&) const
{
return -1;
}
size_type elementNum(std::size_t) const noexcept { return 0; }
constexpr size_type elementNum(std::size_t) const noexcept { return 0; }
size_type totalSize() const noexcept { return TotalSize; }
constexpr size_type totalSize() const noexcept { return TotalSize; }
bool operator==(const BoundsRanges&) const noexcept { return true; }
constexpr bool operator==(const BoundsRanges&) const noexcept { return true; }
};
template <std::ptrdiff_t... RestRanges>
struct BoundsRanges<dynamic_range, RestRanges...> : BoundsRanges<RestRanges...>
struct[[deprecated]] BoundsRanges<dynamic_range, RestRanges...> : BoundsRanges<RestRanges...>
{
using Base = BoundsRanges<RestRanges...>;
using size_type = std::ptrdiff_t;
@@ -358,25 +355,26 @@ namespace details
size_type m_bound;
public:
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute // this pointer type is cannot be assigned nullptr - issue in not_null
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
BoundsRanges(const std::ptrdiff_t* const arr)
GSL_SUPPRESS(
f.23) // NO-FORMAT: attribute // this pointer type is cannot be assigned nullptr - issue in not_null
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
constexpr BoundsRanges(const std::ptrdiff_t* const arr)
: Base(arr + 1), m_bound(*arr * this->Base::totalSize())
{
Expects(0 <= *arr);
}
BoundsRanges() noexcept : m_bound(0) {}
constexpr BoundsRanges() noexcept : m_bound(0) {}
template <std::ptrdiff_t OtherRange, std::ptrdiff_t... RestOtherRanges>
BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
bool /* firstLevel */ = true)
constexpr BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
bool /* firstLevel */ = true)
: Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false)
, m_bound(other.totalSize())
{}
template <typename T, std::size_t Dim = 0>
void serialize(T& arr) const
constexpr void serialize(T & arr) const
{
arr[Dim] = elementNum();
this->Base::template serialize<T, Dim + 1>(arr);
@@ -384,7 +382,7 @@ namespace details
template <typename T, std::size_t Dim = 0>
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
size_type linearize(const T& arr) const
constexpr size_type linearize(const T& arr) const
{
const size_type index = this->Base::totalSize() * arr[Dim];
Expects(index < m_bound);
@@ -392,7 +390,7 @@ namespace details
}
template <typename T, std::size_t Dim = 0>
size_type contains(const T& arr) const
constexpr size_type contains(const T& arr) const
{
const ptrdiff_t last = this->Base::template contains<T, Dim + 1>(arr);
if (last == -1) return -1;
@@ -400,19 +398,20 @@ namespace details
return cur < m_bound ? cur + last : -1;
}
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
size_type totalSize() const noexcept
{
return m_bound;
}
GSL_SUPPRESS(
c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
constexpr size_type totalSize() const noexcept { return m_bound; }
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
size_type elementNum() const noexcept
GSL_SUPPRESS(
c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
constexpr size_type elementNum() const noexcept
{
return totalSize() / this->Base::totalSize();
}
size_type elementNum(std::size_t dim) const noexcept
GSL_SUPPRESS(
c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
constexpr size_type elementNum(std::size_t dim) const noexcept
{
if (dim > 0)
return this->Base::elementNum(dim - 1);
@@ -420,7 +419,7 @@ namespace details
return elementNum();
}
bool operator==(const BoundsRanges& rhs) const noexcept
constexpr bool operator==(const BoundsRanges& rhs) const noexcept
{
return m_bound == rhs.m_bound &&
static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
@@ -428,7 +427,7 @@ namespace details
};
template <std::ptrdiff_t CurRange, std::ptrdiff_t... RestRanges>
struct BoundsRanges<CurRange, RestRanges...> : BoundsRanges<RestRanges...>
struct[[deprecated]] BoundsRanges<CurRange, RestRanges...> : BoundsRanges<RestRanges...>
{
using Base = BoundsRanges<RestRanges...>;
using size_type = std::ptrdiff_t;
@@ -438,12 +437,12 @@ namespace details
static const size_type TotalSize =
Base::TotalSize == dynamic_range ? dynamic_range : CurrentRange * Base::TotalSize;
BoundsRanges(const std::ptrdiff_t* const arr) : Base(arr) {}
BoundsRanges() = default;
constexpr BoundsRanges(const std::ptrdiff_t* const arr) : Base(arr) {}
constexpr BoundsRanges() = default;
template <std::ptrdiff_t OtherRange, std::ptrdiff_t... RestOtherRanges>
BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
bool firstLevel = true)
constexpr BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
bool firstLevel = true)
: Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false)
{
GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: false positive
@@ -451,25 +450,24 @@ namespace details
}
template <typename T, std::size_t Dim = 0>
void serialize(T& arr) const
constexpr void serialize(T & arr) const
{
arr[Dim] = elementNum();
this->Base::template serialize<T, Dim + 1>(arr);
}
template <typename T, std::size_t Dim = 0>
size_type linearize(const T& arr) const
constexpr size_type linearize(const T& arr) const
{
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
Expects(arr[Dim] >= 0 && arr[Dim] < CurrentRange); // Index is out of range
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
return this->Base::totalSize() * arr[Dim] +
this->Base::template linearize<T, Dim + 1>(arr);
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
const ptrdiff_t d = arr[Dim];
return this->Base::totalSize() * d + this->Base::template linearize<T, Dim + 1>(arr);
}
template <typename T, std::size_t Dim = 0>
size_type contains(const T& arr) const
constexpr size_type contains(const T& arr) const
{
if (arr[Dim] >= CurrentRange) return -1;
const size_type last = this->Base::template contains<T, Dim + 1>(arr);
@@ -477,20 +475,20 @@ namespace details
return this->Base::totalSize() * arr[Dim] + last;
}
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
size_type totalSize() const noexcept
GSL_SUPPRESS(
c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
constexpr size_type totalSize() const noexcept
{
return CurrentRange * this->Base::totalSize();
}
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
size_type elementNum() const noexcept
{
return CurrentRange;
}
GSL_SUPPRESS(
c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
constexpr size_type elementNum() const noexcept { return CurrentRange; }
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
size_type elementNum(std::size_t dim) const noexcept
GSL_SUPPRESS(
c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
constexpr size_type elementNum(std::size_t dim) const noexcept
{
if (dim > 0)
return this->Base::elementNum(dim - 1);
@@ -498,50 +496,47 @@ namespace details
return elementNum();
}
bool operator==(const BoundsRanges& rhs) const noexcept
constexpr bool operator==(const BoundsRanges& rhs) const noexcept
{
return static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
}
};
template <typename SourceType, typename TargetType>
struct BoundsRangeConvertible
struct[[deprecated]] BoundsRangeConvertible
: public std::integral_constant<bool, (SourceType::TotalSize >= TargetType::TotalSize ||
TargetType::TotalSize == dynamic_range ||
SourceType::TotalSize == dynamic_range ||
TargetType::TotalSize == 0)>
{
};
TargetType::TotalSize == 0)>{};
template <typename TypeChain>
struct TypeListIndexer
{
struct [[deprecated]] TypeListIndexer {
const TypeChain& obj_;
TypeListIndexer(const TypeChain& obj) : obj_(obj) {}
constexpr TypeListIndexer(const TypeChain& obj) : obj_(obj) {}
template <std::size_t N>
const TypeChain& getObj(std::true_type)
constexpr const TypeChain& getObj(std::true_type)
{
return obj_;
}
template <std::size_t N, typename MyChain = TypeChain,
typename MyBase = typename MyChain::Base>
auto getObj(std::false_type)
-> decltype(TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>())
constexpr auto getObj(std::false_type)
->decltype(TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>())
{
return TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>();
}
template <std::size_t N>
auto get() -> decltype(getObj<N - 1>(std::integral_constant<bool, N == 0>()))
constexpr auto get()->decltype(getObj<N - 1>(std::integral_constant<bool, N == 0>()))
{
return getObj<N - 1>(std::integral_constant<bool, N == 0>());
}
};
template <typename TypeChain>
TypeListIndexer<TypeChain> createTypeListIndexer(const TypeChain& obj)
constexpr TypeListIndexer<TypeChain> createTypeListIndexer(const TypeChain& obj)
{
return TypeListIndexer<TypeChain>(obj);
}
@@ -554,24 +549,23 @@ namespace details
for (std::size_t i = 0; i < Rank - 1; ++i)
{
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
ret[i] = other[i + 1];
ret[i] = other[i + 1];
}
return ret;
}
} // namespace details
template <typename IndexType>
class bounds_iterator;
class [[deprecated]] bounds_iterator;
template <std::ptrdiff_t... Ranges>
class static_bounds
{
class [[deprecated]] static_bounds {
public:
static_bounds(const details::BoundsRanges<Ranges...>&) {}
};
template <std::ptrdiff_t FirstRange, std::ptrdiff_t... RestRanges>
class static_bounds<FirstRange, RestRanges...>
class[[deprecated]] static_bounds<FirstRange, RestRanges...>
{
using MyRanges = details::BoundsRanges<FirstRange, RestRanges...>;
@@ -595,7 +589,6 @@ public:
using sliced_type = static_bounds<RestRanges...>;
using mapping_type = contiguous_mapping_tag;
constexpr static_bounds(const static_bounds&) noexcept = default;
constexpr static_bounds() /*noexcept*/ = default;
template <typename SourceType, typename TargetType, std::size_t Rank>
@@ -604,10 +597,10 @@ public:
template <std::size_t Rank, typename SourceType, typename TargetType,
typename Ret = BoundsRangeConvertible2<typename SourceType::Base,
typename TargetType::Base, Rank>>
static auto helpBoundsRangeConvertible(SourceType, TargetType, std::true_type) -> Ret;
static auto helpBoundsRangeConvertible(SourceType, TargetType, std::true_type)->Ret;
template <std::size_t Rank, typename SourceType, typename TargetType>
static auto helpBoundsRangeConvertible(SourceType, TargetType, ...) -> std::false_type;
static auto helpBoundsRangeConvertible(SourceType, TargetType, ...)->std::false_type;
template <typename SourceType, typename TargetType, std::size_t Rank>
struct BoundsRangeConvertible2
@@ -724,10 +717,7 @@ public:
return !(*this == rhs);
}
constexpr const_iterator begin() const noexcept
{
return const_iterator(*this, index_type{});
}
constexpr const_iterator begin() const noexcept { return const_iterator(*this, index_type{}); }
constexpr const_iterator end() const noexcept
{
@@ -736,7 +726,7 @@ public:
};
template <std::size_t Rank>
class strided_bounds {
class [[deprecated]] strided_bounds {
template <std::size_t OtherRank>
friend class strided_bounds;
@@ -760,14 +750,13 @@ public:
constexpr strided_bounds& operator=(const strided_bounds&) noexcept = default;
constexpr strided_bounds(const value_type (&values)[rank], index_type strides)
constexpr strided_bounds(const value_type(&values)[rank], index_type strides)
: m_extents(values), m_strides(std::move(strides))
{}
constexpr strided_bounds(const index_type& extents, const index_type& strides) noexcept
: m_extents(extents), m_strides(strides)
{
}
{}
constexpr index_type strides() const noexcept { return m_strides; }
@@ -839,21 +828,14 @@ private:
};
template <typename T>
struct is_bounds : std::integral_constant<bool, false>
{
};
struct[[deprecated]] is_bounds : std::integral_constant<bool, false>{};
template <std::ptrdiff_t... Ranges>
struct is_bounds<static_bounds<Ranges...>> : std::integral_constant<bool, true>
{
};
struct[[deprecated]] is_bounds<static_bounds<Ranges...>> : std::integral_constant<bool, true>{};
template <std::size_t Rank>
struct is_bounds<strided_bounds<Rank>> : std::integral_constant<bool, true>
{
};
struct[[deprecated]] is_bounds<strided_bounds<Rank>> : std::integral_constant<bool, true>{};
template <typename IndexType>
class bounds_iterator
{
class [[deprecated]] bounds_iterator {
public:
static const std::size_t rank = IndexType::rank;
using iterator_category = std::random_access_iterator_tag;
@@ -974,7 +956,6 @@ public:
return curr_ == rhs.curr_;
}
constexpr bool operator!=(const bounds_iterator& rhs) const noexcept { return !(*this == rhs); }
constexpr bool operator<(const bounds_iterator& rhs) const noexcept
@@ -988,16 +969,15 @@ public:
constexpr bool operator>=(const bounds_iterator& rhs) const noexcept { return !(rhs > *this); }
void swap(bounds_iterator& rhs) noexcept
void swap(bounds_iterator & rhs) noexcept
{
std::swap(boundary_, rhs.boundary_);
std::swap(curr_, rhs.curr_);
}
private:
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
constexpr bool less(index_type& one, index_type& other) const noexcept
constexpr bool less(index_type & one, index_type & other) const noexcept
{
for (std::size_t i = 0; i < rank; ++i)
{
@@ -1092,17 +1072,17 @@ namespace details
} // namespace details
template <typename Span>
class contiguous_span_iterator;
class [[deprecated]] contiguous_span_iterator;
template <typename Span>
class general_span_iterator;
class [[deprecated]] general_span_iterator;
template <std::ptrdiff_t DimSize = dynamic_range>
struct dim_t
struct [[deprecated]] dim_t
{
static const std::ptrdiff_t value = DimSize;
};
template <>
struct dim_t<dynamic_range>
struct [[deprecated]] dim_t<dynamic_range>
{
static const std::ptrdiff_t value = dynamic_range;
const std::ptrdiff_t dvalue;
@@ -1123,28 +1103,30 @@ constexpr dim_t<N> dim(std::ptrdiff_t n) noexcept
template <typename ValueType, std::ptrdiff_t FirstDimension = dynamic_range,
std::ptrdiff_t... RestDimensions>
class multi_span;
class [[deprecated("gsl::multi_span is deprecated because it is not in the C++ Core Guidelines")]] multi_span;
template <typename ValueType, std::size_t Rank>
class strided_span;
class [[deprecated("gsl::strided_span is deprecated because it is not in the C++ Core Guidelines")]] strided_span;
namespace details
{
template <typename T, typename = std::true_type>
struct SpanTypeTraits
struct [[deprecated]] SpanTypeTraits
{
using value_type = T;
using size_type = std::size_t;
};
template <typename Traits>
struct SpanTypeTraits<Traits, typename std::is_reference<typename Traits::span_traits&>::type>
struct [[deprecated]] SpanTypeTraits<
Traits, typename std::is_reference<typename Traits::span_traits&>::type>
{
using value_type = typename Traits::span_traits::value_type;
using size_type = typename Traits::span_traits::size_type;
};
template <typename T, std::ptrdiff_t... Ranks>
struct SpanArrayTraits
struct [[deprecated]] SpanArrayTraits
{
using type = multi_span<T, Ranks...>;
using value_type = T;
@@ -1153,7 +1135,7 @@ namespace details
using reference = T&;
};
template <typename T, std::ptrdiff_t N, std::ptrdiff_t... Ranks>
struct SpanArrayTraits<T[N], Ranks...> : SpanArrayTraits<T, Ranks..., N>
struct [[deprecated]] SpanArrayTraits<T[N], Ranks...> : SpanArrayTraits<T, Ranks..., N>
{
};
@@ -1177,7 +1159,7 @@ namespace details
totalSize, std::integral_constant<bool, BoundsType::dynamic_rank == 1>());
}
struct Sep
struct [[deprecated]] Sep
{
};
@@ -1200,36 +1182,35 @@ namespace details
}
template <typename... Dimensions>
struct static_as_multi_span_static_bounds_helper
struct [[deprecated]] static_as_multi_span_static_bounds_helper
{
using type = static_bounds<(Dimensions::value)...>;
};
template <typename T>
struct is_multi_span_oracle : std::false_type
struct [[deprecated]] is_multi_span_oracle : std::false_type
{
};
template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions>
struct is_multi_span_oracle<multi_span<ValueType, FirstDimension, RestDimensions...>>
struct [[deprecated]] is_multi_span_oracle<multi_span<ValueType, FirstDimension, RestDimensions...>>
: std::true_type
{
};
template <typename ValueType, std::ptrdiff_t Rank>
struct is_multi_span_oracle<strided_span<ValueType, Rank>> : std::true_type
struct [[deprecated]] is_multi_span_oracle<strided_span<ValueType, Rank>> : std::true_type
{
};
template <typename T>
struct is_multi_span : is_multi_span_oracle<std::remove_cv_t<T>>
struct [[deprecated]] is_multi_span : is_multi_span_oracle<std::remove_cv_t<T>>
{
};
} // namespace details
template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions>
class multi_span
{
class [[deprecated("gsl::multi_span is deprecated because it is not in the C++ Core Guidelines")]] multi_span {
// TODO do we still need this?
template <typename ValueType2, std::ptrdiff_t FirstDimension2,
std::ptrdiff_t... RestDimensions2>
@@ -1262,8 +1243,7 @@ private:
public:
// default constructor - same as constructing from nullptr_t
GSL_SUPPRESS(type.6) // NO-FORMAT: attribute // TODO: false positive
constexpr multi_span() noexcept
: multi_span(nullptr, bounds_type{})
constexpr multi_span() noexcept : multi_span(nullptr, bounds_type{})
{
static_assert(bounds_type::dynamic_rank != 0 ||
(bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0),
@@ -1273,8 +1253,7 @@ public:
// construct from nullptr - get an empty multi_span
GSL_SUPPRESS(type.6) // NO-FORMAT: attribute // TODO: false positive
constexpr multi_span(std::nullptr_t) noexcept
: multi_span(nullptr, bounds_type{})
constexpr multi_span(std::nullptr_t) noexcept : multi_span(nullptr, bounds_type{})
{
static_assert(bounds_type::dynamic_rank != 0 ||
(bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0),
@@ -1298,8 +1277,7 @@ public:
// construct from a single element
GSL_SUPPRESS(type.6) // NO-FORMAT: attribute // TODO: false positive
constexpr multi_span(reference data) noexcept
: multi_span(&data, bounds_type{1})
constexpr multi_span(reference data) noexcept : multi_span(&data, bounds_type{1})
{
static_assert(bounds_type::dynamic_rank > 0 || bounds_type::static_size == 0 ||
bounds_type::static_size == 1,
@@ -1308,17 +1286,14 @@ public:
}
// prevent constructing from temporaries for single-elements
constexpr multi_span(value_type&&) = delete;
constexpr multi_span(value_type &&) = delete;
// construct from pointer + length
GSL_SUPPRESS(type.6) // NO-FORMAT: attribute // TODO: false positive
constexpr multi_span(pointer ptr, size_type size)
: multi_span(ptr, bounds_type{size})
{}
constexpr multi_span(pointer ptr, size_type size) : multi_span(ptr, bounds_type{size}) {}
// construct from pointer + length - multidimensional
constexpr multi_span(pointer data, bounds_type bounds)
: data_(data), bounds_(std::move(bounds))
constexpr multi_span(pointer data, bounds_type bounds) : data_(data), bounds_(std::move(bounds))
{
Expects((bounds_.size() > 0 && data != nullptr) || bounds_.size() == 0);
}
@@ -1336,7 +1311,7 @@ public:
// construct from n-dimensions static array
template <typename T, std::size_t N, typename Helper = details::SpanArrayTraits<T, N>>
constexpr multi_span(T (&arr)[N])
constexpr multi_span(T(&arr)[N])
: multi_span(reinterpret_cast<pointer>(arr), bounds_type{typename Helper::bounds_type{}})
{
static_assert(std::is_convertible<typename Helper::value_type(*)[], value_type(*)[]>::value,
@@ -1357,7 +1332,7 @@ public:
// construct from std::array
template <typename T, std::size_t N>
constexpr multi_span(std::array<T, N>& arr)
constexpr multi_span(std::array<T, N> & arr)
: multi_span(arr.data(), bounds_type{static_bounds<N>{}})
{
static_assert(
@@ -1381,7 +1356,7 @@ public:
// prevent constructing from temporary std::array
template <typename T, std::size_t N>
constexpr multi_span(std::array<T, N>&& arr) = delete;
constexpr multi_span(std::array<T, N> && arr) = delete;
// construct from containers
// future: could use contiguous_iterator_traits to identify only contiguous containers
@@ -1389,11 +1364,11 @@ public:
template <typename Cont, typename DataType = typename Cont::value_type,
typename = std::enable_if_t<
!details::is_multi_span<Cont>::value &&
std::is_convertible<DataType (*)[], value_type (*)[]>::value &&
std::is_convertible<DataType(*)[], value_type(*)[]>::value &&
std::is_same<std::decay_t<decltype(std::declval<Cont>().size(),
*std::declval<Cont>().data())>,
DataType>::value>>
constexpr multi_span(Cont& cont)
constexpr multi_span(Cont & cont)
: multi_span(static_cast<pointer>(cont.data()),
details::newBoundsHelper<bounds_type>(narrow_cast<size_type>(cont.size())))
{}
@@ -1402,11 +1377,11 @@ public:
template <typename Cont, typename DataType = typename Cont::value_type,
typename = std::enable_if_t<
!details::is_multi_span<Cont>::value &&
std::is_convertible<DataType (*)[], value_type (*)[]>::value &&
std::is_convertible<DataType(*)[], value_type(*)[]>::value &&
std::is_same<std::decay_t<decltype(std::declval<Cont>().size(),
*std::declval<Cont>().data())>,
DataType>::value>>
explicit constexpr multi_span(Cont&& cont) = delete;
explicit constexpr multi_span(Cont && cont) = delete;
// construct from a convertible multi_span
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
@@ -1419,7 +1394,7 @@ public:
// trivial copy and move
constexpr multi_span(const multi_span&) = default;
constexpr multi_span(multi_span&&) = default;
constexpr multi_span(multi_span &&) = default;
// trivial assignment
constexpr multi_span& operator=(const multi_span&) = default;
@@ -1493,8 +1468,7 @@ public:
}
// section - creates a non-contiguous, strided multi_span from a contiguous one
constexpr strided_span<ValueType, Rank> section(index_type origin,
index_type extents) const
constexpr strided_span<ValueType, Rank> section(index_type origin, index_type extents) const
{
const size_type size = this->bounds().total_size() - this->bounds().linearize(origin);
return {&this->operator[](origin), size,
@@ -1636,8 +1610,8 @@ public:
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
typename = std::enable_if_t<std::is_same<std::remove_cv_t<value_type>,
std::remove_cv_t<OtherValueType>>::value>>
constexpr bool operator>(const multi_span<OtherValueType, OtherDimensions...>& other) const
noexcept
constexpr bool operator>(const multi_span<OtherValueType, OtherDimensions...>& other)
const noexcept
{
return (other < *this);
}
@@ -1673,7 +1647,8 @@ constexpr auto as_multi_span(SpanType s, Dimensions2... dims)
// convert a multi_span<T> to a multi_span<const byte>
template <typename U, std::ptrdiff_t... Dimensions>
multi_span<const byte, dynamic_range> as_bytes(multi_span<U, Dimensions...> s) noexcept
multi_span<const byte, dynamic_range>
as_bytes(multi_span<U, Dimensions...> s) noexcept
{
static_assert(std::is_trivial<std::decay_t<U>>::value,
"The value_type of multi_span must be a trivial type.");
@@ -1759,7 +1734,8 @@ constexpr auto as_multi_span(T* arr, std::ptrdiff_t len) ->
}
template <typename T, std::size_t N>
constexpr auto as_multi_span(T (&arr)[N]) -> typename details::SpanArrayTraits<T, N>::type
constexpr auto as_multi_span(T (&arr)[N]) ->
typename details::SpanArrayTraits<T, N>::type
{
return {arr};
}
@@ -1812,7 +1788,7 @@ constexpr auto as_multi_span(std::basic_string<CharT, Traits, Allocator>& str)
// strided_span is an extension that is not strictly part of the GSL at this time.
// It is kept here while the multidimensional interface is still being defined.
template <typename ValueType, std::size_t Rank>
class strided_span
class [[deprecated("gsl::strided_span is deprecated because it is not in the C++ Core Guidelines")]] strided_span
{
public:
using bounds_type = strided_bounds<Rank>;
@@ -1886,6 +1862,8 @@ public:
auto d = narrow_cast<size_type>(sizeof(OtherValueType) / sizeof(value_type));
const size_type size = this->bounds().total_size() / d;
GSL_SUPPRESS(type.3) // NO-FORMAT: attribute
return {const_cast<OtherValueType*>(reinterpret_cast<const OtherValueType*>(this->data())),
size,
bounds_type{resize_extent(this->bounds().index_bounds(), d),
@@ -2053,8 +2031,7 @@ private:
};
template <class Span>
class contiguous_span_iterator
{
class [[deprecated]] contiguous_span_iterator {
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = typename Span::value_type;
@@ -2070,7 +2047,8 @@ private:
const Span* m_validator;
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
void validateThis() const {
void validateThis() const
{
// iterator is out of range of the array
Expects(data_ >= m_validator->data_ && data_ < m_validator->data_ + m_validator->size());
}
@@ -2159,7 +2137,7 @@ public:
bool operator>(const contiguous_span_iterator& rhs) const { return rhs < *this; }
bool operator>=(const contiguous_span_iterator& rhs) const { return !(rhs > *this); }
void swap(contiguous_span_iterator& rhs) noexcept
void swap(contiguous_span_iterator & rhs) noexcept
{
std::swap(data_, rhs.data_);
std::swap(m_validator, rhs.m_validator);
@@ -2174,7 +2152,7 @@ contiguous_span_iterator<Span> operator+(typename contiguous_span_iterator<Span>
}
template <typename Span>
class general_span_iterator {
class [[deprecated]] general_span_iterator {
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = typename Span::value_type;
@@ -2257,7 +2235,7 @@ public:
bool operator<=(const general_span_iterator& rhs) const { return !(rhs < *this); }
bool operator>(const general_span_iterator& rhs) const { return rhs < *this; }
bool operator>=(const general_span_iterator& rhs) const { return !(rhs > *this); }
void swap(general_span_iterator& rhs) noexcept
void swap(general_span_iterator & rhs) noexcept
{
std::swap(m_itr, rhs.m_itr);
std::swap(m_container, rhs.m_container);
@@ -2273,7 +2251,7 @@ general_span_iterator<Span> operator+(typename general_span_iterator<Span>::diff
} // namespace gsl
#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER < 1910
#undef constexpr
@@ -2284,8 +2262,12 @@ general_span_iterator<Span> operator+(typename general_span_iterator<Span>::diff
#endif // _MSC_VER
#if __GNUC__ > 6
#if defined(__GNUC__) && __GNUC__ > 6
#pragma GCC diagnostic pop
#endif // __GNUC__ > 6
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif
#endif // GSL_MULTI_SPAN_H
+111 -7
View File
@@ -25,7 +25,7 @@
#include <system_error> // for hash
#include <type_traits> // for enable_if_t, is_convertible, is_assignable
#if defined(_MSC_VER) && _MSC_VER < 1910
#if defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__)
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
@@ -72,13 +72,13 @@ public:
static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr explicit not_null(U&& u) : ptr_(std::forward<U>(u))
constexpr not_null(U&& u) : ptr_(std::forward<U>(u))
{
Expects(ptr_ != nullptr);
}
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
constexpr explicit not_null(T u) : ptr_(u)
constexpr not_null(T u) : ptr_(u)
{
Expects(ptr_ != nullptr);
}
@@ -100,7 +100,7 @@ public:
constexpr operator T() const { return get(); }
constexpr T operator->() const { return get(); }
constexpr decltype(auto) operator*() const { return *get(); }
constexpr decltype(auto) operator*() const { return *get(); }
// prevents compilation when someone attempts to assign a null pointer constant
not_null(std::nullptr_t) = delete;
@@ -121,7 +121,7 @@ private:
template <class T>
auto make_not_null(T&& t) {
return gsl::not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)};
return not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)};
}
template <class T>
@@ -189,10 +189,114 @@ struct hash<gsl::not_null<T>>
} // namespace std
#if defined(_MSC_VER) && _MSC_VER < 1910
namespace gsl
{
//
// strict_not_null
//
// Restricts a pointer or smart pointer to only hold non-null values,
//
// - provides a strict (i.e. explicit constructor from T) wrapper of not_null
// - to be used for new code that wishes the design to be cleaner and make not_null
// checks intentional, or in old code that would like to make the transition.
//
// To make the transition from not_null, incrementally replace not_null
// by strict_not_null and fix compilation errors
//
// Expect to
// - remove all unneeded conversions from raw pointer to not_null and back
// - make API clear by specifying not_null in parameters where needed
// - remove unnecessary asserts
//
template <class T>
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))
{}
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)
{}
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)
{}
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)
{}
strict_not_null(strict_not_null&& other) = 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)
{
not_null<T>::operator=(other);
return *this;
}
// prevents compilation when someone attempts to assign a null pointer constant
strict_not_null(std::nullptr_t) = delete;
strict_not_null& operator=(std::nullptr_t) = delete;
// unwanted operators...pointers only point to single objects!
strict_not_null& operator++() = delete;
strict_not_null& operator--() = delete;
strict_not_null operator++(int) = delete;
strict_not_null operator--(int) = delete;
strict_not_null& operator+=(std::ptrdiff_t) = delete;
strict_not_null& operator-=(std::ptrdiff_t) = delete;
void operator[](std::ptrdiff_t) const = delete;
};
// more unwanted operators
template <class T, class U>
std::ptrdiff_t operator-(const strict_not_null<T>&, const strict_not_null<U>&) = delete;
template <class T>
strict_not_null<T> operator-(const strict_not_null<T>&, std::ptrdiff_t) = delete;
template <class T>
strict_not_null<T> operator+(const strict_not_null<T>&, std::ptrdiff_t) = delete;
template <class T>
strict_not_null<T> operator+(std::ptrdiff_t, const strict_not_null<T>&) = delete;
template <class T>
auto make_strict_not_null(T&& t) {
return strict_not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)};
}
#if ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) )
// deduction guides to prevent the ctad-maybe-unsupported warning
template <class T> not_null(T) -> not_null<T>;
template <class T> strict_not_null(T) -> strict_not_null<T>;
#endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) )
} // namespace gsl
namespace std
{
template <class T>
struct hash<gsl::strict_not_null<T>>
{
std::size_t operator()(const gsl::strict_not_null<T>& value) const { return hash<T>{}(value); }
};
} // namespace std
#if defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__)
#undef constexpr
#pragma pop_macro("constexpr")
#endif // defined(_MSC_VER) && _MSC_VER < 1910
#endif // defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__)
#endif // GSL_POINTERS_H
+29 -15
View File
@@ -31,7 +31,7 @@
#include <utility>
#include <memory> // for std::addressof
#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
// turn off some warnings that are noisy about our Expects statements
@@ -61,7 +61,7 @@
// compiletime, so the compiler wouldn't have to warn indiscriminently, but
// could check if the source value actually doesn't fit into the target type
// and only warn in those cases.
#if __GNUC__ > 6
#if defined(__GNUC__) && __GNUC__ > 6
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
@@ -141,7 +141,7 @@ namespace details
span_iterator() = default;
constexpr span_iterator(const Span* span, typename Span::index_type idx) noexcept
constexpr span_iterator(const Span* span, difference_type idx) noexcept
: span_(span), index_(idx)
{}
@@ -394,17 +394,27 @@ public:
: storage_(KnownNotNull{std::addressof(arr[0])}, details::extent_type<N>())
{}
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
// GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
constexpr span(std::array<ArrayElementType, N>& arr) noexcept
: storage_(arr.data(), details::extent_type<N>())
{}
template <std::size_t N, class = std::enable_if_t<(N > 0)>>
constexpr span(std::array<std::remove_const_t<element_type>, N>& arr) noexcept
: storage_(KnownNotNull{arr.data()}, details::extent_type<N>())
{
}
template <std::size_t N>
// GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
constexpr span(std::array<std::remove_const_t<element_type>, 0>&) noexcept
: storage_(static_cast<pointer>(nullptr), details::extent_type<0>())
{
}
template <std::size_t N, class = std::enable_if_t<(N > 0)>>
constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) noexcept
: storage_(arr.data(), details::extent_type<N>())
{}
: storage_(KnownNotNull{arr.data()}, details::extent_type<N>())
{
}
constexpr span(const std::array<std::remove_const_t<element_type>, 0>&) noexcept
: storage_(static_cast<pointer>(nullptr), details::extent_type<0>())
{
}
// NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
// on Container to be a contiguous sequence container.
@@ -534,7 +544,7 @@ public:
#endif // _MSC_VER
private:
static bool CheckRange(index_type idx, index_type size)
static constexpr bool CheckRange(index_type idx, index_type size) noexcept
{
// Optimization:
//
@@ -546,7 +556,11 @@ private:
// wrap around to a value always greater than size when casted.
// check if we have enough space to wrap around
#if defined(__cpp_if_constexpr)
if constexpr (sizeof(index_type) <= sizeof(size_t))
#else
if (sizeof(index_type) <= sizeof(size_t))
#endif
{
return narrow_cast<size_t>(idx) < narrow_cast<size_t>(size);
}
@@ -762,7 +776,7 @@ constexpr ElementType& at(span<ElementType, Extent> s, index i)
} // namespace gsl
#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER < 1910
#undef constexpr
#pragma pop_macro("constexpr")
@@ -772,7 +786,7 @@ constexpr ElementType& at(span<ElementType, Extent> s, index i)
#pragma warning(pop)
#endif // _MSC_VER
#if __GNUC__ > 6
#if defined(__GNUC__) && __GNUC__ > 6
#pragma GCC diagnostic pop
#endif // __GNUC__ > 6
+5 -3
View File
@@ -20,7 +20,6 @@
#include <gsl/gsl_assert> // for Ensures, Expects
#include <gsl/gsl_util> // for narrow_cast
#include <gsl/span> // for operator!=, operator==, dynamic_extent
#include <gsl/pointers> // for not_null
#include <algorithm> // for equal, lexicographical_compare
#include <array> // for array
@@ -30,7 +29,7 @@
#include <string> // for basic_string, allocator, char_traits
#include <type_traits> // for declval, is_convertible, enable_if_t, add_...
#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool.
@@ -175,6 +174,7 @@ class 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>>;
@@ -186,6 +186,8 @@ public:
using reverse_iterator = typename impl_type::reverse_iterator;
using const_reverse_iterator = typename impl_type::const_reverse_iterator;
using size_type = index_type;
// default (empty)
constexpr basic_string_span() noexcept = default;
@@ -706,7 +708,7 @@ bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other)
#endif
} // namespace gsl
#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(pop)
#if _MSC_VER < 1910
-130
View File
@@ -1,130 +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_TRANSITION_H
#define GSL_TRANSITION_H
#include <gsl/gsl_assert> // for Ensures, Expects
#include <gsl/pointers> // for gsl::not_null
#if defined(_MSC_VER) && _MSC_VER < 1910
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
#endif // defined(_MSC_VER) && _MSC_VER < 1910
namespace gsl_helpers
{
//
// sloppy_not_null
//
// Restricts a pointer or smart pointer to only hold non-null values,
//
// - provides a sloppy (i.e. no explicit contructor from T) wrapper of gsl::not_null
// - is temporary, only to be used to incrementally transition of code
// using older version of gsl::not_null to the new one that made the constructor explicit
//
// To make the transition:
//
// - replace all occurences of gsl::not_null in your code by sloppy_not_null
// variant: rename gsl::not_null by NotNull by including the following in your code,
// foe example, in a common include file:
//
// template<typename T>
// using NotNull = gsl::not_null<T>;
//
// compile using old version of GSL
// change GSL version and replace gsl::not_null by gsl_helpers::sloppy_not_null
// in the added code lines above
//
// - compile - compilation should be successful
// - replace some sloppy_not_nulls by gsl::not_null, fix compilation erros,
// redesign as needed, compile and test
// - repeat until no sloppy_not_nulls remain
//
template <class T>
class sloppy_not_null: public gsl::not_null<T>
{
public:
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr sloppy_not_null(U&& u) :
gsl::not_null<T>(std::forward<U>(u))
{}
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
constexpr sloppy_not_null(T u) :
gsl::not_null<T>(u)
{}
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr sloppy_not_null(const gsl::not_null<U>& other) :
gsl::not_null<T>(other)
{}
sloppy_not_null(sloppy_not_null&& other) = default;
sloppy_not_null(const sloppy_not_null& other) = default;
sloppy_not_null& operator=(const sloppy_not_null& other) = default;
sloppy_not_null& operator=(const gsl::not_null<T>& other)
{
gsl::not_null<T>::operator=(other);
return *this;
}
// prevents compilation when someone attempts to assign a null pointer constant
sloppy_not_null(std::nullptr_t) = delete;
sloppy_not_null& operator=(std::nullptr_t) = delete;
// unwanted operators...pointers only point to single objects!
sloppy_not_null& operator++() = delete;
sloppy_not_null& operator--() = delete;
sloppy_not_null operator++(int) = delete;
sloppy_not_null operator--(int) = delete;
sloppy_not_null& operator+=(std::ptrdiff_t) = delete;
sloppy_not_null& operator-=(std::ptrdiff_t) = delete;
void operator[](std::ptrdiff_t) const = delete;
};
// more unwanted operators
template <class T, class U>
std::ptrdiff_t operator-(const sloppy_not_null<T>&, const sloppy_not_null<U>&) = delete;
template <class T>
sloppy_not_null<T> operator-(const sloppy_not_null<T>&, std::ptrdiff_t) = delete;
template <class T>
sloppy_not_null<T> operator+(const sloppy_not_null<T>&, std::ptrdiff_t) = delete;
template <class T>
sloppy_not_null<T> operator+(std::ptrdiff_t, const sloppy_not_null<T>&) = delete;
} // namespace gsl
namespace std
{
template <class T>
struct hash<gsl_helpers::sloppy_not_null<T>>
{
std::size_t operator()(const gsl_helpers::sloppy_not_null<T>& value) const { return hash<T>{}(value); }
};
} // namespace std
#if defined(_MSC_VER) && _MSC_VER < 1910
#undef constexpr
#pragma pop_macro("constexpr")
#endif // defined(_MSC_VER) && _MSC_VER < 1910
#endif // GSL_TRANSITION_H
+64 -30
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8.7)
cmake_minimum_required(VERSION 3.0.2)
project(GSLTests CXX)
@@ -33,14 +33,24 @@ endif()
# this interface adds compile options to how the tests are run
# please try to keep entries ordered =)
add_library(gsl_tests_config INTERFACE)
target_compile_options(gsl_tests_config INTERFACE
$<$<CXX_COMPILER_ID:MSVC>:
if(MSVC) # MSVC or simulating MSVC
target_compile_options(gsl_tests_config INTERFACE
${GSL_CPLUSPLUS_OPT}
/EHsc
/W4
/WX
>
${GSL_CPLUSPLUS_OPT}
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:
$<$<CXX_COMPILER_ID:Clang>:
-Weverything
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-missing-braces
-Wno-missing-prototypes
-Wno-unknown-attributes
$<$<EQUAL:${GSL_CXX_STANDARD},14>:-Wno-unused-member-function>
>
)
else()
target_compile_options(gsl_tests_config INTERFACE
-fno-strict-aliasing
-Wall
-Wcast-align
@@ -48,16 +58,25 @@ target_compile_options(gsl_tests_config INTERFACE
-Wctor-dtor-privacy
-Werror
-Wextra
-Wno-missing-braces
-Wno-unknown-attributes
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wpedantic
-Wshadow
-Wsign-conversion
>
)
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
-Weverything
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-missing-braces
-Wno-missing-prototypes
-Wno-padded
-Wno-unknown-attributes
$<$<EQUAL:${GSL_CXX_STANDARD},14>:-Wno-unused-member-function>
-Wno-weak-vtables
>
$<$<CXX_COMPILER_ID:Clang>:
$<$<CXX_COMPILER_VERSION:5.0.2>:-Wno-undefined-func-template>
>
)
endif(MSVC)
# for tests to find the catch header
target_include_directories(gsl_tests_config INTERFACE
@@ -107,7 +126,7 @@ add_gsl_test(utils_tests)
add_gsl_test(owner_tests)
add_gsl_test(byte_tests)
add_gsl_test(algorithm_tests)
add_gsl_test(sloppy_notnull_tests)
add_gsl_test(strict_notnull_tests)
# No exception tests
@@ -121,34 +140,49 @@ endforeach(flag_var)
# this interface adds compile options to how the tests are run
# please try to keep entries ordered =)
add_library(gsl_tests_config_noexcept INTERFACE)
target_compile_options(gsl_tests_config_noexcept INTERFACE
$<$<CXX_COMPILER_ID:MSVC>:
/D_HAS_EXCEPTIONS=0
/wd4702
/wd4577
if(MSVC) # MSVC or simulating MSVC
target_compile_definitions(gsl_tests_config_noexcept INTERFACE
_HAS_EXCEPTIONS=0
)
target_compile_options(gsl_tests_config_noexcept INTERFACE
${GSL_CPLUSPLUS_OPT}
/W4
/WX
>
${GSL_CPLUSPLUS_OPT}
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:
-fno-strict-aliasing
$<$<CXX_COMPILER_ID:MSVC>:
/wd4577
/wd4702
>
$<$<CXX_COMPILER_ID:Clang>:
-Weverything
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-missing-prototypes
-Wno-unknown-attributes
>
)
else()
target_compile_options(gsl_tests_config_noexcept INTERFACE
-fno-exceptions
-fno-strict-aliasing
-Wall
-Wcast-align
-Wconversion
-Wctor-dtor-privacy
-Werror
-Wextra
-Wno-missing-braces
-Wno-unknown-attributes
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wpedantic
-Wshadow
-Wsign-conversion
>
)
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
-Weverything
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-missing-prototypes
-Wno-unknown-attributes
-Wno-weak-vtables
>
)
endif(MSVC)
# set definitions for tests
target_compile_definitions(gsl_tests_config_noexcept INTERFACE
+10
View File
@@ -18,6 +18,12 @@
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#pragma warning(disable : 4996) // use of function or classes marked [[deprecated]]
#endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, TEST_CASE
@@ -113,3 +119,7 @@ TEST_CASE("bounds_convertible")
#ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static);
#endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif
+16 -2
View File
@@ -17,8 +17,14 @@
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#pragma warning(disable : 26440 26426) // from catch
#pragma warning(disable : 4996) // multi_span is in the process of being deprecated.
// Suppressing warnings until it is completely removed
#endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHECK...
@@ -1220,6 +1226,8 @@ TEST_CASE("md_access")
expected += 3;
}
}
delete[] image_ptr;
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
@@ -1616,6 +1624,8 @@ TEST_CASE("span_structure_size")
multi_span<const double, dynamic_range, 6, 4> av2 =
as_multi_span(av1, dim(5), dim<6>(), dim<4>());
(void) av2;
delete[] arr;
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
@@ -1782,4 +1792,8 @@ TEST_CASE("iterator")
#ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static);
#endif
#endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif
+6 -11
View File
@@ -14,25 +14,21 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <cstdlib> // for std::exit
#include <gsl/span> // for span
#include <cstdlib> // for std::exit
#include <gsl/span> // for span
int operator_subscript_no_throw() noexcept
{
int arr[10];
const gsl::span<int> sp { arr };
int arr[10];
const gsl::span<int> sp{arr};
return sp[11];
}
void test_terminate()
{
std::exit(0);
}
[[noreturn]] void test_terminate() { std::exit(0); }
void setup_termination_handler() noexcept
{
#if defined(_MSC_VER)
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
auto& handler = gsl::details::get_terminate_handler();
handler = &test_terminate;
@@ -44,7 +40,6 @@ void setup_termination_handler() noexcept
#endif
}
int main() noexcept
{
setup_termination_handler();
+5 -9
View File
@@ -14,24 +14,21 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <cstdlib> // for std::exit
#include <gsl/gsl_util> // for narrow
#include <cstdlib> // for std::exit
#include <gsl/gsl_assert> // for get_terminate
#include <gsl/gsl_util> // for narrow
int narrow_no_throw()
{
const long long bigNumber = 0x0fffffffffffffff;
return gsl::narrow<int>(bigNumber);
return gsl::narrow<int>(bigNumber);
}
void test_terminate()
{
std::exit(0);
}
[[noreturn]] void test_terminate() { std::exit(0); }
void setup_termination_handler() noexcept
{
#if defined(_MSC_VER)
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
auto& handler = gsl::details::get_terminate_handler();
handler = &test_terminate;
@@ -43,7 +40,6 @@ void setup_termination_handler() noexcept
#endif
}
int main()
{
setup_termination_handler();
+93 -35
View File
@@ -25,7 +25,7 @@
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
#include <algorithm> // for addressof
#include <memory> // for shared_ptr, make_shared, operator<, opera...
@@ -128,47 +128,105 @@ struct NonCopyableNonMovable
};
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool helper(not_null<int*> p)
{
return *p == 12;
}
bool helper(not_null<int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool helper_const(not_null<const int*> p)
{
return *p == 12;
}
bool helper_const(not_null<const int*> p) { return *p == 12; }
int* return_pointer() { return nullptr; }
const int* return_pointer_const() { return nullptr; }
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("TestNotNullConstructors")
{
{
#ifdef CONFIRM_COMPILATION_ERRORS
not_null<int*> p = nullptr; // yay...does not compile!
not_null<std::vector<char>*> p = 0; // yay...does not compile!
not_null<int*> p; // yay...does not compile!
std::unique_ptr<int> up = std::make_unique<int>(120);
not_null<int*> p = up;
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;
// Forbid non-nullptr assignable types
not_null<std::vector<int>> f(std::vector<int>{1});
not_null<int> z(10);
not_null<std::vector<int>> y({1, 2});
// Forbid non-nullptr assignable types
not_null<std::vector<int>> f(std::vector<int>{1});
not_null<int> z(10);
not_null<std::vector<int>> y({1, 2});
#endif
int i = 12;
auto rp = RefCounted<int>(&i);
not_null<int*> p(rp);
CHECK(p.get() == &i);
}
not_null<std::shared_ptr<int>> x(
std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
{
// from shared pointer
int i = 12;
auto rp = RefCounted<int>(&i);
not_null<int*> p(rp);
CHECK(p.get() == &i);
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
int* pi = nullptr;
CHECK_THROWS_AS(not_null<decltype(pi)>(pi), fail_fast);
#endif
not_null<std::shared_ptr<int>> x(
std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
int* pi = nullptr;
CHECK_THROWS_AS(not_null<decltype(pi)>(pi), fail_fast);
}
{
// from pointer to local
int t = 42;
not_null<int*> x = &t;
helper(&t);
helper_const(&t);
CHECK(*x == 42);
}
{
// from raw pointer
// from not_null pointer
int t = 42;
int* p = &t;
not_null<int*> x = p;
helper(p);
helper_const(p);
helper(x);
helper_const(x);
CHECK(*x == 42);
}
{
// from raw const pointer
// from not_null const pointer
int t = 42;
const int* cp = &t;
not_null<const int*> x = cp;
helper_const(cp);
helper_const(x);
CHECK(*x == 42);
}
{
// from not_null const pointer, using auto
int t = 42;
const int* cp = &t;
auto x = not_null<const int*>{cp};
CHECK(*x == 42);
}
{
// from returned pointer
CHECK_THROWS_AS(helper(return_pointer()), fail_fast);
CHECK_THROWS_AS(helper_const(return_pointer()), fail_fast);
}
}
template<typename T>
template <typename T>
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
void ostream_helper(T v)
{
@@ -176,8 +234,8 @@ void ostream_helper(T v)
{
std::ostringstream os;
std::ostringstream ref;
os << p;
ref << &v;
os << static_cast<void*>(p);
ref << static_cast<void*>(&v);
CHECK(os.str() == ref.str());
}
{
@@ -193,7 +251,7 @@ TEST_CASE("TestNotNullostream")
{
ostream_helper<int>(17);
ostream_helper<float>(21.5f);
ostream_helper<double>(3.4566e-7f);
ostream_helper<double>(3.4566e-7);
ostream_helper<char>('c');
ostream_helper<uint16_t>(0x0123u);
ostream_helper<const char*>("cstring");
@@ -474,5 +532,5 @@ TEST_CASE("TestMakeNotNull")
#endif
}
static_assert(std::is_nothrow_move_constructible<not_null<void *>>::value, "not_null must be no-throw move constructible");
static_assert(std::is_nothrow_move_constructible<not_null<void*>>::value,
"not_null must be no-throw move constructible");
-124
View File
@@ -1,124 +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.
//
///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
// Fix VS2015 build breaks in Release
#pragma warning(disable : 4702) // unreachable code
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
#include <samples/gsl_transition> // for sloppy_not_null
namespace gsl
{
struct fail_fast;
} // namespace gsl
using namespace gsl;
using namespace gsl_helpers;
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool helper(not_null<int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool helper_const(not_null<const int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool sloppy_helper(sloppy_not_null<int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool sloppy_helper_const(sloppy_not_null<const int*> p) { return *p == 12; }
TEST_CASE("TestSloppyNotNull")
{
{
// raw ptr <-> sloppy_not_null
int x = 42;
const sloppy_not_null<int*> snn = &x;
sloppy_helper(&x);
sloppy_helper_const(&x);
CHECK(*snn == 42);
}
{
// sloppy_not_null -> sloppy_not_null
int x = 42;
sloppy_not_null<int*> snn1{&x};
const sloppy_not_null<int*> snn2{&x};
sloppy_helper(snn1);
sloppy_helper_const(snn1);
CHECK(snn1 == snn2);
}
{
// sloppy_not_null -> not_null
int x = 42;
sloppy_not_null<int*> snn{&x};
const not_null<int*> nn1 = snn;
const not_null<int*> nn2{snn};
helper(snn);
helper_const(snn);
CHECK(snn == nn1);
CHECK(snn == nn2);
}
{
// not_null -> sloppy_not_null
int x = 42;
not_null<int*> nn{&x};
const sloppy_not_null<int*> snn1{nn};
const sloppy_not_null<int*> snn2 = nn;
sloppy_helper(nn);
sloppy_helper_const(nn);
CHECK(snn1 == nn);
CHECK(snn2 == nn);
std::hash<sloppy_not_null<int*>> hash_snn;
std::hash<not_null<int*>> hash_nn;
CHECK(hash_nn(snn1) == hash_nn(nn));
CHECK(hash_snn(snn1) == hash_nn(nn));
CHECK(hash_nn(snn1) == hash_nn(snn2));
CHECK(hash_snn(snn1) == hash_snn(nn));
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
sloppy_not_null<int*> p{nullptr};
}
#endif
}
static_assert(std::is_nothrow_move_constructible<sloppy_not_null<void*>>::value,
"sloppy_not_null must be no-throw move constructible");
+18 -7
View File
@@ -37,9 +37,10 @@
#include <type_traits> // for integral_constant<>::value, is_default_co...
#include <vector> // for vector
namespace gsl {
namespace gsl
{
struct fail_fast;
} // namespace gsl
} // namespace gsl
using namespace std;
using namespace gsl;
@@ -54,9 +55,12 @@ struct DerivedClass : BaseClass
};
struct AddressOverloaded
{
#if (__cplusplus > 201402L)
[[maybe_unused]]
#endif
AddressOverloaded operator&() const { return {}; }
};
}
} // namespace
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("default_constructor")
@@ -452,7 +456,13 @@ TEST_CASE("from_std_array_constructor")
CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()));
}
std::array<AddressOverloaded, 4> ao_arr{};
{
std::array<int, 0> empty_arr{};
span<int> s{empty_arr};
CHECK((s.size() == 0 && s.empty()));
}
std::array<AddressOverloaded, 4> ao_arr{};
{
span<AddressOverloaded, 4> fs{ao_arr};
@@ -500,15 +510,16 @@ TEST_CASE("from_std_array_constructor")
CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()));
}
// This test checks for the bug found in gcc 6.1, 6.2, 6.3, 7.1, 7.2, 7.3 - issue #590
// This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590
{
span<int> s1 = make_span(arr);
static span<int> s2;
s2 = s1;
#if __GNUC__ == 6 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
// Known to be broken in gcc 6.4 with optimizations
#if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
__GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
// Known to be broken in gcc 6.4 and 6.5 with optimizations
// Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116
CHECK(s1.size() == 4);
CHECK(s2.size() == 0);
+193
View File
@@ -0,0 +1,193 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
// Fix VS2015 build breaks in Release
#pragma warning(disable : 4702) // unreachable code
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
namespace gsl
{
struct fail_fast;
} // namespace gsl
using namespace gsl;
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool helper(not_null<int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool helper_const(not_null<const int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool strict_helper(strict_not_null<int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool strict_helper_const(strict_not_null<const int*> p) { return *p == 12; }
int* return_pointer() { return nullptr; }
const int* return_pointer_const() { return nullptr; }
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("TestStrictNotNull")
{
{
// raw ptr <-> strict_not_null
int x = 42;
#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
const strict_not_null<int*> snn1{&x};
helper(snn1);
helper_const(snn1);
CHECK(*snn1 == 42);
}
{
// strict_not_null -> strict_not_null
int x = 42;
strict_not_null<int*> snn1{&x};
const strict_not_null<int*> snn2{&x};
strict_helper(snn1);
strict_helper_const(snn1);
strict_helper_const(snn2);
CHECK(snn1 == snn2);
}
{
// strict_not_null -> not_null
int x = 42;
strict_not_null<int*> snn{&x};
const not_null<int*> nn1 = snn;
const not_null<int*> nn2{snn};
helper(snn);
helper_const(snn);
CHECK(snn == nn1);
CHECK(snn == nn2);
}
{
// not_null -> strict_not_null
int x = 42;
not_null<int*> nn{&x};
const strict_not_null<int*> snn1{nn};
const strict_not_null<int*> snn2{nn};
strict_helper(nn);
strict_helper_const(nn);
CHECK(snn1 == nn);
CHECK(snn2 == nn);
std::hash<strict_not_null<int*>> hash_snn;
std::hash<not_null<int*>> hash_nn;
CHECK(hash_nn(snn1) == hash_nn(nn));
CHECK(hash_snn(snn1) == hash_nn(nn));
CHECK(hash_nn(snn1) == hash_nn(snn2));
CHECK(hash_snn(snn1) == hash_snn(nn));
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
strict_not_null<int*> p{nullptr};
}
#endif
}
#if defined(__cplusplus) && (__cplusplus >= 201703L)
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("TestStrictNotNullConstructorTypeDeduction")
{
{
int i = 42;
strict_not_null x{&i};
helper(strict_not_null{&i});
helper_const(strict_not_null{&i});
CHECK(*x == 42);
}
{
int i = 42;
int* p = &i;
strict_not_null x{p};
helper(strict_not_null{p});
helper_const(strict_not_null{p});
CHECK(*x == 42);
}
{
auto workaround_macro = []() {
int* p1 = nullptr;
const strict_not_null x{p1};
};
CHECK_THROWS_AS(workaround_macro(), fail_fast);
}
{
auto workaround_macro = []() {
const int* p1 = nullptr;
const strict_not_null x{p1};
};
CHECK_THROWS_AS(workaround_macro(), fail_fast);
}
{
int* p = nullptr;
CHECK_THROWS_AS(helper(strict_not_null{p}), fail_fast);
CHECK_THROWS_AS(helper_const(strict_not_null{p}), fail_fast);
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
strict_not_null x{nullptr};
helper(strict_not_null{nullptr});
helper_const(strict_not_null{nullptr});
}
#endif
}
#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
static_assert(std::is_nothrow_move_constructible<strict_not_null<void*>>::value,
"strict_not_null must be no-throw move constructible");
+17 -7
View File
@@ -17,8 +17,14 @@
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#pragma warning(disable : 26440 26426) // from catch deprecated
#pragma warning(disable : 4996) // strided_span is in the process of being deprecated.
// Suppressing warnings until it is completely removed
#endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHECK...
@@ -117,7 +123,7 @@ TEST_CASE("strided_span_constructors")
CHECK(sav.bounds().strides() == multi_span_index<1>{1});
CHECK(sav[1] == 2);
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
// strided_span<const int, 1> sav_c{ {src}, {2, 1} };
strided_span<const int, 1> sav_c{multi_span<const int>{src},
strided_bounds<1>{2, 1}};
@@ -129,7 +135,7 @@ TEST_CASE("strided_span_constructors")
CHECK(sav_c.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_c[1] == 2);
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<volatile int, 1> sav_v{src, {2, 1}};
#else
strided_span<volatile int, 1> sav_v{multi_span<volatile int>{src},
@@ -139,7 +145,7 @@ TEST_CASE("strided_span_constructors")
CHECK(sav_v.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_v[1] == 2);
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
#else
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
@@ -159,7 +165,7 @@ TEST_CASE("strided_span_constructors")
CHECK(sav_c.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_c[1] == 2);
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
#else
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
@@ -180,7 +186,7 @@ TEST_CASE("strided_span_constructors")
CHECK(sav_v.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_v[1] == 2);
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
#else
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
@@ -598,7 +604,7 @@ void iterate_every_other_element(multi_span<int, dynamic_range> av)
// pick every other element
auto length = av.size() / 2;
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
auto bounds = strided_bounds<1>({length}, {2});
#else
auto bounds = strided_bounds<1>(multi_span_index<1>{length}, multi_span_index<1>{2});
@@ -794,3 +800,7 @@ TEST_CASE("strided_span_conversion")
i++;
}
}
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif
+2 -1
View File
@@ -20,7 +20,8 @@
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26401 26409 26415 26418 26426 26429 26432 26433 26434 26435 26436 26439 26440 26443 26444 26446 26447 26451 26460 26461 26466 26472 26481 26482 26485 26492 26493 26494 26495 26496 26497) // from catch
#include <CodeAnalysis/Warnings.h>
#pragma warning(disable : ALL_CODE_ANALYSIS_WARNINGS) // from catch
#endif // _MSC_VER
#include <catch/catch.hpp>
+5 -1
View File
@@ -80,7 +80,7 @@ TEST_CASE("finally_function_with_bind")
CHECK(i == 1);
}
int j = 0;
static int j = 0;
void g() { j += 1; }
TEST_CASE("finally_function_ptr")
{
@@ -126,4 +126,8 @@ TEST_CASE("narrow")
n = -42;
CHECK_THROWS_AS(narrow<unsigned>(n), narrowing_error);
#if GSL_CONSTEXPR_NARROW
static_assert(narrow<char>(120) == 120, "Fix GSL_CONSTEXPR_NARROW");
#endif
}