mirror of
https://github.com/microsoft/GSL.git
synced 2026-08-06 13:44:09 +02:00
Compare commits
87 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e99e76c97 | |||
| 263440f2a1 | |||
| a7759e6d3f | |||
| 128b4356ac | |||
| 8e481ebe19 | |||
| 4610f26b33 | |||
| d0e5daf441 | |||
| 9939d5889b | |||
| 22cba52114 | |||
| 97dc8f83fc | |||
| 71ec9f84d8 | |||
| 3d56ba9e7f | |||
| cf9cc34da8 | |||
| 0a78d8ea3c | |||
| 02d1051fdd | |||
| 275e0176c0 | |||
| 4b289d4cf0 | |||
| 6ff4a5287d | |||
| 2b8f7aea32 | |||
| 7adf7eb6fe | |||
| 5e4463a7c1 | |||
| 10ce5b634f | |||
| eb995b3671 | |||
| b630dfe36a | |||
| e026971c03 | |||
| bbeb0bdc91 | |||
| 23066c829f | |||
| a454d295ed | |||
| ba9af38494 | |||
| d5382a293b | |||
| 787e7ef616 | |||
| 1046c9d247 | |||
| b576cc6ce3 | |||
| 2ce3177ebd | |||
| cee1929de7 | |||
| 1d48188de9 | |||
| b05a4464b9 | |||
| 1212beae77 | |||
| 66809c6852 | |||
| b74b286d5e | |||
| 2a1ef25406 | |||
| 7d78b743e4 | |||
| 6418b5f4de | |||
| 6eeed739f1 | |||
| 9ff6e19ea9 | |||
| 7a7d025ffa | |||
| be3c3c2731 | |||
| 0f68d133fa | |||
| 88aca1caf3 | |||
| 2e4d0d7e22 | |||
| 5a7093f983 | |||
| b673375719 | |||
| c02ddae4bc | |||
| 2bf9f137a6 | |||
| 1995e86d1a | |||
| 585f48ce55 | |||
| 86be2366c7 | |||
| 55aad0ab6d | |||
| 5016ce4a4d | |||
| 6241b3faa6 | |||
| 831584d947 | |||
| f1a2e91e4e | |||
| cea0d0ac2b | |||
| 6a75903c79 | |||
| b6c531f7c1 | |||
| f4a715816c | |||
| 1f76fbd168 | |||
| 5778149583 | |||
| 0cebbd77bf | |||
| 21cb6bb8b0 | |||
| a9ef39f14a | |||
| ffdaf0fb21 | |||
| cb2d1af89a | |||
| 75ad0c1b40 | |||
| 51ae678d08 | |||
| 2be3b00faf | |||
| d6a2242d97 | |||
| cee3125af7 | |||
| 5cbde3008a | |||
| d6b26b367b | |||
| c4c1f6395a | |||
| d933e51b8b | |||
| 2fc94db3eb | |||
| fbe867a9c4 | |||
| 697eb5533e | |||
| 9c5e21045d | |||
| d25969dbdf |
+14
-1
@@ -5,7 +5,19 @@ IndentWidth: 4
|
||||
AccessModifierOffset: -4
|
||||
NamespaceIndentation: Inner
|
||||
|
||||
BreakBeforeBraces: Allman
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterNamespace: true
|
||||
AfterEnum: true
|
||||
AfterStruct: true
|
||||
AfterClass: true
|
||||
SplitEmptyFunction: false
|
||||
AfterControlStatement: true
|
||||
AfterFunction: true
|
||||
AfterUnion: true
|
||||
BeforeElse: true
|
||||
|
||||
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
@@ -19,3 +31,4 @@ AlignConsecutiveAssignments: false
|
||||
AlignTrailingComments: true
|
||||
|
||||
SpaceAfterCStyleCast: true
|
||||
CommentPragmas: '^ NO-FORMAT:'
|
||||
|
||||
+91
-35
@@ -23,23 +23,23 @@ matrix:
|
||||
##########################################################################
|
||||
|
||||
# XCode 8.3
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Debug
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode8.3
|
||||
compiler: clang
|
||||
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Release
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode8.3
|
||||
compiler: clang
|
||||
|
||||
# XCode 9.1
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Debug
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode9.1
|
||||
compiler: clang
|
||||
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Release
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode9.1
|
||||
compiler: clang
|
||||
@@ -49,7 +49,7 @@ matrix:
|
||||
##########################################################################
|
||||
|
||||
# Clang 3.6
|
||||
- env: COMPILER=clang++-3.6 BUILD_TYPE=Debug
|
||||
- env: COMPILER=clang++-3.6 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang36
|
||||
apt:
|
||||
packages:
|
||||
@@ -59,11 +59,11 @@ matrix:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.6
|
||||
|
||||
- env: COMPILER=clang++-3.6 BUILD_TYPE=Release
|
||||
- env: COMPILER=clang++-3.6 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang36
|
||||
|
||||
# Clang 3.7
|
||||
- env: COMPILER=clang++-3.7 BUILD_TYPE=Debug
|
||||
- env: COMPILER=clang++-3.7 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang37
|
||||
apt:
|
||||
packages:
|
||||
@@ -73,11 +73,11 @@ matrix:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.7
|
||||
|
||||
- env: COMPILER=clang++-3.7 BUILD_TYPE=Release
|
||||
- env: COMPILER=clang++-3.7 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang37
|
||||
|
||||
# Clang 3.8
|
||||
- env: COMPILER=clang++-3.8 BUILD_TYPE=Debug
|
||||
- env: COMPILER=clang++-3.8 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang38
|
||||
apt:
|
||||
packages:
|
||||
@@ -87,11 +87,11 @@ matrix:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- env: COMPILER=clang++-3.8 BUILD_TYPE=Release
|
||||
- env: COMPILER=clang++-3.8 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang38
|
||||
|
||||
# Clang 3.9
|
||||
- env: COMPILER=clang++-3.9 BUILD_TYPE=Debug
|
||||
- env: COMPILER=clang++-3.9 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang39
|
||||
apt:
|
||||
packages:
|
||||
@@ -101,11 +101,11 @@ matrix:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.9
|
||||
|
||||
- env: COMPILER=clang++-3.9 BUILD_TYPE=Release
|
||||
- env: COMPILER=clang++-3.9 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang39
|
||||
|
||||
# Clang 4.0
|
||||
- env: COMPILER=clang++-4.0 BUILD_TYPE=Debug
|
||||
- env: COMPILER=clang++-4.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang40
|
||||
apt:
|
||||
packages:
|
||||
@@ -115,63 +115,119 @@ matrix:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
|
||||
- env: COMPILER=clang++-4.0 BUILD_TYPE=Release
|
||||
- env: COMPILER=clang++-4.0 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang40
|
||||
|
||||
# Clang 5.0
|
||||
- env: COMPILER=clang++-5.0 BUILD_TYPE=Debug
|
||||
addons: &clang40
|
||||
- env: COMPILER=clang++-5.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang50
|
||||
apt:
|
||||
packages:
|
||||
- clang-5.0
|
||||
- g++-5
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-4.0 main'
|
||||
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- env: COMPILER=clang++-5.0 BUILD_TYPE=Release
|
||||
addons: *clang40
|
||||
- env: COMPILER=clang++-5.0 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang50
|
||||
|
||||
- env: COMPILER=clang++-5.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
addons: *clang50
|
||||
|
||||
- env: COMPILER=clang++-5.0 BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
addons: *clang50
|
||||
|
||||
# Clang 6.0
|
||||
- env: COMPILER=clang++-6.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang60
|
||||
apt:
|
||||
packages:
|
||||
- clang-6.0
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-6.0
|
||||
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- env: COMPILER=clang++-6.0 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang60
|
||||
|
||||
# Clang 6.0 c++17
|
||||
- env: COMPILER=clang++-6.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
addons: *clang60
|
||||
|
||||
- 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
|
||||
##########################################################################
|
||||
|
||||
# GCC 5
|
||||
- env: COMPILER=g++-5 BUILD_TYPE=Debug
|
||||
- env: COMPILER=g++-5 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &gcc5
|
||||
apt:
|
||||
packages: g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- env: COMPILER=g++-5 BUILD_TYPE=Release
|
||||
- env: COMPILER=g++-5 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *gcc5
|
||||
|
||||
# GCC 6
|
||||
- env: COMPILER=g++-6 BUILD_TYPE=Debug
|
||||
- env: COMPILER=g++-6 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &gcc6
|
||||
apt:
|
||||
packages: g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- env: COMPILER=g++-6 BUILD_TYPE=Release
|
||||
- env: COMPILER=g++-6 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *gcc6
|
||||
|
||||
# Currently fails due to #525
|
||||
## GCC 7
|
||||
#- env: COMPILER=g++-7 BUILD_TYPE=Debug
|
||||
# addons: &gcc7
|
||||
# apt:
|
||||
# packages: g++-7
|
||||
# sources:
|
||||
# - ubuntu-toolchain-r-test
|
||||
# GCC 7
|
||||
- env: COMPILER=g++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &gcc7
|
||||
apt:
|
||||
packages: g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
#- env: COMPILER=g++-7 BUILD_TYPE=Release
|
||||
# addons: *gcc7
|
||||
- env: COMPILER=g++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *gcc7
|
||||
|
||||
# GCC 7 c++17
|
||||
- env: COMPILER=g++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
addons: *gcc7
|
||||
|
||||
- env: COMPILER=g++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
addons: *gcc7
|
||||
|
||||
install:
|
||||
# Set the ${CXX} variable properly
|
||||
@@ -231,7 +287,7 @@ before_script:
|
||||
# have CMake to generate build files
|
||||
- cd "${TRAVIS_BUILD_DIR}"
|
||||
- mkdir build && cd build
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DGSL_CXX_STANDARD=$GSL_CXX_STANDARD
|
||||
|
||||
script:
|
||||
# build and run tests
|
||||
|
||||
+45
-25
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.1.3)
|
||||
|
||||
project(GSL CXX)
|
||||
|
||||
@@ -14,22 +14,28 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(GSL_STANDALONE_PROJECT ON)
|
||||
endif ()
|
||||
|
||||
set(GSL_CXX_STANDARD "14" CACHE STRING "Use c++ standard")
|
||||
set(GSL_CXX_STD "cxx_std_${GSL_CXX_STANDARD}")
|
||||
|
||||
if (MSVC)
|
||||
set(GSL_CXX_STD_OPT "-std:c++${GSL_CXX_STANDARD}")
|
||||
else()
|
||||
set(GSL_CXX_STD_OPT "-std=c++${GSL_CXX_STANDARD}")
|
||||
endif()
|
||||
|
||||
# when minimum version required is 3.8.0 remove if below
|
||||
# both branches do exactly the same thing
|
||||
if (CMAKE_VERSION VERSION_LESS 3.7.9)
|
||||
if (NOT MSVC)
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
|
||||
if(COMPILER_SUPPORTS_CXX14)
|
||||
target_compile_options(GSL INTERFACE "-std=c++14")
|
||||
else()
|
||||
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
|
||||
endif()
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("${GSL_CXX_STD_OPT}" COMPILER_SUPPORTS_CXX_STANDARD)
|
||||
|
||||
if(COMPILER_SUPPORTS_CXX_STANDARD)
|
||||
target_compile_options(GSL INTERFACE "${GSL_CXX_STD_OPT}")
|
||||
else()
|
||||
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no c++${GSL_CXX_STANDARD} support. Please use a different C++ compiler.")
|
||||
endif()
|
||||
else ()
|
||||
# set the GSL library to be compiled only with c++14
|
||||
target_compile_features(GSL INTERFACE cxx_std_14)
|
||||
target_compile_features(GSL INTERFACE "${GSL_CXX_STD}")
|
||||
# on *nix systems force the use of -std=c++XX instead of -std=gnu++XX (default)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
endif()
|
||||
@@ -39,27 +45,41 @@ target_compile_definitions(GSL INTERFACE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:
|
||||
# remove unnecessary warnings about unchecked iterators
|
||||
_SCL_SECURE_NO_WARNINGS
|
||||
# remove deprecation warnings about std::uncaught_exception() (from catch)
|
||||
_SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING
|
||||
>
|
||||
)
|
||||
|
||||
# add include folders to the library and targets that consume it
|
||||
target_include_directories(GSL INTERFACE
|
||||
$<BUILD_INTERFACE:
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
>
|
||||
)
|
||||
|
||||
if (MSVC_IDE)
|
||||
option(VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE)
|
||||
# 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()
|
||||
set(VS_ADD_NATIVE_VISUALIZERS FALSE CACHE INTERNAL "Native visualizers are Visual Studio extension" FORCE)
|
||||
target_include_directories(GSL SYSTEM INTERFACE
|
||||
$<BUILD_INTERFACE:
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
>
|
||||
)
|
||||
endif()
|
||||
|
||||
# add natvis file to the library so it will automatically be loaded into Visual Studio
|
||||
if(VS_ADD_NATIVE_VISUALIZERS)
|
||||
target_sources(GSL INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis
|
||||
)
|
||||
|
||||
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()
|
||||
set(VS_ADD_NATIVE_VISUALIZERS FALSE CACHE INTERNAL "Native visualizers are Visual Studio extension" FORCE)
|
||||
endif()
|
||||
|
||||
# add natvis file to the library so it will automatically be loaded into Visual Studio
|
||||
if(VS_ADD_NATIVE_VISUALIZERS)
|
||||
target_sources(GSL INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "x64-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [
|
||||
"msvc_x64_x64"
|
||||
],
|
||||
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
|
||||
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DGSL_CXX_STANDARD=17",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"codeAnalysisRuleset": "CppCoreCheckRules.ruleset"
|
||||
}
|
||||
]
|
||||
}
|
||||
+2
-2
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# GSL: Guideline Support Library [](https://travis-ci.org/Microsoft/GSL) [](https://ci.appveyor.com/project/neilmacintosh/GSL)
|
||||
# GSL: Guidelines Support Library [](https://travis-ci.org/Microsoft/GSL) [](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,9 +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
|
||||
* GNU/Linux using Clang/LLVM 3.6
|
||||
* Windows using Intel C++ Compiler 18.0
|
||||
* 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)
|
||||
@@ -45,7 +53,7 @@ contributing any changes that were necessary back to this project to benefit the
|
||||
## Building the tests
|
||||
To build the tests, you will require the following:
|
||||
|
||||
* [CMake](http://cmake.org), version 3.7 or later to be installed and in your PATH.
|
||||
* [CMake](http://cmake.org), version 3.1.3 or later to be installed and in your PATH.
|
||||
|
||||
These steps assume the source code of this repository has been cloned into a directory named `c:\GSL`.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
+96
-15
@@ -11,35 +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"
|
||||
$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
|
||||
|
||||
@@ -31,15 +31,12 @@
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#pragma warning(disable : 4996) // unsafe use of std::copy_n
|
||||
|
||||
// blanket turn off warnings from CppCoreCheck for now
|
||||
// so people aren't annoyed by them when running the tool.
|
||||
// more targeted suppressions will be added in a future update to the GSL
|
||||
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
|
||||
#endif // _MSC_VER
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
|
||||
// Note: this will generate faster code than std::copy using span iterator in older msvc+stl
|
||||
// not necessary for msvc since VS2017 15.8 (_MSC_VER >= 1915)
|
||||
template <class SrcElementType, std::ptrdiff_t SrcExtent, class DestElementType,
|
||||
std::ptrdiff_t DestExtent>
|
||||
void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest)
|
||||
@@ -51,6 +48,7 @@ void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent>
|
||||
"Source range is longer than target range");
|
||||
|
||||
Expects(dest.size() >= src.size());
|
||||
GSL_SUPPRESS(stl.1) // NO-FORMAT: attribute
|
||||
std::copy_n(src.data(), src.size(), dest.data());
|
||||
}
|
||||
|
||||
|
||||
+38
-6
@@ -20,12 +20,34 @@
|
||||
#include <exception>
|
||||
#include <stdexcept> // for logic_error
|
||||
|
||||
//
|
||||
// make suppress attributes parse for some compilers
|
||||
// Hopefully temporary until suppression standardization occurs
|
||||
//
|
||||
#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 // _MSC_VER
|
||||
#endif // __clang__
|
||||
|
||||
//
|
||||
// Temporary until MSVC STL supports no-exceptions mode.
|
||||
// Currently terminate is a no-op in this mode, so we add termination behavior back
|
||||
//
|
||||
#if defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
|
||||
#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
|
||||
|
||||
//
|
||||
@@ -81,11 +103,17 @@ namespace details
|
||||
{
|
||||
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
|
||||
|
||||
typedef void (*terminate_handler)();
|
||||
typedef void (__cdecl *terminate_handler)();
|
||||
|
||||
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute
|
||||
[[noreturn]] inline void __cdecl default_terminate_handler()
|
||||
{
|
||||
__fastfail(RANGE_CHECKS_FAILURE);
|
||||
}
|
||||
|
||||
inline gsl::details::terminate_handler& get_terminate_handler() noexcept
|
||||
{
|
||||
static terminate_handler handler = &abort;
|
||||
static terminate_handler handler = &default_terminate_handler;
|
||||
return handler;
|
||||
}
|
||||
|
||||
@@ -103,7 +131,7 @@ namespace details
|
||||
#if defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
|
||||
|
||||
template <typename Exception>
|
||||
[[noreturn]] void throw_exception(Exception&&)
|
||||
[[noreturn]] void throw_exception(Exception&&) noexcept
|
||||
{
|
||||
gsl::details::terminate();
|
||||
}
|
||||
@@ -113,10 +141,10 @@ namespace details
|
||||
template <typename Exception>
|
||||
[[noreturn]] void throw_exception(Exception&& exception)
|
||||
{
|
||||
throw exception;
|
||||
throw std::forward<Exception>(exception);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // GSL_TERMINATE_ON_CONTRACT_VIOLATION
|
||||
|
||||
} // namespace details
|
||||
} // namespace gsl
|
||||
@@ -137,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
|
||||
|
||||
+43
-12
@@ -17,51 +17,80 @@
|
||||
#ifndef GSL_BYTE_H
|
||||
#define GSL_BYTE_H
|
||||
|
||||
//
|
||||
// make suppress attributes work for some compilers
|
||||
// Hopefully temporary until suppression standardization occurs
|
||||
//
|
||||
#if defined(__clang__)
|
||||
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]]
|
||||
#else
|
||||
#if defined(_MSC_VER)
|
||||
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
|
||||
#else
|
||||
#define GSL_SUPPRESS(x)
|
||||
#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)
|
||||
|
||||
// don't warn about function style casts in byte related operators
|
||||
#pragma warning(disable : 26493)
|
||||
// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool.
|
||||
#pragma warning(disable : 26493) // don't use c-style casts // TODO: MSVC suppression in templates does not always work
|
||||
|
||||
#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
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
// also check if libc++ version is sufficient (> 5.0) or libstc++ actually contains std::byte
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201703L) && \
|
||||
(defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) || \
|
||||
defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000))
|
||||
|
||||
#define GSL_USE_STD_BYTE 1
|
||||
#include <cstddef>
|
||||
|
||||
#else // defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
#else // defined(__cplusplus) && (__cplusplus >= 201703L) &&
|
||||
// (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) ||
|
||||
// defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000))
|
||||
|
||||
#define GSL_USE_STD_BYTE 0
|
||||
|
||||
#endif //defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
#endif //defined(__cplusplus) && (__cplusplus >= 201703L) &&
|
||||
// (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) ||
|
||||
// defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000))
|
||||
#endif // GSL_USE_STD_BYTE
|
||||
|
||||
#endif // _MSC_VER
|
||||
#endif // _MSC_VER
|
||||
|
||||
// Use __may_alias__ attribute on gcc and clang
|
||||
#if defined __clang__ || (defined(__GNUC__) && __GNUC__ > 5)
|
||||
#define byte_may_alias __attribute__((__may_alias__))
|
||||
#else // defined __clang__ || defined __GNUC__
|
||||
#define byte_may_alias
|
||||
#endif // defined __clang__ || defined __GNUC__
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
#if GSL_USE_STD_BYTE
|
||||
|
||||
|
||||
using std::byte;
|
||||
using std::to_integer;
|
||||
|
||||
@@ -69,7 +98,7 @@ using std::to_integer;
|
||||
|
||||
// This is a simple definition for now that allows
|
||||
// use of byte within span<> to be standards-compliant
|
||||
enum class byte : unsigned char
|
||||
enum class byte_may_alias byte : unsigned char
|
||||
{
|
||||
};
|
||||
|
||||
@@ -146,6 +175,8 @@ constexpr byte to_byte_impl(T t) noexcept
|
||||
return static_cast<byte>(t);
|
||||
}
|
||||
template <>
|
||||
// NOTE: need suppression since c++14 does not allow "return {t}"
|
||||
// GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: suppression does not work
|
||||
constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept
|
||||
{
|
||||
return byte(t);
|
||||
|
||||
+30
-15
@@ -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
|
||||
@@ -34,8 +34,14 @@
|
||||
#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 (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,14 +59,13 @@ 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;
|
||||
final_action& operator=(final_action&&) = delete;
|
||||
|
||||
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // terminate if throws
|
||||
~final_action() noexcept
|
||||
{
|
||||
if (invoke_) f_();
|
||||
@@ -68,12 +73,11 @@ public:
|
||||
|
||||
private:
|
||||
F f_;
|
||||
bool invoke_ {true};
|
||||
bool invoke_{true};
|
||||
};
|
||||
|
||||
// finally() - convenience function to generate a final_action
|
||||
template <class F>
|
||||
|
||||
final_action<F> finally(const F& f) noexcept
|
||||
{
|
||||
return final_action<F>(f);
|
||||
@@ -87,6 +91,7 @@ final_action<F> finally(F&& f) noexcept
|
||||
|
||||
// narrow_cast(): a searchable way to do narrowing casts of values
|
||||
template <class T, class U>
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
constexpr T narrow_cast(U&& u) noexcept
|
||||
{
|
||||
return static_cast<T>(std::forward<U>(u));
|
||||
@@ -103,11 +108,16 @@ namespace details
|
||||
: public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
|
||||
template <class T, class U>
|
||||
T narrow(U 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);
|
||||
if (static_cast<U>(t) != u) gsl::details::throw_exception(narrowing_error());
|
||||
@@ -120,21 +130,26 @@ T narrow(U u)
|
||||
// at() - Bounds-checked way of accessing builtin arrays, std::array, std::vector
|
||||
//
|
||||
template <class T, std::size_t N>
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
constexpr T& at(T (&arr)[N], const index i)
|
||||
{
|
||||
Expects(i >= 0 && i < narrow_cast<index>(N));
|
||||
return arr[static_cast<std::size_t>(i)];
|
||||
return arr[narrow_cast<std::size_t>(i)];
|
||||
}
|
||||
|
||||
template <class Cont>
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()])
|
||||
{
|
||||
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
|
||||
using size_type = decltype(cont.size());
|
||||
return cont[static_cast<size_type>(i)];
|
||||
return cont[narrow_cast<size_type>(i)];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
constexpr T at(const std::initializer_list<T> cont, const index i)
|
||||
{
|
||||
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
|
||||
@@ -143,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")
|
||||
|
||||
+497
-452
File diff suppressed because it is too large
Load Diff
+119
-4
@@ -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*/
|
||||
|
||||
@@ -77,6 +77,12 @@ public:
|
||||
Expects(ptr_ != nullptr);
|
||||
}
|
||||
|
||||
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
|
||||
constexpr not_null(T u) : ptr_(u)
|
||||
{
|
||||
Expects(ptr_ != nullptr);
|
||||
}
|
||||
|
||||
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||
constexpr not_null(const not_null<U>& other) : not_null(other.get())
|
||||
{
|
||||
@@ -94,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;
|
||||
@@ -113,6 +119,11 @@ private:
|
||||
T ptr_;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
auto make_not_null(T&& t) {
|
||||
return not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::ostream& operator<<(std::ostream& os, const not_null<T>& val)
|
||||
{
|
||||
@@ -178,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
|
||||
|
||||
+180
-106
@@ -29,26 +29,26 @@
|
||||
#include <stdexcept>
|
||||
#include <type_traits> // for enable_if_t, declval, is_convertible, inte...
|
||||
#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
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#pragma warning(disable : 4702) // unreachable code
|
||||
|
||||
// blanket turn off warnings from CppCoreCheck for now
|
||||
// so people aren't annoyed by them when running the tool.
|
||||
// more targeted suppressions will be added in a future update to the GSL
|
||||
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
|
||||
// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool.
|
||||
#pragma warning(disable : 26495) // uninitalized member when constructor calls constructor
|
||||
#pragma warning(disable : 26446) // parser bug does not allow attributes on some templates
|
||||
|
||||
#if _MSC_VER < 1910
|
||||
#pragma push_macro("constexpr")
|
||||
#define constexpr /*constexpr*/
|
||||
#define GSL_USE_STATIC_CONSTEXPR_WORKAROUND
|
||||
|
||||
#endif // _MSC_VER < 1910
|
||||
#else // _MSC_VER
|
||||
#endif // _MSC_VER < 1910
|
||||
#endif // _MSC_VER
|
||||
|
||||
// See if we have enough C++17 power to use a static constexpr data member
|
||||
// without needing an out-of-line definition
|
||||
@@ -56,7 +56,15 @@
|
||||
#define GSL_USE_STATIC_CONSTEXPR_WORKAROUND
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus >= 201703L))
|
||||
|
||||
#endif // _MSC_VER
|
||||
// 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 defined(__GNUC__) && __GNUC__ > 6
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
@@ -119,7 +127,6 @@ namespace details
|
||||
using element_type_ = typename Span::element_type;
|
||||
|
||||
public:
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Tell Microsoft standard library that span_iterators are checked.
|
||||
using _Unchecked_type = typename Span::pointer;
|
||||
@@ -134,17 +141,17 @@ 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)
|
||||
{}
|
||||
|
||||
friend span_iterator<Span, true>;
|
||||
template<bool B, std::enable_if_t<!B && IsConst>* = nullptr>
|
||||
template <bool B, std::enable_if_t<!B && IsConst>* = nullptr>
|
||||
constexpr span_iterator(const span_iterator<Span, B>& other) noexcept
|
||||
: span_iterator(other.span_, other.index_)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
constexpr reference operator*() const
|
||||
{
|
||||
Expects(index_ != span_->size());
|
||||
@@ -191,6 +198,11 @@ namespace details
|
||||
return ret += n;
|
||||
}
|
||||
|
||||
friend constexpr span_iterator operator+(difference_type n, span_iterator const& rhs)
|
||||
{
|
||||
return rhs + n;
|
||||
}
|
||||
|
||||
constexpr span_iterator& operator+=(difference_type n)
|
||||
{
|
||||
Expects((index_ + n) >= 0 && (index_ + n) <= span_->size());
|
||||
@@ -212,68 +224,82 @@ namespace details
|
||||
return index_ - rhs.index_;
|
||||
}
|
||||
|
||||
constexpr reference operator[](difference_type n) const
|
||||
{
|
||||
return *(*this + n);
|
||||
}
|
||||
constexpr reference operator[](difference_type n) const { return *(*this + n); }
|
||||
|
||||
constexpr friend bool operator==(span_iterator lhs,
|
||||
span_iterator rhs) noexcept
|
||||
constexpr friend bool operator==(span_iterator lhs, span_iterator rhs) noexcept
|
||||
{
|
||||
return lhs.span_ == rhs.span_ && lhs.index_ == rhs.index_;
|
||||
}
|
||||
|
||||
constexpr friend bool operator!=(span_iterator lhs,
|
||||
span_iterator rhs) noexcept
|
||||
constexpr friend bool operator!=(span_iterator lhs, span_iterator rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
constexpr friend bool operator<(span_iterator lhs,
|
||||
span_iterator rhs) noexcept
|
||||
constexpr friend bool operator<(span_iterator lhs, span_iterator rhs) noexcept
|
||||
{
|
||||
return lhs.index_ < rhs.index_;
|
||||
}
|
||||
|
||||
constexpr friend bool operator<=(span_iterator lhs,
|
||||
span_iterator rhs) noexcept
|
||||
constexpr friend bool operator<=(span_iterator lhs, span_iterator rhs) noexcept
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
constexpr friend bool operator>(span_iterator lhs,
|
||||
span_iterator rhs) noexcept
|
||||
constexpr friend bool operator>(span_iterator lhs, span_iterator rhs) noexcept
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
constexpr friend bool operator>=(span_iterator lhs,
|
||||
span_iterator rhs) noexcept
|
||||
constexpr friend bool operator>=(span_iterator lhs, span_iterator rhs) noexcept
|
||||
{
|
||||
return !(rhs > lhs);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// MSVC++ iterator debugging support; allows STL algorithms in 15.8+
|
||||
// to unwrap span_iterator to a pointer type after a range check in STL
|
||||
// algorithm calls
|
||||
friend constexpr void _Verify_range(span_iterator lhs, span_iterator rhs) noexcept
|
||||
{ // test that [lhs, rhs) forms a valid range inside an STL algorithm
|
||||
Expects(lhs.span_ == rhs.span_ // range spans have to match
|
||||
&& lhs.index_ <= rhs.index_); // range must not be transposed
|
||||
}
|
||||
|
||||
constexpr void _Verify_offset(const difference_type n) const noexcept
|
||||
{ // test that the iterator *this + n is a valid range in an STL
|
||||
// algorithm call
|
||||
Expects((index_ + n) >= 0 && (index_ + n) <= span_->size());
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
constexpr pointer _Unwrapped() const noexcept
|
||||
{ // after seeking *this to a high water mark, or using one of the
|
||||
// _Verify_xxx functions above, unwrap this span_iterator to a raw
|
||||
// pointer
|
||||
return span_->data() + index_;
|
||||
}
|
||||
|
||||
// Tell the STL that span_iterator should not be unwrapped if it can't
|
||||
// validate in advance, even in release / optimized builds:
|
||||
#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
|
||||
static constexpr const bool _Unwrap_when_unverified = false;
|
||||
#else
|
||||
static constexpr bool _Unwrap_when_unverified = false;
|
||||
#endif
|
||||
GSL_SUPPRESS(con.3) // NO-FORMAT: attribute // TODO: false positive
|
||||
constexpr void _Seek_to(const pointer p) noexcept
|
||||
{ // adjust the position of *this to previously verified location p
|
||||
// after _Unwrapped
|
||||
index_ = p - span_->data();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
const Span* span_ = nullptr;
|
||||
std::ptrdiff_t index_ = 0;
|
||||
};
|
||||
|
||||
template <class Span, bool IsConst>
|
||||
constexpr span_iterator<Span, IsConst>
|
||||
operator+(typename span_iterator<Span, IsConst>::difference_type n,
|
||||
span_iterator<Span, IsConst> rhs)
|
||||
{
|
||||
return rhs + n;
|
||||
}
|
||||
|
||||
template <class Span, bool IsConst>
|
||||
constexpr span_iterator<Span, IsConst>
|
||||
operator-(typename span_iterator<Span, IsConst>::difference_type n,
|
||||
span_iterator<Span, IsConst> rhs)
|
||||
{
|
||||
return rhs - n;
|
||||
}
|
||||
|
||||
template <std::ptrdiff_t Ext>
|
||||
class extent_type
|
||||
{
|
||||
@@ -305,8 +331,7 @@ namespace details
|
||||
|
||||
template <index_type Other>
|
||||
explicit constexpr extent_type(extent_type<Other> ext) : size_(ext.size())
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
explicit constexpr extent_type(index_type size) : size_(size) { Expects(size >= 0); }
|
||||
|
||||
@@ -319,7 +344,9 @@ namespace details
|
||||
template <class ElementType, std::ptrdiff_t Extent, std::ptrdiff_t Offset, std::ptrdiff_t Count>
|
||||
struct calculate_subspan_type
|
||||
{
|
||||
using type = span<ElementType, Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : Extent)>;
|
||||
using type = span<ElementType, Count != dynamic_extent
|
||||
? Count
|
||||
: (Extent != dynamic_extent ? Extent - Offset : Extent)>;
|
||||
};
|
||||
} // namespace details
|
||||
|
||||
@@ -343,9 +370,9 @@ public:
|
||||
using size_type = index_type;
|
||||
|
||||
#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
|
||||
static constexpr const index_type extent { Extent };
|
||||
static constexpr const index_type extent{Extent};
|
||||
#else
|
||||
static constexpr index_type extent { Extent };
|
||||
static constexpr index_type extent{Extent};
|
||||
#endif
|
||||
|
||||
// [span.cons], span constructors, copy, assignment, and destructor
|
||||
@@ -354,31 +381,38 @@ public:
|
||||
// since "std::enable_if_t<Extent <= 0>" is ill-formed when Extent is greater than 0.
|
||||
class = std::enable_if_t<(Dependent || Extent <= 0)>>
|
||||
constexpr span() noexcept : storage_(nullptr, details::extent_type<0>())
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
constexpr span(pointer ptr, index_type count) : storage_(ptr, count) {}
|
||||
|
||||
constexpr span(pointer firstElem, pointer lastElem)
|
||||
: storage_(firstElem, std::distance(firstElem, lastElem))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
template <std::size_t N>
|
||||
constexpr span(element_type (&arr)[N]) noexcept
|
||||
: storage_(KnownNotNull{&arr[0]}, details::extent_type<N>())
|
||||
: storage_(KnownNotNull{std::addressof(arr[0])}, 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, class ArrayElementType = std::remove_const_t<element_type>>
|
||||
constexpr span(std::array<ArrayElementType, N>& arr) noexcept
|
||||
: storage_(&arr[0], details::extent_type<N>())
|
||||
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>
|
||||
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[0], 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>())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -391,8 +425,7 @@ public:
|
||||
std::is_convertible<typename Container::pointer,
|
||||
decltype(std::declval<Container>().data())>::value>>
|
||||
constexpr span(Container& cont) : span(cont.data(), narrow<index_type>(cont.size()))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
template <class Container,
|
||||
class = std::enable_if_t<
|
||||
@@ -401,8 +434,7 @@ public:
|
||||
std::is_convertible<typename Container::pointer,
|
||||
decltype(std::declval<Container>().data())>::value>>
|
||||
constexpr span(const Container& cont) : span(cont.data(), narrow<index_type>(cont.size()))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
constexpr span(const span& other) noexcept = default;
|
||||
|
||||
@@ -413,12 +445,11 @@ public:
|
||||
details::is_allowed_element_type_conversion<OtherElementType, element_type>::value>>
|
||||
constexpr span(const span<OtherElementType, OtherExtent>& other)
|
||||
: storage_(other.data(), details::extent_type<OtherExtent>(other.size()))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
~span() noexcept = default;
|
||||
constexpr span& operator=(const span& other) noexcept = default;
|
||||
|
||||
|
||||
// [span.sub], span subviews
|
||||
template <std::ptrdiff_t Count>
|
||||
constexpr span<element_type, Count> first() const
|
||||
@@ -428,6 +459,7 @@ public:
|
||||
}
|
||||
|
||||
template <std::ptrdiff_t Count>
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
constexpr span<element_type, Count> last() const
|
||||
{
|
||||
Expects(Count >= 0 && size() - Count >= 0);
|
||||
@@ -435,7 +467,9 @@ public:
|
||||
}
|
||||
|
||||
template <std::ptrdiff_t Offset, std::ptrdiff_t Count = dynamic_extent>
|
||||
constexpr auto subspan() const -> typename details::calculate_subspan_type<ElementType, Extent, Offset, Count>::type
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
constexpr auto subspan() const ->
|
||||
typename details::calculate_subspan_type<ElementType, Extent, Offset, Count>::type
|
||||
{
|
||||
Expects((Offset >= 0 && size() - Offset >= 0) &&
|
||||
(Count == dynamic_extent || (Count >= 0 && Offset + Count <= size())));
|
||||
@@ -460,7 +494,6 @@ public:
|
||||
return make_subspan(offset, count, subspan_selector<Extent>{});
|
||||
}
|
||||
|
||||
|
||||
// [span.obs], span observers
|
||||
constexpr index_type size() const noexcept { return storage_.size(); }
|
||||
constexpr index_type size_bytes() const noexcept
|
||||
@@ -470,9 +503,10 @@ public:
|
||||
constexpr bool empty() const noexcept { return size() == 0; }
|
||||
|
||||
// [span.elem], span element access
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
constexpr reference operator[](index_type idx) const
|
||||
{
|
||||
Expects(idx >= 0 && idx < storage_.size());
|
||||
Expects(CheckRange(idx, storage_.size()));
|
||||
return data()[idx];
|
||||
}
|
||||
|
||||
@@ -490,13 +524,54 @@ public:
|
||||
constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; }
|
||||
constexpr reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; }
|
||||
|
||||
constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator{cend()}; }
|
||||
constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator{cbegin()}; }
|
||||
constexpr const_reverse_iterator crbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator{cend()};
|
||||
}
|
||||
constexpr const_reverse_iterator crend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator{cbegin()};
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Tell MSVC how to unwrap spans in range-based-for
|
||||
constexpr pointer _Unchecked_begin() const noexcept { return data(); }
|
||||
constexpr pointer _Unchecked_end() const noexcept
|
||||
{
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
return data() + size();
|
||||
}
|
||||
#endif // _MSC_VER
|
||||
|
||||
private:
|
||||
static constexpr bool CheckRange(index_type idx, index_type size) noexcept
|
||||
{
|
||||
// Optimization:
|
||||
//
|
||||
// idx >= 0 && idx < size
|
||||
// =>
|
||||
// static_cast<size_t>(idx) < static_cast<size_t>(size)
|
||||
//
|
||||
// because size >=0 by span construction, and negative idx will
|
||||
// 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
return idx >= 0 && idx < size;
|
||||
}
|
||||
}
|
||||
|
||||
// Needed to remove unnecessary null check in subspans
|
||||
struct KnownNotNull
|
||||
struct KnownNotNull
|
||||
{
|
||||
pointer p;
|
||||
};
|
||||
@@ -508,20 +583,20 @@ private:
|
||||
class storage_type : public ExtentType
|
||||
{
|
||||
public:
|
||||
// KnownNotNull parameter is needed to remove unnecessary null check
|
||||
// KnownNotNull parameter is needed to remove unnecessary null check
|
||||
// in subspans and constructors from arrays
|
||||
template <class OtherExtentType>
|
||||
constexpr storage_type(KnownNotNull data, OtherExtentType ext) : ExtentType(ext), data_(data.p)
|
||||
constexpr storage_type(KnownNotNull data, OtherExtentType ext)
|
||||
: ExtentType(ext), data_(data.p)
|
||||
{
|
||||
Expects(ExtentType::size() >= 0);
|
||||
Expects(ExtentType::size() >= 0);
|
||||
}
|
||||
|
||||
|
||||
template <class OtherExtentType>
|
||||
constexpr storage_type(pointer data, OtherExtentType ext) : ExtentType(ext), data_(data)
|
||||
{
|
||||
Expects(ExtentType::size() >= 0);
|
||||
Expects(data || ExtentType::size() == 0);
|
||||
Expects(ExtentType::size() >= 0);
|
||||
Expects(data || ExtentType::size() == 0);
|
||||
}
|
||||
|
||||
constexpr pointer data() const noexcept { return data_; }
|
||||
@@ -537,29 +612,28 @@ private:
|
||||
constexpr span(KnownNotNull ptr, index_type count) : storage_(ptr, count) {}
|
||||
|
||||
template <std::ptrdiff_t CallerExtent>
|
||||
class subspan_selector {};
|
||||
class subspan_selector
|
||||
{
|
||||
};
|
||||
|
||||
template <std::ptrdiff_t CallerExtent>
|
||||
span<element_type, dynamic_extent> make_subspan(index_type offset,
|
||||
index_type count,
|
||||
span<element_type, dynamic_extent> make_subspan(index_type offset, index_type count,
|
||||
subspan_selector<CallerExtent>) const
|
||||
{
|
||||
span<element_type, dynamic_extent> tmp(*this);
|
||||
const span<element_type, dynamic_extent> tmp(*this);
|
||||
return tmp.subspan(offset, count);
|
||||
}
|
||||
|
||||
span<element_type, dynamic_extent> make_subspan(index_type offset,
|
||||
index_type count,
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
span<element_type, dynamic_extent> make_subspan(index_type offset, index_type count,
|
||||
subspan_selector<dynamic_extent>) const
|
||||
{
|
||||
Expects(offset >= 0 && size() - offset >= 0);
|
||||
if (count == dynamic_extent)
|
||||
{
|
||||
return { KnownNotNull{ data() + offset }, size() - offset };
|
||||
}
|
||||
|
||||
if (count == dynamic_extent) { return {KnownNotNull{data() + offset}, size() - offset}; }
|
||||
|
||||
Expects(count >= 0 && size() - offset >= count);
|
||||
return { KnownNotNull{ data() + offset }, count };
|
||||
return {KnownNotNull{data() + offset}, count};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -568,46 +642,39 @@ template <class ElementType, std::ptrdiff_t Extent>
|
||||
constexpr const typename span<ElementType, Extent>::index_type span<ElementType, Extent>::extent;
|
||||
#endif
|
||||
|
||||
|
||||
// [span.comparison], span comparison operators
|
||||
template <class ElementType, std::ptrdiff_t FirstExtent, std::ptrdiff_t SecondExtent>
|
||||
constexpr bool operator==(span<ElementType, FirstExtent> l,
|
||||
span<ElementType, SecondExtent> r)
|
||||
constexpr bool operator==(span<ElementType, FirstExtent> l, span<ElementType, SecondExtent> r)
|
||||
{
|
||||
return std::equal(l.begin(), l.end(), r.begin(), r.end());
|
||||
}
|
||||
|
||||
template <class ElementType, std::ptrdiff_t Extent>
|
||||
constexpr bool operator!=(span<ElementType, Extent> l,
|
||||
span<ElementType, Extent> r)
|
||||
constexpr bool operator!=(span<ElementType, Extent> l, span<ElementType, Extent> r)
|
||||
{
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
template <class ElementType, std::ptrdiff_t Extent>
|
||||
constexpr bool operator<(span<ElementType, Extent> l,
|
||||
span<ElementType, Extent> r)
|
||||
constexpr bool operator<(span<ElementType, Extent> l, span<ElementType, Extent> r)
|
||||
{
|
||||
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
|
||||
}
|
||||
|
||||
template <class ElementType, std::ptrdiff_t Extent>
|
||||
constexpr bool operator<=(span<ElementType, Extent> l,
|
||||
span<ElementType, Extent> r)
|
||||
constexpr bool operator<=(span<ElementType, Extent> l, span<ElementType, Extent> r)
|
||||
{
|
||||
return !(l > r);
|
||||
}
|
||||
|
||||
template <class ElementType, std::ptrdiff_t Extent>
|
||||
constexpr bool operator>(span<ElementType, Extent> l,
|
||||
span<ElementType, Extent> r)
|
||||
constexpr bool operator>(span<ElementType, Extent> l, span<ElementType, Extent> r)
|
||||
{
|
||||
return r < l;
|
||||
}
|
||||
|
||||
template <class ElementType, std::ptrdiff_t Extent>
|
||||
constexpr bool operator>=(span<ElementType, Extent> l,
|
||||
span<ElementType, Extent> r)
|
||||
constexpr bool operator>=(span<ElementType, Extent> l, span<ElementType, Extent> r)
|
||||
{
|
||||
return !(l < r);
|
||||
}
|
||||
@@ -633,13 +700,14 @@ namespace details
|
||||
: std::integral_constant<std::ptrdiff_t, dynamic_extent>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
// [span.objectrep], views of object representation
|
||||
template <class ElementType, std::ptrdiff_t Extent>
|
||||
span<const byte, details::calculate_byte_size<ElementType, Extent>::value>
|
||||
as_bytes(span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
@@ -648,6 +716,7 @@ template <class ElementType, std::ptrdiff_t Extent,
|
||||
span<byte, details::calculate_byte_size<ElementType, Extent>::value>
|
||||
as_writeable_bytes(span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
@@ -655,7 +724,8 @@ as_writeable_bytes(span<ElementType, Extent> s) noexcept
|
||||
// make_span() - Utility functions for creating spans
|
||||
//
|
||||
template <class ElementType>
|
||||
constexpr span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::index_type count)
|
||||
constexpr span<ElementType> make_span(ElementType* ptr,
|
||||
typename span<ElementType>::index_type count)
|
||||
{
|
||||
return span<ElementType>(ptr, count);
|
||||
}
|
||||
@@ -706,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")
|
||||
@@ -716,4 +786,8 @@ constexpr ElementType& at(span<ElementType, Extent> s, index i)
|
||||
#pragma warning(pop)
|
||||
#endif // _MSC_VER
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ > 6
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __GNUC__ > 6
|
||||
|
||||
#endif // GSL_SPAN_H
|
||||
|
||||
+95
-89
@@ -29,13 +29,12 @@
|
||||
#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)
|
||||
|
||||
// blanket turn off warnings from CppCoreCheck for now
|
||||
// so people aren't annoyed by them when running the tool.
|
||||
// more targeted suppressions will be added in a future update to the GSL
|
||||
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
|
||||
// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool.
|
||||
#pragma warning(disable : 26446) // TODO: bug in parser - attributes and templates
|
||||
#pragma warning(disable : 26481) // TODO: suppress does not work inside templates sometimes
|
||||
|
||||
#if _MSC_VER < 1910
|
||||
#pragma push_macro("constexpr")
|
||||
@@ -44,13 +43,6 @@
|
||||
#endif // _MSC_VER < 1910
|
||||
#endif // _MSC_VER
|
||||
|
||||
// In order to test the library, we need it to throw exceptions that we can catch
|
||||
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
|
||||
#define GSL_NOEXCEPT /*noexcept*/
|
||||
#else
|
||||
#define GSL_NOEXCEPT noexcept
|
||||
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
//
|
||||
@@ -105,7 +97,7 @@ namespace details
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
//
|
||||
// ensure_sentinel()
|
||||
@@ -118,7 +110,13 @@ namespace details
|
||||
template <typename T, const T Sentinel>
|
||||
span<T, dynamic_extent> ensure_sentinel(T* seq, std::ptrdiff_t max = PTRDIFF_MAX)
|
||||
{
|
||||
Ensures(seq != nullptr);
|
||||
|
||||
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute // TODO: false positive // TODO: suppress does not work
|
||||
auto cur = seq;
|
||||
Ensures(cur != nullptr); // workaround for removing the warning
|
||||
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute // TODO: suppress does not work
|
||||
while ((cur - seq) < max && *cur != Sentinel) ++cur;
|
||||
Ensures(*cur == Sentinel);
|
||||
return {seq, cur - seq};
|
||||
@@ -138,21 +136,20 @@ span<CharT, dynamic_extent> ensure_z(CharT* const& sz, std::ptrdiff_t max = PTRD
|
||||
template <typename CharT, std::size_t N>
|
||||
span<CharT, dynamic_extent> ensure_z(CharT (&sz)[N])
|
||||
{
|
||||
return ensure_z(&sz[0], static_cast<std::ptrdiff_t>(N));
|
||||
return ensure_z(&sz[0], narrow_cast<std::ptrdiff_t>(N));
|
||||
}
|
||||
|
||||
template <class Cont>
|
||||
span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_extent>
|
||||
ensure_z(Cont& cont)
|
||||
{
|
||||
return ensure_z(cont.data(), static_cast<std::ptrdiff_t>(cont.size()));
|
||||
return ensure_z(cont.data(), narrow_cast<std::ptrdiff_t>(cont.size()));
|
||||
}
|
||||
|
||||
template <typename CharT, std::ptrdiff_t>
|
||||
class basic_string_span;
|
||||
|
||||
namespace details
|
||||
{
|
||||
namespace details {
|
||||
template <typename T>
|
||||
struct is_basic_string_span_oracle : std::false_type
|
||||
{
|
||||
@@ -167,7 +164,7 @@ namespace details
|
||||
struct is_basic_string_span : is_basic_string_span_oracle<std::remove_cv_t<T>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
//
|
||||
// string_span and relatives
|
||||
@@ -177,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>>;
|
||||
@@ -188,14 +186,16 @@ 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() GSL_NOEXCEPT = default;
|
||||
constexpr basic_string_span() noexcept = default;
|
||||
|
||||
// copy
|
||||
constexpr basic_string_span(const basic_string_span& other) GSL_NOEXCEPT = default;
|
||||
constexpr basic_string_span(const basic_string_span& other) noexcept = default;
|
||||
|
||||
// assign
|
||||
constexpr basic_string_span& operator=(const basic_string_span& other) GSL_NOEXCEPT = default;
|
||||
constexpr basic_string_span& operator=(const basic_string_span& other) noexcept = default;
|
||||
|
||||
constexpr basic_string_span(pointer ptr, index_type length) : span_(ptr, length) {}
|
||||
constexpr basic_string_span(pointer firstElem, pointer lastElem) : span_(firstElem, lastElem) {}
|
||||
@@ -204,32 +204,27 @@ public:
|
||||
// All other containers allow 0s within the length, so we do not remove them
|
||||
template <std::size_t N>
|
||||
constexpr basic_string_span(element_type (&arr)[N]) : span_(remove_z(arr))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
|
||||
constexpr basic_string_span(std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT : span_(arr)
|
||||
{
|
||||
}
|
||||
constexpr basic_string_span(std::array<ArrayElementType, N>& arr) noexcept : span_(arr)
|
||||
{}
|
||||
|
||||
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
|
||||
constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT
|
||||
: span_(arr)
|
||||
{
|
||||
}
|
||||
constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) noexcept : span_(arr)
|
||||
{}
|
||||
|
||||
// Container signature should work for basic_string after C++17 version exists
|
||||
template <class Traits, class Allocator>
|
||||
// GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
|
||||
constexpr basic_string_span(std::basic_string<element_type, Traits, Allocator>& str)
|
||||
: span_(&str[0], narrow_cast<std::ptrdiff_t>(str.length()))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
template <class Traits, class Allocator>
|
||||
constexpr basic_string_span(const std::basic_string<element_type, Traits, Allocator>& str)
|
||||
: span_(&str[0], str.length())
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
// from containers. Containers must have a pointer type and data() function signatures
|
||||
template <class Container,
|
||||
@@ -239,8 +234,7 @@ public:
|
||||
std::is_convertible<typename Container::pointer,
|
||||
decltype(std::declval<Container>().data())>::value>>
|
||||
constexpr basic_string_span(Container& cont) : span_(cont)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
template <class Container,
|
||||
class = std::enable_if_t<
|
||||
@@ -249,8 +243,7 @@ public:
|
||||
std::is_convertible<typename Container::pointer,
|
||||
decltype(std::declval<Container>().data())>::value>>
|
||||
constexpr basic_string_span(const Container& cont) : span_(cont)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
// from string_span
|
||||
template <
|
||||
@@ -259,8 +252,7 @@ public:
|
||||
typename basic_string_span<OtherValueType, OtherExtent>::impl_type, impl_type>::value>>
|
||||
constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other)
|
||||
: span_(other.data(), other.length())
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
template <index_type Count>
|
||||
constexpr basic_string_span<element_type, Count> first() const
|
||||
@@ -301,23 +293,23 @@ public:
|
||||
|
||||
constexpr pointer data() const { return span_.data(); }
|
||||
|
||||
constexpr index_type length() const GSL_NOEXCEPT { return span_.size(); }
|
||||
constexpr index_type size() const GSL_NOEXCEPT { return span_.size(); }
|
||||
constexpr index_type size_bytes() const GSL_NOEXCEPT { return span_.size_bytes(); }
|
||||
constexpr index_type length_bytes() const GSL_NOEXCEPT { return span_.length_bytes(); }
|
||||
constexpr bool empty() const GSL_NOEXCEPT { return size() == 0; }
|
||||
constexpr index_type length() const noexcept { return span_.size(); }
|
||||
constexpr index_type size() const noexcept { return span_.size(); }
|
||||
constexpr index_type size_bytes() const noexcept { return span_.size_bytes(); }
|
||||
constexpr index_type length_bytes() const noexcept { return span_.length_bytes(); }
|
||||
constexpr bool empty() const noexcept { return size() == 0; }
|
||||
|
||||
constexpr iterator begin() const GSL_NOEXCEPT { return span_.begin(); }
|
||||
constexpr iterator end() const GSL_NOEXCEPT { return span_.end(); }
|
||||
constexpr iterator begin() const noexcept { return span_.begin(); }
|
||||
constexpr iterator end() const noexcept { return span_.end(); }
|
||||
|
||||
constexpr const_iterator cbegin() const GSL_NOEXCEPT { return span_.cbegin(); }
|
||||
constexpr const_iterator cend() const GSL_NOEXCEPT { return span_.cend(); }
|
||||
constexpr const_iterator cbegin() const noexcept { return span_.cbegin(); }
|
||||
constexpr const_iterator cend() const noexcept { return span_.cend(); }
|
||||
|
||||
constexpr reverse_iterator rbegin() const GSL_NOEXCEPT { return span_.rbegin(); }
|
||||
constexpr reverse_iterator rend() const GSL_NOEXCEPT { return span_.rend(); }
|
||||
constexpr reverse_iterator rbegin() const noexcept { return span_.rbegin(); }
|
||||
constexpr reverse_iterator rend() const noexcept { return span_.rend(); }
|
||||
|
||||
constexpr const_reverse_iterator crbegin() const GSL_NOEXCEPT { return span_.crbegin(); }
|
||||
constexpr const_reverse_iterator crend() const GSL_NOEXCEPT { return span_.crend(); }
|
||||
constexpr const_reverse_iterator crbegin() const noexcept { return span_.crbegin(); }
|
||||
constexpr const_reverse_iterator crend() const noexcept { return span_.crend(); }
|
||||
|
||||
private:
|
||||
static impl_type remove_z(pointer const& sz, std::ptrdiff_t max)
|
||||
@@ -366,21 +358,37 @@ template <typename CharT, std::ptrdiff_t Extent>
|
||||
std::basic_string<typename std::remove_const<CharT>::type>
|
||||
to_string(basic_string_span<CharT, Extent> view)
|
||||
{
|
||||
return {view.data(), static_cast<std::size_t>(view.length())};
|
||||
return {view.data(), narrow_cast<std::size_t>(view.length())};
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits = typename std::char_traits<CharT>,
|
||||
typename Allocator = std::allocator<CharT>, typename gCharT, std::ptrdiff_t Extent>
|
||||
std::basic_string<CharT, Traits, Allocator> to_basic_string(basic_string_span<gCharT, Extent> view)
|
||||
{
|
||||
return {view.data(), static_cast<std::size_t>(view.length())};
|
||||
return {view.data(), narrow_cast<std::size_t>(view.length())};
|
||||
}
|
||||
|
||||
template <class ElementType, std::ptrdiff_t Extent>
|
||||
basic_string_span<const byte, details::calculate_byte_size<ElementType, Extent>::value>
|
||||
as_bytes(basic_string_span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
template <class ElementType, std::ptrdiff_t Extent,
|
||||
class = std::enable_if_t<!std::is_const<ElementType>::value>>
|
||||
basic_string_span<byte, details::calculate_byte_size<ElementType, Extent>::value>
|
||||
as_writeable_bytes(basic_string_span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
// zero-terminated string span, used to convert
|
||||
// zero-terminated spans to legacy strings
|
||||
template <typename CharT, std::ptrdiff_t Extent = dynamic_extent>
|
||||
class basic_zstring_span
|
||||
{
|
||||
class basic_zstring_span {
|
||||
public:
|
||||
using value_type = CharT;
|
||||
using const_value_type = std::add_const_t<CharT>;
|
||||
@@ -394,7 +402,7 @@ public:
|
||||
using impl_type = span<value_type, Extent>;
|
||||
using string_span_type = basic_string_span<value_type, Extent>;
|
||||
|
||||
constexpr basic_zstring_span(impl_type s) GSL_NOEXCEPT : span_(s)
|
||||
constexpr basic_zstring_span(impl_type s) : span_(s)
|
||||
{
|
||||
// expects a zero-terminated span
|
||||
Expects(s[s.size() - 1] == '\0');
|
||||
@@ -412,16 +420,16 @@ public:
|
||||
// move assign
|
||||
constexpr basic_zstring_span& operator=(basic_zstring_span&& other) = default;
|
||||
|
||||
constexpr bool empty() const GSL_NOEXCEPT { return span_.size() == 0; }
|
||||
constexpr bool empty() const noexcept { return span_.size() == 0; }
|
||||
|
||||
constexpr string_span_type as_string_span() const GSL_NOEXCEPT
|
||||
constexpr string_span_type as_string_span() const noexcept
|
||||
{
|
||||
auto sz = span_.size();
|
||||
return { span_.data(), sz > 1 ? sz - 1 : 0 };
|
||||
const auto sz = span_.size();
|
||||
return {span_.data(), sz > 1 ? sz - 1 : 0};
|
||||
}
|
||||
constexpr string_span_type ensure_z() const GSL_NOEXCEPT { return gsl::ensure_z(span_); }
|
||||
constexpr string_span_type ensure_z() const { return gsl::ensure_z(span_); }
|
||||
|
||||
constexpr const_zstring_type assume_z() const GSL_NOEXCEPT { return span_.data(); }
|
||||
constexpr const_zstring_type assume_z() const noexcept { return span_.data(); }
|
||||
|
||||
private:
|
||||
impl_type span_;
|
||||
@@ -456,7 +464,7 @@ template <class CharT, std::ptrdiff_t Extent, class T,
|
||||
class = std::enable_if_t<
|
||||
details::is_basic_string_span<T>::value ||
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
|
||||
bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other) GSL_NOEXCEPT
|
||||
bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other)
|
||||
{
|
||||
const gsl::basic_string_span<std::add_const_t<CharT>> tmp(other);
|
||||
return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end());
|
||||
@@ -466,9 +474,9 @@ template <class CharT, std::ptrdiff_t Extent, class T,
|
||||
class = std::enable_if_t<
|
||||
!details::is_basic_string_span<T>::value &&
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
|
||||
bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other) GSL_NOEXCEPT
|
||||
bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other)
|
||||
{
|
||||
gsl::basic_string_span<std::add_const_t<CharT>> tmp(one);
|
||||
const gsl::basic_string_span<std::add_const_t<CharT>> tmp(one);
|
||||
return std::equal(tmp.begin(), tmp.end(), other.begin(), other.end());
|
||||
}
|
||||
|
||||
@@ -476,7 +484,7 @@ bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||
typename = std::enable_if_t<std::is_convertible<
|
||||
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
|
||||
bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
|
||||
bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other)
|
||||
{
|
||||
return !(one == other);
|
||||
}
|
||||
@@ -486,7 +494,7 @@ template <
|
||||
typename = std::enable_if_t<
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
|
||||
!gsl::details::is_basic_string_span<T>::value>>
|
||||
bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
|
||||
bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other)
|
||||
{
|
||||
return !(one == other);
|
||||
}
|
||||
@@ -495,7 +503,7 @@ bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_N
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||
typename = std::enable_if_t<std::is_convertible<
|
||||
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
|
||||
bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
|
||||
bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other)
|
||||
{
|
||||
const gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
|
||||
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
|
||||
@@ -506,7 +514,7 @@ template <
|
||||
typename = std::enable_if_t<
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
|
||||
!gsl::details::is_basic_string_span<T>::value>>
|
||||
bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
|
||||
bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other)
|
||||
{
|
||||
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
|
||||
return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end());
|
||||
@@ -525,7 +533,7 @@ template <
|
||||
std::is_convertible<DataType*, CharT*>::value &&
|
||||
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
|
||||
DataType>::value>>
|
||||
bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
|
||||
bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other)
|
||||
{
|
||||
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
|
||||
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
|
||||
@@ -539,7 +547,7 @@ template <
|
||||
std::is_convertible<DataType*, CharT*>::value &&
|
||||
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
|
||||
DataType>::value>>
|
||||
bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
|
||||
bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other)
|
||||
{
|
||||
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
|
||||
return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end());
|
||||
@@ -550,7 +558,7 @@ bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NO
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||
typename = std::enable_if_t<std::is_convertible<
|
||||
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
|
||||
bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
|
||||
bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other)
|
||||
{
|
||||
return !(other < one);
|
||||
}
|
||||
@@ -560,7 +568,7 @@ template <
|
||||
typename = std::enable_if_t<
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
|
||||
!gsl::details::is_basic_string_span<T>::value>>
|
||||
bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
|
||||
bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other)
|
||||
{
|
||||
return !(other < one);
|
||||
}
|
||||
@@ -578,7 +586,7 @@ template <
|
||||
std::is_convertible<DataType*, CharT*>::value &&
|
||||
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
|
||||
DataType>::value>>
|
||||
bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
|
||||
bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other)
|
||||
{
|
||||
return !(other < one);
|
||||
}
|
||||
@@ -591,7 +599,7 @@ template <
|
||||
std::is_convertible<DataType*, CharT*>::value &&
|
||||
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
|
||||
DataType>::value>>
|
||||
bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
|
||||
bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other)
|
||||
{
|
||||
return !(other < one);
|
||||
}
|
||||
@@ -601,7 +609,7 @@ bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_N
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||
typename = std::enable_if_t<std::is_convertible<
|
||||
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
|
||||
bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
|
||||
bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other)
|
||||
{
|
||||
return other < one;
|
||||
}
|
||||
@@ -611,7 +619,7 @@ template <
|
||||
typename = std::enable_if_t<
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
|
||||
!gsl::details::is_basic_string_span<T>::value>>
|
||||
bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
|
||||
bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other)
|
||||
{
|
||||
return other < one;
|
||||
}
|
||||
@@ -629,7 +637,7 @@ template <
|
||||
std::is_convertible<DataType*, CharT*>::value &&
|
||||
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
|
||||
DataType>::value>>
|
||||
bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
|
||||
bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other)
|
||||
{
|
||||
return other < one;
|
||||
}
|
||||
@@ -642,7 +650,7 @@ template <
|
||||
std::is_convertible<DataType*, CharT*>::value &&
|
||||
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
|
||||
DataType>::value>>
|
||||
bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
|
||||
bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other)
|
||||
{
|
||||
return other < one;
|
||||
}
|
||||
@@ -652,7 +660,7 @@ bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NO
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||
typename = std::enable_if_t<std::is_convertible<
|
||||
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
|
||||
bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
|
||||
bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other)
|
||||
{
|
||||
return !(one < other);
|
||||
}
|
||||
@@ -662,7 +670,7 @@ template <
|
||||
typename = std::enable_if_t<
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
|
||||
!gsl::details::is_basic_string_span<T>::value>>
|
||||
bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
|
||||
bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other)
|
||||
{
|
||||
return !(one < other);
|
||||
}
|
||||
@@ -680,7 +688,7 @@ template <
|
||||
std::is_convertible<DataType*, CharT*>::value &&
|
||||
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
|
||||
DataType>::value>>
|
||||
bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
|
||||
bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other)
|
||||
{
|
||||
return !(one < other);
|
||||
}
|
||||
@@ -693,16 +701,14 @@ template <
|
||||
std::is_convertible<DataType*, CharT*>::value &&
|
||||
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
|
||||
DataType>::value>>
|
||||
bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
|
||||
bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other)
|
||||
{
|
||||
return !(one < other);
|
||||
}
|
||||
#endif
|
||||
} // namespace GSL
|
||||
} // namespace gsl
|
||||
|
||||
#undef GSL_NOEXCEPT
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#pragma warning(pop)
|
||||
|
||||
#if _MSC_VER < 1910
|
||||
|
||||
+68
-25
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
cmake_minimum_required(VERSION 3.0.2)
|
||||
|
||||
project(GSLTests CXX)
|
||||
|
||||
@@ -26,16 +26,31 @@ else()
|
||||
add_custom_target(catch)
|
||||
endif()
|
||||
|
||||
if (MSVC AND (GSL_CXX_STANDARD EQUAL 17))
|
||||
set(GSL_CPLUSPLUS_OPT -Zc:__cplusplus -permissive-)
|
||||
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
|
||||
>
|
||||
$<$<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
|
||||
@@ -43,15 +58,25 @@ target_compile_options(gsl_tests_config INTERFACE
|
||||
-Wctor-dtor-privacy
|
||||
-Werror
|
||||
-Wextra
|
||||
-Wno-missing-braces
|
||||
-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
|
||||
@@ -101,6 +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(strict_notnull_tests)
|
||||
|
||||
|
||||
# No exception tests
|
||||
@@ -114,32 +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
|
||||
>
|
||||
$<$<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
|
||||
-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
|
||||
|
||||
+31
-20
@@ -14,6 +14,12 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHE...
|
||||
|
||||
#include <gsl/gsl_algorithm> // for copy
|
||||
@@ -29,6 +35,8 @@ struct fail_fast;
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
TEST_CASE("same_type")
|
||||
{
|
||||
// dynamic source and destination span
|
||||
@@ -36,8 +44,8 @@ TEST_CASE("same_type")
|
||||
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||
std::array<int, 10> dst{};
|
||||
|
||||
span<int> src_span(src);
|
||||
span<int> dst_span(dst);
|
||||
const span<int> src_span(src);
|
||||
const span<int> dst_span(dst);
|
||||
|
||||
copy(src_span, dst_span);
|
||||
copy(src_span, dst_span.subspan(src_span.size()));
|
||||
@@ -53,8 +61,8 @@ TEST_CASE("same_type")
|
||||
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||
std::array<int, 10> dst{};
|
||||
|
||||
span<int, 5> src_span(src);
|
||||
span<int> dst_span(dst);
|
||||
const span<int, 5> src_span(src);
|
||||
const span<int> dst_span(dst);
|
||||
|
||||
copy(src_span, dst_span);
|
||||
copy(src_span, dst_span.subspan(src_span.size()));
|
||||
@@ -70,8 +78,8 @@ TEST_CASE("same_type")
|
||||
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||
std::array<int, 10> dst{};
|
||||
|
||||
span<int> src_span(src);
|
||||
span<int, 10> dst_span(dst);
|
||||
const span<int> src_span(src);
|
||||
const span<int, 10> dst_span(dst);
|
||||
|
||||
copy(src_span, dst_span);
|
||||
copy(src_span, dst_span.subspan(src_span.size()));
|
||||
@@ -87,8 +95,8 @@ TEST_CASE("same_type")
|
||||
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||
std::array<int, 10> dst{};
|
||||
|
||||
span<int, 5> src_span(src);
|
||||
span<int, 10> dst_span(dst);
|
||||
const span<int, 5> src_span(src);
|
||||
const span<int, 10> dst_span(dst);
|
||||
|
||||
copy(src_span, dst_span);
|
||||
copy(src_span, dst_span.subspan(src_span.size()));
|
||||
@@ -100,6 +108,9 @@ TEST_CASE("same_type")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
TEST_CASE("compatible_type")
|
||||
{
|
||||
// dynamic source and destination span
|
||||
@@ -107,8 +118,8 @@ TEST_CASE("compatible_type")
|
||||
std::array<short, 5> src{1, 2, 3, 4, 5};
|
||||
std::array<int, 10> dst{};
|
||||
|
||||
span<short> src_span(src);
|
||||
span<int> dst_span(dst);
|
||||
const span<short> src_span(src);
|
||||
const span<int> dst_span(dst);
|
||||
|
||||
copy(src_span, dst_span);
|
||||
copy(src_span, dst_span.subspan(src_span.size()));
|
||||
@@ -124,8 +135,8 @@ TEST_CASE("compatible_type")
|
||||
std::array<short, 5> src{1, 2, 3, 4, 5};
|
||||
std::array<int, 10> dst{};
|
||||
|
||||
span<short, 5> src_span(src);
|
||||
span<int> dst_span(dst);
|
||||
const span<short, 5> src_span(src);
|
||||
const span<int> dst_span(dst);
|
||||
|
||||
copy(src_span, dst_span);
|
||||
copy(src_span, dst_span.subspan(src_span.size()));
|
||||
@@ -141,8 +152,8 @@ TEST_CASE("compatible_type")
|
||||
std::array<short, 5> src{1, 2, 3, 4, 5};
|
||||
std::array<int, 10> dst{};
|
||||
|
||||
span<short> src_span(src);
|
||||
span<int, 10> dst_span(dst);
|
||||
const span<short> src_span(src);
|
||||
const span<int, 10> dst_span(dst);
|
||||
|
||||
copy(src_span, dst_span);
|
||||
copy(src_span, dst_span.subspan(src_span.size()));
|
||||
@@ -158,8 +169,8 @@ TEST_CASE("compatible_type")
|
||||
std::array<short, 5> src{1, 2, 3, 4, 5};
|
||||
std::array<int, 10> dst{};
|
||||
|
||||
span<short, 5> src_span(src);
|
||||
span<int, 10> dst_span(dst);
|
||||
const span<short, 5> src_span(src);
|
||||
const span<int, 10> dst_span(dst);
|
||||
|
||||
copy(src_span, dst_span);
|
||||
copy(src_span, dst_span.subspan(src_span.size()));
|
||||
@@ -195,10 +206,10 @@ TEST_CASE("small_destination_span")
|
||||
std::array<int, 12> src{1, 2, 3, 4};
|
||||
std::array<int, 4> dst{};
|
||||
|
||||
span<int> src_span_dyn(src);
|
||||
span<int, 12> src_span_static(src);
|
||||
span<int> dst_span_dyn(dst);
|
||||
span<int, 4> dst_span_static(dst);
|
||||
const span<int> src_span_dyn(src);
|
||||
const span<int, 12> src_span_static(src);
|
||||
const span<int> dst_span_dyn(dst);
|
||||
const span<int, 4> dst_span_static(dst);
|
||||
|
||||
CHECK_THROWS_AS(copy(src_span_dyn, dst_span_dyn), fail_fast);
|
||||
CHECK_THROWS_AS(copy(src_span_dyn, dst_span_static), fail_fast);
|
||||
|
||||
@@ -14,6 +14,12 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHECK...
|
||||
|
||||
#include <gsl/gsl_assert> // for fail_fast (ptr only), Ensures, Expects
|
||||
|
||||
+20
-1
@@ -14,6 +14,12 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK_THROW...
|
||||
|
||||
#include <gsl/gsl_util> // for at
|
||||
@@ -23,12 +29,15 @@
|
||||
#include <initializer_list> // for initializer_list
|
||||
#include <vector> // for vector
|
||||
|
||||
|
||||
namespace gsl {
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
|
||||
using gsl::fail_fast;
|
||||
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
TEST_CASE("static_array")
|
||||
{
|
||||
int a[4] = {1, 2, 3, 4};
|
||||
@@ -45,6 +54,8 @@ TEST_CASE("static_array")
|
||||
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
TEST_CASE("std_array")
|
||||
{
|
||||
std::array<int, 4> a = {1, 2, 3, 4};
|
||||
@@ -61,6 +72,8 @@ TEST_CASE("std_array")
|
||||
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
TEST_CASE("StdVector")
|
||||
{
|
||||
std::vector<int> a = {1, 2, 3, 4};
|
||||
@@ -77,9 +90,11 @@ TEST_CASE("StdVector")
|
||||
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
TEST_CASE("InitializerList")
|
||||
{
|
||||
std::initializer_list<int> a = {1, 2, 3, 4};
|
||||
const std::initializer_list<int> a = {1, 2, 3, 4};
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
CHECK(gsl::at(a, i) == i + 1);
|
||||
@@ -93,6 +108,9 @@ TEST_CASE("InitializerList")
|
||||
}
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
static constexpr bool test_constexpr()
|
||||
{
|
||||
int a1[4] = {1, 2, 3, 4};
|
||||
@@ -114,3 +132,4 @@ static constexpr bool test_constexpr()
|
||||
|
||||
static_assert(test_constexpr(), "FAIL");
|
||||
#endif
|
||||
|
||||
|
||||
@@ -14,6 +14,18 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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 : 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
|
||||
|
||||
#include <gsl/multi_span> // for static_bounds, static_bounds_dynamic_range_t
|
||||
@@ -32,6 +44,7 @@ namespace
|
||||
void use(std::ptrdiff_t&) {}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
TEST_CASE("basic_bounds")
|
||||
{
|
||||
for (auto point : static_bounds<dynamic_range, 3, 4>{2}) {
|
||||
@@ -44,6 +57,8 @@ TEST_CASE("basic_bounds")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("bounds_basic")
|
||||
{
|
||||
static_bounds<3, 4, 5> b;
|
||||
@@ -53,6 +68,8 @@ TEST_CASE("bounds_basic")
|
||||
x.slice().slice();
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("arrayview_iterator")
|
||||
{
|
||||
static_bounds<4, dynamic_range, 2> bounds{3};
|
||||
@@ -71,6 +88,7 @@ TEST_CASE("arrayview_iterator")
|
||||
#endif
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("bounds_convertible")
|
||||
{
|
||||
static_bounds<7, 4, 2> b1;
|
||||
@@ -97,3 +115,11 @@ TEST_CASE("bounds_convertible")
|
||||
CHECK(b5 == b6);
|
||||
CHECK(b5.size() == b6.size());
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
+18
-6
@@ -14,6 +14,12 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
|
||||
|
||||
#include <gsl/gsl_byte> // for to_byte, to_integer, byte, operator&, ope...
|
||||
@@ -23,7 +29,6 @@ using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
TEST_CASE("construction")
|
||||
{
|
||||
{
|
||||
@@ -31,6 +36,7 @@ TEST_CASE("construction")
|
||||
CHECK(static_cast<unsigned char>(b) == 4);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(es.49)
|
||||
{
|
||||
const byte b = byte(12);
|
||||
CHECK(static_cast<unsigned char>(b) == 12);
|
||||
@@ -46,11 +52,12 @@ TEST_CASE("construction")
|
||||
CHECK(static_cast<unsigned char>(b) == 12);
|
||||
}
|
||||
|
||||
// waiting for C++17 enum class direct initializer support
|
||||
//{
|
||||
// byte b { 14 };
|
||||
// CHECK(static_cast<unsigned char>(b) == 14);
|
||||
//}
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
{
|
||||
const byte b { 14 };
|
||||
CHECK(static_cast<unsigned char>(b) == 14);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("bitwise_operations")
|
||||
@@ -114,6 +121,7 @@ int modify_both(gsl::byte & b, int& i)
|
||||
return i;
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(type.1)
|
||||
TEST_CASE("aliasing")
|
||||
{
|
||||
int i{0};
|
||||
@@ -122,3 +130,7 @@ TEST_CASE("aliasing")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
|
||||
+168
-70
@@ -14,6 +14,19 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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 : 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...
|
||||
|
||||
#include <gsl/gsl_byte> // for byte
|
||||
@@ -29,9 +42,10 @@
|
||||
#include <string> // for string
|
||||
#include <vector> // for vector
|
||||
|
||||
namespace gsl {
|
||||
namespace gsl
|
||||
{
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
} // namespace gsl
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
@@ -44,8 +58,9 @@ struct BaseClass
|
||||
struct DerivedClass : BaseClass
|
||||
{
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("default_constructor")
|
||||
{
|
||||
{
|
||||
@@ -80,6 +95,7 @@ TEST_CASE("default_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_nullptr_constructor")
|
||||
{
|
||||
{
|
||||
@@ -122,8 +138,8 @@ TEST_CASE("from_nullptr_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("from_nullptr_length_constructor")
|
||||
{
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_nullptr_length_constructor") {
|
||||
{
|
||||
multi_span<int> s{nullptr, 0};
|
||||
CHECK((s.length() == 0 && s.data() == nullptr));
|
||||
@@ -141,25 +157,18 @@ TEST_CASE("from_nullptr_length_constructor")
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
multi_span<int, 1> s{nullptr, 0};
|
||||
CHECK((s.length() == 1 && s.data() == nullptr)); // explains why it can't compile
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = []() { multi_span<int> s{nullptr, 1}; };
|
||||
auto workaround_macro = []() { const multi_span<int> s{nullptr, 1}; };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
|
||||
auto const_workaround_macro = []() { multi_span<const int> cs{nullptr, 1}; };
|
||||
auto const_workaround_macro = []() { const multi_span<const int> cs{nullptr, 1}; };
|
||||
CHECK_THROWS_AS(const_workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = []() { multi_span<int, 0> s{nullptr, 1}; };
|
||||
auto workaround_macro = []() { const multi_span<int, 0> s{nullptr, 1}; };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
|
||||
auto const_workaround_macro = []() { multi_span<const int, 0> s{nullptr, 1}; };
|
||||
auto const_workaround_macro = []() { const multi_span<const int, 0> s{nullptr, 1}; };
|
||||
CHECK_THROWS_AS(const_workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
@@ -170,8 +179,16 @@ TEST_CASE("from_nullptr_length_constructor")
|
||||
multi_span<const int*> cs{nullptr, 0};
|
||||
CHECK((cs.length() == 0 && cs.data() == nullptr));
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
multi_span<int, 1> s{nullptr, 0};
|
||||
CHECK((s.length() == 1 && s.data() == nullptr)); // explains why it can't compile
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_element_constructor")
|
||||
{
|
||||
int i = 5;
|
||||
@@ -222,6 +239,7 @@ TEST_CASE("from_element_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_pointer_length_constructor")
|
||||
{
|
||||
int arr[4] = {1, 2, 3, 4};
|
||||
@@ -246,11 +264,12 @@ TEST_CASE("from_pointer_length_constructor")
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
auto workaround_macro = [=]() { multi_span<int> s{p, 2}; };
|
||||
auto workaround_macro = [=]() { const multi_span<int> s{p, 2}; };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_pointer_pointer_constructor")
|
||||
{
|
||||
int arr[4] = {1, 2, 3, 4};
|
||||
@@ -278,29 +297,31 @@ TEST_CASE("from_pointer_pointer_constructor")
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = [&]() { multi_span<int> s{&arr[1], &arr[0]}; };
|
||||
auto workaround_macro = [&]() { const multi_span<int> s{&arr[1], &arr[0]}; };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
auto workaround_macro = [&]() { multi_span<int> s{&arr[0], p}; };
|
||||
auto workaround_macro = [&]() { const multi_span<int> s{&arr[0], p}; };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
auto workaround_macro = [&]() { multi_span<int> s{p, p}; };
|
||||
auto workaround_macro = [&]() { const multi_span<int> s{p, p}; };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
auto workaround_macro = [&]() { multi_span<int> s{&arr[0], p}; };
|
||||
auto workaround_macro = [&]() { const multi_span<int> s{&arr[0], p}; };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_array_constructor")
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
@@ -425,6 +446,11 @@ TEST_CASE("from_array_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(i.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_dynamic_array_constructor")
|
||||
{
|
||||
double(*arr)[3][4] = new double[100][3][4];
|
||||
@@ -453,6 +479,7 @@ TEST_CASE("from_dynamic_array_constructor")
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: Attribute
|
||||
TEST_CASE("from_std_array_constructor")
|
||||
{
|
||||
std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
@@ -512,6 +539,7 @@ TEST_CASE("from_std_array_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_const_std_array_constructor")
|
||||
{
|
||||
const std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
@@ -559,6 +587,7 @@ TEST_CASE("from_const_std_array_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_container_constructor")
|
||||
{
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
@@ -589,8 +618,7 @@ TEST_CASE("from_container_constructor")
|
||||
multi_span<char> s{cstr};
|
||||
#endif
|
||||
multi_span<const char> cs{cstr};
|
||||
CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size()) &&
|
||||
cs.data() == cstr.data()));
|
||||
CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size()) && cs.data() == cstr.data()));
|
||||
}
|
||||
|
||||
{
|
||||
@@ -633,6 +661,8 @@ TEST_CASE("from_container_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_convertible_span_constructor")
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
@@ -660,6 +690,7 @@ TEST_CASE("from_convertible_span_constructor")
|
||||
(void) avcd;
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("copy_move_and_assignment")
|
||||
{
|
||||
multi_span<int> s1;
|
||||
@@ -688,6 +719,8 @@ void fn(const Bounds&)
|
||||
{
|
||||
static_assert(Bounds::static_size == 60, "static bounds is wrong size");
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("as_multi_span_reshape")
|
||||
{
|
||||
int a[3][4][5];
|
||||
@@ -706,11 +739,10 @@ TEST_CASE("as_multi_span_reshape")
|
||||
auto av8 = as_multi_span<int>(av7);
|
||||
|
||||
CHECK(av8.size() == av6.size());
|
||||
for (auto i = 0; i < av8.size(); i++) {
|
||||
CHECK(av8[i] == 1);
|
||||
}
|
||||
for (auto i = 0; i < av8.size(); i++) { CHECK(av8[i] == 1); }
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("first")
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
@@ -754,6 +786,7 @@ TEST_CASE("first")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("last")
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
@@ -796,6 +829,7 @@ TEST_CASE("last")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("subspan")
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
@@ -869,6 +903,7 @@ TEST_CASE("subspan")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("rank")
|
||||
{
|
||||
int arr[2] = {1, 2};
|
||||
@@ -890,6 +925,7 @@ TEST_CASE("rank")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("extent")
|
||||
{
|
||||
{
|
||||
@@ -962,6 +998,7 @@ TEST_CASE("operator_function_call")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("comparison_operators")
|
||||
{
|
||||
{
|
||||
@@ -1074,17 +1111,20 @@ TEST_CASE("comparison_operators")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(i.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
TEST_CASE("basics")
|
||||
{
|
||||
auto ptr = as_multi_span(new int[10], 10);
|
||||
fill(ptr.begin(), ptr.end(), 99);
|
||||
for (int num : ptr) {
|
||||
CHECK(num == 99);
|
||||
}
|
||||
for (int num : ptr) { CHECK(num == 99); }
|
||||
|
||||
delete[] ptr.data();
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("bounds_checks")
|
||||
{
|
||||
int arr[10][2];
|
||||
@@ -1111,25 +1151,24 @@ TEST_CASE("bounds_checks")
|
||||
|
||||
void overloaded_func(multi_span<const int, dynamic_range, 3, 5> exp, int expected_value)
|
||||
{
|
||||
for (auto val : exp) {
|
||||
CHECK(val == expected_value);
|
||||
}
|
||||
for (auto val : exp) { CHECK(val == expected_value); }
|
||||
}
|
||||
|
||||
void overloaded_func(multi_span<const char, dynamic_range, 3, 5> exp, char expected_value)
|
||||
{
|
||||
for (auto val : exp) {
|
||||
CHECK(val == expected_value);
|
||||
}
|
||||
for (auto val : exp) { CHECK(val == expected_value); }
|
||||
}
|
||||
|
||||
void fixed_func(multi_span<int, 3, 3, 5> exp, int expected_value)
|
||||
{
|
||||
for (auto val : exp) {
|
||||
CHECK(val == expected_value);
|
||||
}
|
||||
for (auto val : exp) { CHECK(val == expected_value); }
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
|
||||
TEST_CASE("span_parameter_test")
|
||||
{
|
||||
auto data = new int[4][3][5];
|
||||
@@ -1151,12 +1190,16 @@ TEST_CASE("span_parameter_test")
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // false positive, checker does not recognize multi_span yet
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute
|
||||
TEST_CASE("md_access")
|
||||
{
|
||||
auto width = 5, height = 20;
|
||||
|
||||
auto imgSize = width * height;
|
||||
auto image_ptr = new int[static_cast<std::size_t>(imgSize)][3];
|
||||
auto image_ptr = new int[narrow_cast<std::size_t>(imgSize)][3];
|
||||
|
||||
// size check will be done
|
||||
auto image_view =
|
||||
@@ -1165,8 +1208,10 @@ TEST_CASE("md_access")
|
||||
iota(image_view.begin(), image_view.end(), 1);
|
||||
|
||||
int expected = 0;
|
||||
for (auto i = 0; i < height; i++) {
|
||||
for (auto j = 0; j < width; j++) {
|
||||
for (auto i = 0; i < height; i++)
|
||||
{
|
||||
for (auto j = 0; j < width; j++)
|
||||
{
|
||||
CHECK(expected + 1 == image_view[i][j][0]);
|
||||
CHECK(expected + 2 == image_view[i][j][1]);
|
||||
CHECK(expected + 3 == image_view[i][j][2]);
|
||||
@@ -1181,8 +1226,15 @@ TEST_CASE("md_access")
|
||||
expected += 3;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] image_ptr;
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(i.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute
|
||||
TEST_CASE("as_multi_span")
|
||||
{
|
||||
{
|
||||
@@ -1201,6 +1253,7 @@ TEST_CASE("as_multi_span")
|
||||
|
||||
string str = "ttttttttttttttt"; // size = 15
|
||||
auto t = str.data();
|
||||
GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: false positive
|
||||
(void) t;
|
||||
auto av3 = as_multi_span(str);
|
||||
overloaded_func(as_multi_span(av3, dim(1), dim<3>(), dim<5>()), 't');
|
||||
@@ -1232,12 +1285,13 @@ TEST_CASE("as_multi_span")
|
||||
auto dv = as_multi_span(vec);
|
||||
(void) dv;
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
auto dv2 = as_multi_span(std::move(vec));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("empty_spans")
|
||||
{
|
||||
{
|
||||
@@ -1247,7 +1301,8 @@ TEST_CASE("empty_spans")
|
||||
CHECK_THROWS_AS(empty_av[0], fail_fast);
|
||||
CHECK_THROWS_AS(empty_av.begin()[0], fail_fast);
|
||||
CHECK_THROWS_AS(empty_av.cbegin()[0], fail_fast);
|
||||
for (auto& v : empty_av) {
|
||||
for (auto& v : empty_av)
|
||||
{
|
||||
(void) v;
|
||||
CHECK(false);
|
||||
}
|
||||
@@ -1259,17 +1314,25 @@ TEST_CASE("empty_spans")
|
||||
CHECK_THROWS_AS(empty_av[0], fail_fast);
|
||||
CHECK_THROWS_AS(empty_av.begin()[0], fail_fast);
|
||||
CHECK_THROWS_AS(empty_av.cbegin()[0], fail_fast);
|
||||
for (auto& v : empty_av) {
|
||||
for (auto& v : empty_av)
|
||||
{
|
||||
(void) v;
|
||||
CHECK(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
TEST_CASE("index_constructor")
|
||||
{
|
||||
auto arr = new int[8];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
arr[2 * i] = 4 + i;
|
||||
arr[2 * i + 1] = i;
|
||||
}
|
||||
@@ -1291,6 +1354,7 @@ TEST_CASE("index_constructor")
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("index_constructors")
|
||||
{
|
||||
{
|
||||
@@ -1352,17 +1416,18 @@ TEST_CASE("index_constructors")
|
||||
CHECK(i9[0] == 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
multi_span_index<3> i1(0, 1);
|
||||
multi_span_index<3> i2(0, 1, 2, 3);
|
||||
multi_span_index<3> i3 = {0};
|
||||
multi_span_index<3> i4 = {0, 1, 2, 3};
|
||||
multi_span_index<1> i5 = {0, 1};
|
||||
multi_span_index<3> i1(0, 1);
|
||||
multi_span_index<3> i2(0, 1, 2, 3);
|
||||
multi_span_index<3> i3 = {0};
|
||||
multi_span_index<3> i4 = {0, 1, 2, 3};
|
||||
multi_span_index<1> i5 = {0, 1};
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("index_operations")
|
||||
{
|
||||
ptrdiff_t a[3] = {0, 1, 2};
|
||||
@@ -1418,6 +1483,8 @@ TEST_CASE("index_operations")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
void iterate_second_column(multi_span<int, dynamic_range, dynamic_range> av)
|
||||
{
|
||||
auto length = av.size() / 2;
|
||||
@@ -1426,33 +1493,33 @@ void iterate_second_column(multi_span<int, dynamic_range, dynamic_range> av)
|
||||
auto section = av.section({0, 1}, {length, 1});
|
||||
|
||||
CHECK(section.size() == length);
|
||||
for (auto i = 0; i < section.size(); ++i) {
|
||||
CHECK(section[i][0] == av[i][1]);
|
||||
}
|
||||
for (auto i = 0; i < section.size(); ++i) { CHECK(section[i][0] == av[i][1]); }
|
||||
|
||||
for (auto i = 0; i < section.size(); ++i) {
|
||||
for (auto i = 0; i < section.size(); ++i)
|
||||
{
|
||||
auto idx = multi_span_index<2>{i, 0}; // avoid braces inside the CHECK macro
|
||||
CHECK(section[idx] == av[i][1]);
|
||||
}
|
||||
|
||||
CHECK(section.bounds().index_bounds()[0] == length);
|
||||
CHECK(section.bounds().index_bounds()[1] == 1);
|
||||
for (auto i = 0; i < section.bounds().index_bounds()[0]; ++i) {
|
||||
for (auto j = 0; j < section.bounds().index_bounds()[1]; ++j) {
|
||||
for (auto i = 0; i < section.bounds().index_bounds()[0]; ++i)
|
||||
{
|
||||
for (auto j = 0; j < section.bounds().index_bounds()[1]; ++j)
|
||||
{
|
||||
auto idx = multi_span_index<2>{i, j}; // avoid braces inside the CHECK macro
|
||||
CHECK(section[idx] == av[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
auto check_sum = 0;
|
||||
for (auto i = 0; i < length; ++i) {
|
||||
check_sum += av[i][1];
|
||||
}
|
||||
for (auto i = 0; i < length; ++i) { check_sum += av[i][1]; }
|
||||
|
||||
{
|
||||
auto idx = 0;
|
||||
auto sum = 0;
|
||||
for (auto num : section) {
|
||||
for (auto num : section)
|
||||
{
|
||||
CHECK(num == av[idx][1]);
|
||||
sum += num;
|
||||
idx++;
|
||||
@@ -1463,7 +1530,8 @@ void iterate_second_column(multi_span<int, dynamic_range, dynamic_range> av)
|
||||
{
|
||||
auto idx = length - 1;
|
||||
auto sum = 0;
|
||||
for (auto iter = section.rbegin(); iter != section.rend(); ++iter) {
|
||||
for (auto iter = section.rbegin(); iter != section.rend(); ++iter)
|
||||
{
|
||||
CHECK(*iter == av[idx][1]);
|
||||
sum += *iter;
|
||||
idx--;
|
||||
@@ -1473,6 +1541,7 @@ void iterate_second_column(multi_span<int, dynamic_range, dynamic_range> av)
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("span_section_iteration")
|
||||
{
|
||||
int arr[4][2] = {{4, 0}, {5, 1}, {6, 2}, {7, 3}};
|
||||
@@ -1499,15 +1568,18 @@ TEST_CASE("span_section_iteration")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
TEST_CASE("dynamic_span_section_iteration")
|
||||
{
|
||||
auto height = 4, width = 2;
|
||||
auto size = height * width;
|
||||
|
||||
auto arr = new int[static_cast<std::size_t>(size)];
|
||||
for (auto i = 0; i < size; ++i) {
|
||||
arr[i] = i;
|
||||
}
|
||||
auto arr = new int[narrow_cast<std::size_t>(size)];
|
||||
for (auto i = 0; i < size; ++i) { arr[i] = i; }
|
||||
|
||||
auto av = as_multi_span(arr, size);
|
||||
|
||||
@@ -1531,6 +1603,10 @@ TEST_CASE("dynamic_span_section_iteration")
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(i.11) // NO-FORMAT: attribute
|
||||
TEST_CASE("span_structure_size")
|
||||
{
|
||||
double(*arr)[3][4] = new double[100][3][4];
|
||||
@@ -1548,8 +1624,11 @@ 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
|
||||
TEST_CASE("fixed_size_conversions")
|
||||
{
|
||||
int arr[] = {1, 2, 3, 4};
|
||||
@@ -1631,7 +1710,7 @@ TEST_CASE("fixed_size_conversions")
|
||||
#endif
|
||||
{
|
||||
auto f = [&]() {
|
||||
multi_span<int, 4> av9 = {arr2, 2};
|
||||
const multi_span<int, 4> av9 = {arr2, 2};
|
||||
(void) av9;
|
||||
};
|
||||
CHECK_THROWS_AS(f(), fail_fast);
|
||||
@@ -1640,12 +1719,13 @@ TEST_CASE("fixed_size_conversions")
|
||||
// this should fail - we are trying to assign a small dynamic a_v to a fixed_size larger one
|
||||
multi_span<int, dynamic_range> av = arr2;
|
||||
auto f = [&]() {
|
||||
multi_span<int, 4> av2 = av;
|
||||
const multi_span<int, 4> av2 = av;
|
||||
(void) av2;
|
||||
};
|
||||
CHECK_THROWS_AS(f(), fail_fast);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("as_writeable_bytes")
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
@@ -1674,6 +1754,10 @@ TEST_CASE("as_writeable_bytes")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("iterator")
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
@@ -1682,8 +1766,14 @@ TEST_CASE("iterator")
|
||||
multi_span<int, dynamic_range> av = a;
|
||||
auto wav = as_writeable_bytes(av);
|
||||
for (auto& b : wav) {
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
b = byte{0};
|
||||
#else
|
||||
GSL_SUPPRESS(es.49)
|
||||
b = byte(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < 4; ++i) {
|
||||
CHECK(a[i] == 0);
|
||||
}
|
||||
@@ -1699,3 +1789,11 @@ TEST_CASE("iterator")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -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()
|
||||
int operator_subscript_no_throw() noexcept
|
||||
{
|
||||
int arr[10];
|
||||
gsl::span<int> sp { arr };
|
||||
int arr[10];
|
||||
const gsl::span<int> sp{arr};
|
||||
return sp[11];
|
||||
}
|
||||
|
||||
[[noreturn]] void test_terminate() { std::exit(0); }
|
||||
|
||||
void test_terminate()
|
||||
{
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
void setup_termination_handler()
|
||||
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,8 +40,7 @@ void setup_termination_handler()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
int main() noexcept
|
||||
{
|
||||
setup_termination_handler();
|
||||
operator_subscript_no_throw();
|
||||
|
||||
@@ -14,23 +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()
|
||||
{
|
||||
long long bigNumber = 0x0fffffffffffffff;
|
||||
return gsl::narrow<int>(bigNumber);
|
||||
const long long bigNumber = 0x0fffffffffffffff;
|
||||
return gsl::narrow<int>(bigNumber);
|
||||
}
|
||||
|
||||
void test_terminate()
|
||||
{
|
||||
std::exit(0);
|
||||
}
|
||||
[[noreturn]] void test_terminate() { std::exit(0); }
|
||||
|
||||
void setup_termination_handler()
|
||||
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;
|
||||
@@ -42,7 +40,6 @@ void setup_termination_handler()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
setup_termination_handler();
|
||||
|
||||
+241
-36
@@ -14,6 +14,15 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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>
|
||||
@@ -25,9 +34,10 @@
|
||||
#include <string> // for basic_string, operator==, string, operator<<
|
||||
#include <typeinfo> // for type_info
|
||||
|
||||
namespace gsl {
|
||||
namespace gsl
|
||||
{
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
} // namespace gsl
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
@@ -63,6 +73,7 @@ struct CustomPtr
|
||||
template <typename T, typename U>
|
||||
std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
return reinterpret_cast<const void*>(lhs.p_) == reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -70,6 +81,7 @@ std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
return reinterpret_cast<const void*>(lhs.p_) != reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -77,6 +89,7 @@ std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
return reinterpret_cast<const void*>(lhs.p_) < reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -84,6 +97,7 @@ std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
return reinterpret_cast<const void*>(lhs.p_) > reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -91,6 +105,7 @@ std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
return reinterpret_cast<const void*>(lhs.p_) <= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -98,6 +113,7 @@ std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator>=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
return reinterpret_cast<const void*>(lhs.p_) >= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -111,45 +127,115 @@ struct NonCopyableNonMovable
|
||||
NonCopyableNonMovable& operator=(NonCopyableNonMovable&&) = delete;
|
||||
};
|
||||
|
||||
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; }
|
||||
|
||||
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)
|
||||
{
|
||||
not_null<T*> p(&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());
|
||||
}
|
||||
{
|
||||
@@ -165,23 +251,24 @@ 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");
|
||||
ostream_helper<std::string>("string");
|
||||
}
|
||||
|
||||
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestNotNullCasting")
|
||||
{
|
||||
MyBase base;
|
||||
MyDerived derived;
|
||||
Unrelated unrelated;
|
||||
not_null<Unrelated*> u = &unrelated;
|
||||
not_null<Unrelated*> u{&unrelated};
|
||||
(void) u;
|
||||
not_null<MyDerived*> p = &derived;
|
||||
not_null<MyBase*> q = &base;
|
||||
not_null<MyDerived*> p{&derived};
|
||||
not_null<MyBase*> q(&base);
|
||||
q = p; // allowed with heterogeneous copy ctor
|
||||
CHECK(q == p);
|
||||
|
||||
@@ -192,18 +279,18 @@ TEST_CASE("TestNotNullCasting")
|
||||
not_null<Unrelated*> r = p;
|
||||
not_null<Unrelated*> s = reinterpret_cast<Unrelated*>(p);
|
||||
#endif
|
||||
not_null<Unrelated*> t = reinterpret_cast<Unrelated*>(p.get());
|
||||
not_null<Unrelated*> t(reinterpret_cast<Unrelated*>(p.get()));
|
||||
CHECK(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get()));
|
||||
}
|
||||
|
||||
TEST_CASE("TestNotNullAssignment")
|
||||
{
|
||||
int i = 12;
|
||||
not_null<int*> p = &i;
|
||||
not_null<int*> p(&i);
|
||||
CHECK(helper(p));
|
||||
|
||||
int* q = nullptr;
|
||||
CHECK_THROWS_AS(p = q, fail_fast);
|
||||
CHECK_THROWS_AS(p = not_null<int*>(q), fail_fast);
|
||||
}
|
||||
|
||||
TEST_CASE("TestNotNullRawPointerComparison")
|
||||
@@ -232,21 +319,21 @@ TEST_CASE("TestNotNullRawPointerComparison")
|
||||
CHECK((NotNull1(p1) <= NotNull1(p1)) == true);
|
||||
CHECK((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
|
||||
CHECK((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
|
||||
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestNotNullDereferenceOperator")
|
||||
{
|
||||
{
|
||||
auto sp1 = std::make_shared<NonCopyableNonMovable>();
|
||||
|
||||
using NotNullSp1 = not_null<decltype(sp1)>;
|
||||
CHECK(typeid(*sp1) == typeid(*NotNullSp1(sp1)));
|
||||
CHECK(typeid(*sp1) == typeid(*NotNullSp1(sp1)));
|
||||
CHECK(std::addressof(*NotNullSp1(sp1)) == std::addressof(*sp1));
|
||||
}
|
||||
|
||||
{
|
||||
int ints[1] = { 42 };
|
||||
int ints[1] = {42};
|
||||
CustomPtr<int> p1(&ints[0]);
|
||||
|
||||
using NotNull1 = not_null<decltype(p1)>;
|
||||
@@ -296,6 +383,7 @@ TEST_CASE("TestNotNullSharedPtrComparison")
|
||||
CHECK((NotNullSp2(sp2) >= NotNullSp1(sp1)) == (sp2 >= sp1));
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestNotNullCustomPtrComparison")
|
||||
{
|
||||
int ints[2] = {42, 43};
|
||||
@@ -328,4 +416,121 @@ TEST_CASE("TestNotNullCustomPtrComparison")
|
||||
CHECK((NotNull2(p2) >= NotNull1(p1)) == (p2 >= p1));
|
||||
}
|
||||
|
||||
static_assert(std::is_nothrow_move_constructible<not_null<void *>>::value, "not_null must be no-throw move constructible");
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestNotNullConstructorTypeDeduction")
|
||||
{
|
||||
{
|
||||
int i = 42;
|
||||
|
||||
not_null x{&i};
|
||||
helper(not_null{&i});
|
||||
helper_const(not_null{&i});
|
||||
|
||||
CHECK(*x == 42);
|
||||
}
|
||||
|
||||
{
|
||||
int i = 42;
|
||||
int* p = &i;
|
||||
|
||||
not_null x{p};
|
||||
helper(not_null{p});
|
||||
helper_const(not_null{p});
|
||||
|
||||
CHECK(*x == 42);
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = []() {
|
||||
int* p1 = nullptr;
|
||||
const not_null x{p1};
|
||||
};
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = []() {
|
||||
const int* p1 = nullptr;
|
||||
const not_null x{p1};
|
||||
};
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
|
||||
CHECK_THROWS_AS(helper(not_null{p}), fail_fast);
|
||||
CHECK_THROWS_AS(helper_const(not_null{p}), fail_fast);
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
not_null x{nullptr};
|
||||
helper(not_null{nullptr});
|
||||
helper_const(not_null{nullptr});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
|
||||
TEST_CASE("TestMakeNotNull")
|
||||
{
|
||||
{
|
||||
int i = 42;
|
||||
|
||||
const auto x = make_not_null(&i);
|
||||
helper(make_not_null(&i));
|
||||
helper_const(make_not_null(&i));
|
||||
|
||||
CHECK(*x == 42);
|
||||
}
|
||||
|
||||
{
|
||||
int i = 42;
|
||||
int* p = &i;
|
||||
|
||||
const auto x = make_not_null(p);
|
||||
helper(make_not_null(p));
|
||||
helper_const(make_not_null(p));
|
||||
|
||||
CHECK(*x == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const auto workaround_macro = []() {
|
||||
int* p1 = nullptr;
|
||||
const auto x = make_not_null(p1);
|
||||
CHECK(*x == 42);
|
||||
};
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
const auto workaround_macro = []() {
|
||||
const int* p1 = nullptr;
|
||||
const auto x = make_not_null(p1);
|
||||
CHECK(*x == 42);
|
||||
};
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
|
||||
CHECK_THROWS_AS(helper(make_not_null(p)), fail_fast);
|
||||
CHECK_THROWS_AS(helper_const(make_not_null(p)), fail_fast);
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
CHECK_THROWS_AS(make_not_null(nullptr), fail_fast);
|
||||
CHECK_THROWS_AS(helper(make_not_null(nullptr)), fail_fast);
|
||||
CHECK_THROWS_AS(helper_const(make_not_null(nullptr)), fail_fast);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static_assert(std::is_nothrow_move_constructible<not_null<void*>>::value,
|
||||
"not_null must be no-throw move constructible");
|
||||
|
||||
@@ -14,14 +14,25 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
|
||||
#endif
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
|
||||
|
||||
#include <gsl/pointers> // for owner
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute
|
||||
void f(int* i) { *i += 1; }
|
||||
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute // TODO: false positive
|
||||
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
|
||||
TEST_CASE("basic_test")
|
||||
{
|
||||
owner<int*> p = new int(120);
|
||||
|
||||
+134
-34
@@ -14,6 +14,13 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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 26497) // from catch
|
||||
|
||||
#endif
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
|
||||
|
||||
#include <gsl/gsl_byte> // for byte
|
||||
@@ -30,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;
|
||||
@@ -45,8 +53,16 @@ struct BaseClass
|
||||
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")
|
||||
{
|
||||
{
|
||||
@@ -81,6 +97,7 @@ TEST_CASE("default_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("size_optimization")
|
||||
{
|
||||
{
|
||||
@@ -94,56 +111,60 @@ TEST_CASE("size_optimization")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_nullptr_size_constructor")
|
||||
{
|
||||
{
|
||||
span<int> s{nullptr, static_cast<span<int>::index_type>(0)};
|
||||
span<int> s{nullptr, narrow_cast<span<int>::index_type>(0)};
|
||||
CHECK((s.size() == 0 && s.data() == nullptr));
|
||||
|
||||
span<const int> cs{nullptr, static_cast<span<int>::index_type>(0)};
|
||||
span<const int> cs{nullptr, narrow_cast<span<int>::index_type>(0)};
|
||||
CHECK((cs.size() == 0 && cs.data() == nullptr));
|
||||
}
|
||||
|
||||
{
|
||||
span<int, 0> s{nullptr, static_cast<span<int>::index_type>(0)};
|
||||
span<int, 0> s{nullptr, narrow_cast<span<int>::index_type>(0)};
|
||||
CHECK((s.size() == 0 && s.data() == nullptr));
|
||||
|
||||
span<const int, 0> cs{nullptr, static_cast<span<int>::index_type>(0)};
|
||||
span<const int, 0> cs{nullptr, narrow_cast<span<int>::index_type>(0)};
|
||||
CHECK((cs.size() == 0 && cs.data() == nullptr));
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = []() {
|
||||
span<int, 1> s{nullptr, static_cast<span<int>::index_type>(0)};
|
||||
const span<int, 1> s{nullptr, narrow_cast<span<int>::index_type>(0)};
|
||||
};
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = []() { span<int> s{nullptr, 1}; };
|
||||
auto workaround_macro = []() { const span<int> s{nullptr, 1}; };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
|
||||
auto const_workaround_macro = []() { span<const int> cs{nullptr, 1}; };
|
||||
auto const_workaround_macro = []() { const span<const int> cs{nullptr, 1}; };
|
||||
CHECK_THROWS_AS(const_workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = []() { span<int, 0> s{nullptr, 1}; };
|
||||
auto workaround_macro = []() { const span<int, 0> s{nullptr, 1}; };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
|
||||
auto const_workaround_macro = []() { span<const int, 0> s{nullptr, 1}; };
|
||||
auto const_workaround_macro = []() { const span<const int, 0> s{nullptr, 1}; };
|
||||
CHECK_THROWS_AS(const_workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
{
|
||||
span<int*> s{nullptr, static_cast<span<int>::index_type>(0)};
|
||||
span<int*> s{nullptr, narrow_cast<span<int>::index_type>(0)};
|
||||
CHECK((s.size() == 0 && s.data() == nullptr));
|
||||
|
||||
span<const int*> cs{nullptr, static_cast<span<int>::index_type>(0)};
|
||||
span<const int*> cs{nullptr, narrow_cast<span<int>::index_type>(0)};
|
||||
CHECK((cs.size() == 0 && cs.data() == nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_pointer_length_constructor")
|
||||
{
|
||||
int arr[4] = {1, 2, 3, 4};
|
||||
@@ -164,7 +185,7 @@ TEST_CASE("from_pointer_length_constructor")
|
||||
}
|
||||
}
|
||||
{
|
||||
span<int> s = { &arr[i], 4-i };
|
||||
span<int> s = { &arr[i], 4-narrow_cast<ptrdiff_t>(i) };
|
||||
CHECK(s.size() == 4-i);
|
||||
CHECK(s.data() == &arr[i]);
|
||||
CHECK(s.empty() == (4-i == 0));
|
||||
@@ -186,13 +207,13 @@ TEST_CASE("from_pointer_length_constructor")
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
span<int> s{p, static_cast<span<int>::index_type>(0)};
|
||||
span<int> s{p, narrow_cast<span<int>::index_type>(0)};
|
||||
CHECK((s.size() == 0 && s.data() == nullptr));
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
auto workaround_macro = [=]() { span<int> s{p, 2}; };
|
||||
auto workaround_macro = [=]() { const span<int> s{p, 2}; };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
@@ -204,7 +225,7 @@ TEST_CASE("from_pointer_length_constructor")
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
auto s = make_span(p, static_cast<span<int>::index_type>(0));
|
||||
auto s = make_span(p, narrow_cast<span<int>::index_type>(0));
|
||||
CHECK((s.size() == 0 && s.data() == nullptr));
|
||||
}
|
||||
|
||||
@@ -215,6 +236,8 @@ TEST_CASE("from_pointer_length_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_pointer_pointer_constructor")
|
||||
{
|
||||
int arr[4] = {1, 2, 3, 4};
|
||||
@@ -296,12 +319,12 @@ TEST_CASE("from_array_constructor")
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
|
||||
{
|
||||
span<int> s{arr};
|
||||
const span<int> s{arr};
|
||||
CHECK((s.size() == 5 && s.data() == &arr[0]));
|
||||
}
|
||||
|
||||
{
|
||||
span<int, 5> s{arr};
|
||||
const span<int, 5> s{arr};
|
||||
CHECK((s.size() == 5 && s.data() == &arr[0]));
|
||||
}
|
||||
|
||||
@@ -333,8 +356,8 @@ TEST_CASE("from_array_constructor")
|
||||
}
|
||||
#endif
|
||||
{
|
||||
span<int[3]> s{&(arr2d[0]), 1};
|
||||
CHECK((s.size() == 1 && s.data() == &arr2d[0]));
|
||||
const span<int[3]> s{std::addressof(arr2d[0]), 1};
|
||||
CHECK((s.size() == 1 && s.data() == std::addressof(arr2d[0])));
|
||||
}
|
||||
|
||||
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
@@ -362,26 +385,38 @@ TEST_CASE("from_array_constructor")
|
||||
}
|
||||
#endif
|
||||
{
|
||||
span<int[3][2]> s{&arr3d[0], 1};
|
||||
CHECK((s.size() == 1 && s.data() == &arr3d[0]));
|
||||
const span<int[3][2]> s{std::addressof(arr3d[0]), 1};
|
||||
CHECK((s.size() == 1 && s.data() == std::addressof(arr3d[0])));
|
||||
}
|
||||
|
||||
{
|
||||
auto s = make_span(arr);
|
||||
CHECK((s.size() == 5 && s.data() == &arr[0]));
|
||||
const auto s = make_span(arr);
|
||||
CHECK((s.size() == 5 && s.data() == std::addressof(arr[0])));
|
||||
}
|
||||
|
||||
{
|
||||
auto s = make_span(&(arr2d[0]), 1);
|
||||
CHECK((s.size() == 1 && s.data() == &arr2d[0]));
|
||||
const auto s = make_span(std::addressof(arr2d[0]), 1);
|
||||
CHECK((s.size() == 1 && s.data() == std::addressof(arr2d[0])));
|
||||
}
|
||||
|
||||
{
|
||||
auto s = make_span(&arr3d[0], 1);
|
||||
CHECK((s.size() == 1 && s.data() == &arr3d[0]));
|
||||
const auto s = make_span(std::addressof(arr3d[0]), 1);
|
||||
CHECK((s.size() == 1 && s.data() == std::addressof(arr3d[0])));
|
||||
}
|
||||
|
||||
AddressOverloaded ao_arr[5] = {};
|
||||
|
||||
{
|
||||
const span<AddressOverloaded, 5> s{ao_arr};
|
||||
CHECK((s.size() == 5 && s.data() == std::addressof(ao_arr[0])));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(i.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_dynamic_array_constructor")
|
||||
{
|
||||
double(*arr)[3][4] = new double[100][3][4];
|
||||
@@ -399,6 +434,8 @@ TEST_CASE("from_dynamic_array_constructor")
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_std_array_constructor")
|
||||
{
|
||||
std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
@@ -419,6 +456,19 @@ TEST_CASE("from_std_array_constructor")
|
||||
CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()));
|
||||
}
|
||||
|
||||
{
|
||||
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};
|
||||
CHECK((fs.size() == narrow_cast<ptrdiff_t>(ao_arr.size()) && ao_arr.data() == fs.data()));
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
span<int, 2> s{arr};
|
||||
@@ -459,8 +509,27 @@ TEST_CASE("from_std_array_constructor")
|
||||
auto s = make_span(arr);
|
||||
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, 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 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);
|
||||
#else
|
||||
CHECK(s1.size() == s2.size());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_const_std_array_constructor")
|
||||
{
|
||||
const std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
@@ -475,6 +544,13 @@ TEST_CASE("from_const_std_array_constructor")
|
||||
CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()));
|
||||
}
|
||||
|
||||
const std::array<AddressOverloaded, 4> ao_arr{};
|
||||
|
||||
{
|
||||
span<const AddressOverloaded, 4> s{ao_arr};
|
||||
CHECK((s.size() == narrow_cast<ptrdiff_t>(ao_arr.size()) && s.data() == ao_arr.data()));
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
span<const int, 2> s{arr};
|
||||
@@ -504,6 +580,7 @@ TEST_CASE("from_const_std_array_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_std_array_const_constructor")
|
||||
{
|
||||
std::array<const int, 4> arr = {1, 2, 3, 4};
|
||||
@@ -544,6 +621,7 @@ TEST_CASE("from_std_array_const_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_container_constructor")
|
||||
{
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
@@ -636,6 +714,7 @@ TEST_CASE("from_container_constructor")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("from_convertible_span_constructor")
|
||||
{
|
||||
{
|
||||
@@ -673,6 +752,7 @@ TEST_CASE("from_convertible_span_constructor")
|
||||
#endif
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("copy_move_and_assignment")
|
||||
{
|
||||
span<int> s1;
|
||||
@@ -694,6 +774,7 @@ TEST_CASE("copy_move_and_assignment")
|
||||
CHECK((s1.size() == 2 && s1.data() == &arr[1]));
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("first")
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
@@ -732,6 +813,7 @@ TEST_CASE("first")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("last")
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
@@ -769,6 +851,7 @@ TEST_CASE("last")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("subspan")
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
@@ -850,6 +933,7 @@ TEST_CASE("subspan")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("at_call")
|
||||
{
|
||||
int arr[4] = {1, 2, 3, 4};
|
||||
@@ -869,6 +953,7 @@ TEST_CASE("at_call")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("operator_function_call")
|
||||
{
|
||||
int arr[4] = {1, 2, 3, 4};
|
||||
@@ -888,6 +973,7 @@ TEST_CASE("operator_function_call")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("iterator_default_init")
|
||||
{
|
||||
span<int>::iterator it1;
|
||||
@@ -895,6 +981,7 @@ TEST_CASE("iterator_default_init")
|
||||
CHECK(it1 == it2);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("const_iterator_default_init")
|
||||
{
|
||||
span<int>::const_iterator it1;
|
||||
@@ -902,6 +989,7 @@ TEST_CASE("const_iterator_default_init")
|
||||
CHECK(it1 == it2);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("iterator_conversions")
|
||||
{
|
||||
span<int>::iterator badIt;
|
||||
@@ -924,6 +1012,7 @@ TEST_CASE("iterator_conversions")
|
||||
CHECK(cit3 == s.cend());
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("iterator_comparisons")
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
@@ -971,6 +1060,7 @@ TEST_CASE("iterator_comparisons")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("begin_end")
|
||||
{
|
||||
{
|
||||
@@ -1026,6 +1116,7 @@ TEST_CASE("begin_end")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("cbegin_cend")
|
||||
{
|
||||
{
|
||||
@@ -1078,6 +1169,7 @@ TEST_CASE("cbegin_cend")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("rbegin_rend")
|
||||
{
|
||||
{
|
||||
@@ -1120,6 +1212,7 @@ TEST_CASE("rbegin_rend")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("crbegin_crend")
|
||||
{
|
||||
{
|
||||
@@ -1159,6 +1252,7 @@ TEST_CASE("crbegin_crend")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("comparison_operators")
|
||||
{
|
||||
{
|
||||
@@ -1279,6 +1373,7 @@ TEST_CASE("comparison_operators")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("as_bytes")
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
@@ -1309,6 +1404,7 @@ TEST_CASE("as_bytes")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("as_writeable_bytes")
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
@@ -1342,6 +1438,7 @@ TEST_CASE("as_writeable_bytes")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("fixed_size_conversions")
|
||||
{
|
||||
int arr[] = {1, 2, 3, 4};
|
||||
@@ -1372,7 +1469,7 @@ TEST_CASE("fixed_size_conversions")
|
||||
{
|
||||
span<int> s = arr;
|
||||
auto f = [&]() {
|
||||
span<int, 2> s2 = s;
|
||||
const span<int, 2> s2 = s;
|
||||
static_cast<void>(s2);
|
||||
};
|
||||
CHECK_THROWS_AS(f(), fail_fast);
|
||||
@@ -1382,7 +1479,7 @@ TEST_CASE("fixed_size_conversions")
|
||||
|
||||
// you can convert statically
|
||||
{
|
||||
const span<int, 2> s2 = {arr, 2};
|
||||
const span<int, 2> s2 = {&arr[0], 2};
|
||||
static_cast<void>(s2);
|
||||
}
|
||||
{
|
||||
@@ -1411,7 +1508,7 @@ TEST_CASE("fixed_size_conversions")
|
||||
#endif
|
||||
{
|
||||
auto f = [&]() {
|
||||
span<int, 4> _s4 = {arr2, 2};
|
||||
const span<int, 4> _s4 = {arr2, 2};
|
||||
static_cast<void>(_s4);
|
||||
};
|
||||
CHECK_THROWS_AS(f(), fail_fast);
|
||||
@@ -1420,12 +1517,13 @@ TEST_CASE("fixed_size_conversions")
|
||||
// this should fail - we are trying to assign a small dynamic span to a fixed_size larger one
|
||||
span<int> av = arr2;
|
||||
auto f = [&]() {
|
||||
span<int, 4> _s4 = av;
|
||||
const span<int, 4> _s4 = av;
|
||||
static_cast<void>(_s4);
|
||||
};
|
||||
CHECK_THROWS_AS(f(), fail_fast);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("interop_with_std_regex")
|
||||
{
|
||||
char lat[] = {'1', '2', '3', '4', '5', '6', 'E', 'F', 'G'};
|
||||
@@ -1449,6 +1547,7 @@ TEST_CASE("interop_with_std_regex")
|
||||
CHECK(match[0].second == (f_it + 1));
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("interop_with_gsl_at")
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
@@ -1462,3 +1561,4 @@ TEST_CASE("default_constructible")
|
||||
CHECK((std::is_default_constructible<span<int, 0>>::value));
|
||||
CHECK((!std::is_default_constructible<span<int, 42>>::value));
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
@@ -14,6 +14,19 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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 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...
|
||||
|
||||
#include <gsl/gsl_byte> // for byte
|
||||
@@ -60,17 +73,20 @@ TEST_CASE("span_section")
|
||||
const multi_span<int, 5, 10> av = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
|
||||
|
||||
const strided_span<int, 2> av_section_1 = av.section({1, 2}, {3, 4});
|
||||
CHECK(!av_section_1.empty());
|
||||
CHECK((av_section_1[{0, 0}] == 12));
|
||||
CHECK((av_section_1[{0, 1}] == 13));
|
||||
CHECK((av_section_1[{1, 0}] == 22));
|
||||
CHECK((av_section_1[{2, 3}] == 35));
|
||||
|
||||
const strided_span<int, 2> av_section_2 = av_section_1.section({1, 2}, {2, 2});
|
||||
CHECK(!av_section_2.empty());
|
||||
CHECK((av_section_2[{0, 0}] == 24));
|
||||
CHECK((av_section_2[{0, 1}] == 25));
|
||||
CHECK((av_section_2[{1, 0}] == 34));
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("strided_span_constructors")
|
||||
{
|
||||
// Check stride constructor
|
||||
@@ -107,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}};
|
||||
@@ -119,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},
|
||||
@@ -129,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},
|
||||
@@ -149,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},
|
||||
@@ -170,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},
|
||||
@@ -271,6 +287,7 @@ TEST_CASE("strided_span_constructors")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("strided_span_slice")
|
||||
{
|
||||
std::vector<int> data(5 * 10);
|
||||
@@ -297,6 +314,7 @@ TEST_CASE("strided_span_slice")
|
||||
CHECK(sav[4][9] == 49);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("strided_span_column_major")
|
||||
{
|
||||
// strided_span may be used to accommodate more peculiar
|
||||
@@ -329,6 +347,7 @@ TEST_CASE("strided_span_column_major")
|
||||
CHECK((cm_sec[{2, 1}] == 15));
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("strided_span_bounds")
|
||||
{
|
||||
int arr[] = {0, 1, 2, 3};
|
||||
@@ -445,6 +464,7 @@ TEST_CASE("strided_span_bounds")
|
||||
#endif
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("strided_span_type_conversion")
|
||||
{
|
||||
int arr[] = {0, 1, 2, 3};
|
||||
@@ -542,6 +562,8 @@ TEST_CASE("strided_span_type_conversion")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("empty_strided_spans")
|
||||
{
|
||||
{
|
||||
@@ -549,6 +571,7 @@ TEST_CASE("empty_strided_spans")
|
||||
strided_span<int, 1> empty_sav{empty_av, {0, 1}};
|
||||
|
||||
CHECK(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
|
||||
CHECK(empty_sav.empty());
|
||||
CHECK_THROWS_AS(empty_sav[0], fail_fast);
|
||||
CHECK_THROWS_AS(empty_sav.begin()[0], fail_fast);
|
||||
CHECK_THROWS_AS(empty_sav.cbegin()[0], fail_fast);
|
||||
@@ -574,12 +597,14 @@ TEST_CASE("empty_strided_spans")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
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});
|
||||
@@ -599,6 +624,7 @@ void iterate_every_other_element(multi_span<int, dynamic_range> av)
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("strided_span_section_iteration")
|
||||
{
|
||||
int arr[8] = {4, 0, 5, 1, 6, 2, 7, 3};
|
||||
@@ -616,6 +642,11 @@ TEST_CASE("strided_span_section_iteration")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
TEST_CASE("dynamic_strided_span_section_iteration")
|
||||
{
|
||||
auto arr = new int[8];
|
||||
@@ -630,6 +661,9 @@ TEST_CASE("dynamic_strided_span_section_iteration")
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute // TODO: does not work
|
||||
void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
|
||||
{
|
||||
const int expected[6] = {2, 3, 10, 11, 18, 19};
|
||||
@@ -656,6 +690,9 @@ void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
TEST_CASE("strided_span_section_iteration_3d")
|
||||
{
|
||||
int arr[3][4][2]{};
|
||||
@@ -670,6 +707,11 @@ TEST_CASE("strided_span_section_iteration_3d")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
TEST_CASE("dynamic_strided_span_section_iteration_3d")
|
||||
{
|
||||
const auto height = 12, width = 2;
|
||||
@@ -702,6 +744,9 @@ TEST_CASE("dynamic_strided_span_section_iteration_3d")
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
TEST_CASE("strided_span_conversion")
|
||||
{
|
||||
// get an multi_span of 'c' values from the list of X's
|
||||
@@ -720,7 +765,7 @@ TEST_CASE("strided_span_conversion")
|
||||
auto d1 = narrow_cast<int>(sizeof(int)) * 12 / d2;
|
||||
|
||||
// convert to 4x12 array of bytes
|
||||
auto av = as_multi_span(as_bytes(as_multi_span(arr, 4)), dim(d1), dim(d2));
|
||||
auto av = as_multi_span(as_bytes(as_multi_span(&arr[0], 4)), dim(d1), dim(d2));
|
||||
|
||||
CHECK(av.bounds().index_bounds()[0] == 4);
|
||||
CHECK(av.bounds().index_bounds()[1] == 12);
|
||||
@@ -755,3 +800,7 @@ TEST_CASE("strided_span_conversion")
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,13 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
|
||||
#endif
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
|
||||
|
||||
#include <gsl/gsl_assert> // for Expects, fail_fast (ptr only)
|
||||
@@ -37,6 +44,8 @@ namespace generic
|
||||
{
|
||||
|
||||
template <typename CharT>
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute
|
||||
auto strlen(const CharT* s)
|
||||
{
|
||||
auto p = s;
|
||||
@@ -45,13 +54,15 @@ auto strlen(const CharT* s)
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
auto strnlen(const CharT* s, std::size_t n)
|
||||
{
|
||||
return std::find(s, s + n, CharT(0)) - s;
|
||||
return std::find(s, s + n, CharT{0}) - s;
|
||||
}
|
||||
|
||||
} // namespace generic
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestLiteralConstruction")
|
||||
{
|
||||
cwstring_span<> v = ensure_z(L"Hello");
|
||||
@@ -61,6 +72,7 @@ TEST_CASE("TestLiteralConstruction")
|
||||
wstring_span<> v2 = ensure0(L"Hello");
|
||||
#endif
|
||||
}
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
|
||||
TEST_CASE("TestConstructFromStdString")
|
||||
{
|
||||
@@ -69,6 +81,7 @@ TEST_CASE("TestConstructFromStdString")
|
||||
CHECK(v.length() == static_cast<cstring_span<>::index_type>(s.length()));
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestConstructFromStdVector")
|
||||
{
|
||||
std::vector<char> vec(5, 'h');
|
||||
@@ -76,6 +89,7 @@ TEST_CASE("TestConstructFromStdVector")
|
||||
CHECK(v.length() == static_cast<string_span<>::index_type>(vec.size()));
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestStackArrayConstruction")
|
||||
{
|
||||
wchar_t stack_string[] = L"Hello";
|
||||
@@ -101,6 +115,7 @@ TEST_CASE("TestStackArrayConstruction")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestConstructFromConstCharPointer")
|
||||
{
|
||||
const char* s = "Hello";
|
||||
@@ -108,6 +123,7 @@ TEST_CASE("TestConstructFromConstCharPointer")
|
||||
CHECK(v.length() == 5);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestConversionToConst")
|
||||
{
|
||||
char stack_string[] = "Hello";
|
||||
@@ -116,6 +132,7 @@ TEST_CASE("TestConversionToConst")
|
||||
CHECK(v.length() == v2.length());
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestConversionFromConst")
|
||||
{
|
||||
char stack_string[] = "Hello";
|
||||
@@ -127,6 +144,7 @@ TEST_CASE("TestConversionFromConst")
|
||||
#endif
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestToString")
|
||||
{
|
||||
auto s = gsl::to_string(cstring_span<>{});
|
||||
@@ -139,6 +157,7 @@ TEST_CASE("TestToString")
|
||||
CHECK(s2.length() == 5);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("TestToBasicString")
|
||||
{
|
||||
auto s = gsl::to_basic_string<char, std::char_traits<char>, ::std::allocator<char>>(
|
||||
@@ -152,6 +171,8 @@ TEST_CASE("TestToBasicString")
|
||||
CHECK(s2.length() == 5);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute
|
||||
TEST_CASE("EqualityAndImplicitConstructors")
|
||||
{
|
||||
{
|
||||
@@ -378,6 +399,8 @@ TEST_CASE("EqualityAndImplicitConstructors")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute
|
||||
TEST_CASE("ComparisonAndImplicitConstructors")
|
||||
{
|
||||
{
|
||||
@@ -448,6 +471,12 @@ TEST_CASE("ComparisonAndImplicitConstructors")
|
||||
CHECK(span >= string_span<>(vec));
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
TEST_CASE("ConstrutorsEnsureZ")
|
||||
{
|
||||
// remove z from literals
|
||||
@@ -478,6 +507,8 @@ TEST_CASE("ConstrutorsEnsureZ")
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute
|
||||
TEST_CASE("Constructors")
|
||||
{
|
||||
// creating cstring_span
|
||||
@@ -884,6 +915,8 @@ czstring_span<> CreateTempName(string_span<> span)
|
||||
return {ret};
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
TEST_CASE("zstring")
|
||||
{
|
||||
|
||||
@@ -904,7 +937,7 @@ TEST_CASE("zstring")
|
||||
char buf[1];
|
||||
buf[0] = 'a';
|
||||
|
||||
auto workaround_macro = [&]() { zstring_span<> zspan({buf, 1}); };
|
||||
auto workaround_macro = [&]() { const zstring_span<> zspan({buf, 1}); };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
@@ -938,6 +971,8 @@ cwzstring_span<> CreateTempNameW(wstring_span<> span)
|
||||
return {ret};
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
TEST_CASE("wzstring")
|
||||
{
|
||||
|
||||
@@ -958,7 +993,7 @@ TEST_CASE("wzstring")
|
||||
wchar_t buf[1];
|
||||
buf[0] = L'a';
|
||||
|
||||
const auto workaround_macro = [&]() { wzstring_span<> zspan({buf, 1}); };
|
||||
const auto workaround_macro = [&]() { const wzstring_span<> zspan({buf, 1}); };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
@@ -992,6 +1027,8 @@ cu16zstring_span<> CreateTempNameU16(u16string_span<> span)
|
||||
return {ret};
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
TEST_CASE("u16zstring")
|
||||
{
|
||||
|
||||
@@ -1012,7 +1049,7 @@ TEST_CASE("u16zstring")
|
||||
char16_t buf[1];
|
||||
buf[0] = u'a';
|
||||
|
||||
const auto workaround_macro = [&]() { u16zstring_span<> zspan({buf, 1}); };
|
||||
const auto workaround_macro = [&]() { const u16zstring_span<> zspan({buf, 1}); };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
@@ -1046,6 +1083,8 @@ cu32zstring_span<> CreateTempNameU32(u32string_span<> span)
|
||||
return {ret};
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
TEST_CASE("u32zstring")
|
||||
{
|
||||
|
||||
@@ -1066,7 +1105,7 @@ TEST_CASE("u32zstring")
|
||||
char32_t buf[1];
|
||||
buf[0] = u'a';
|
||||
|
||||
const auto workaround_macro = [&]() { u32zstring_span<> zspan({buf, 1}); };
|
||||
const auto workaround_macro = [&]() { const u32zstring_span<> zspan({buf, 1}); };
|
||||
CHECK_THROWS_AS(workaround_macro(), fail_fast);
|
||||
}
|
||||
|
||||
@@ -1090,6 +1129,8 @@ TEST_CASE("Issue305")
|
||||
CHECK(foo["bar"] == 1);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute
|
||||
TEST_CASE("char16_t type")
|
||||
{
|
||||
gsl::cu16string_span<> ss1 = gsl::ensure_z(u"abc");
|
||||
@@ -1131,6 +1172,8 @@ TEST_CASE("char16_t type")
|
||||
CHECK(ss8 != ss9);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute
|
||||
TEST_CASE("char32_t type")
|
||||
{
|
||||
gsl::cu32string_span<> ss1 = gsl::ensure_z(U"abc");
|
||||
@@ -1167,3 +1210,24 @@ TEST_CASE("char32_t type")
|
||||
CHECK(ss8 <= ss9);
|
||||
CHECK(ss8 != ss9);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("as_bytes")
|
||||
{
|
||||
cwzstring_span<> v(L"qwerty");
|
||||
const auto s = v.as_string_span();
|
||||
const auto bs = as_bytes(s);
|
||||
CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
|
||||
CHECK(bs.size() == s.size_bytes());
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("as_writeable_bytes")
|
||||
{
|
||||
wchar_t buf[]{L"qwerty"};
|
||||
wzstring_span<> v(buf);
|
||||
const auto s = v.as_string_span();
|
||||
const auto bs = as_writeable_bytes(s);
|
||||
CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
|
||||
CHECK(bs.size() == s.size_bytes());
|
||||
}
|
||||
|
||||
@@ -15,4 +15,13 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
// blanket turn off warnings from CppCoreCheck from catch
|
||||
// so people aren't annoyed by them when running the tool.
|
||||
#include <CodeAnalysis/Warnings.h>
|
||||
#pragma warning(disable : ALL_CODE_ANALYSIS_WARNINGS) // from catch
|
||||
#endif // _MSC_VER
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
+14
-1
@@ -14,6 +14,13 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
|
||||
#endif
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
|
||||
|
||||
#include <gsl/gsl_util> // for narrow, finally, narrow_cast, narrowing_e...
|
||||
@@ -73,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")
|
||||
{
|
||||
@@ -85,6 +92,7 @@ TEST_CASE("finally_function_ptr")
|
||||
CHECK(j == 1);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
TEST_CASE("narrow_cast")
|
||||
{
|
||||
int n = 120;
|
||||
@@ -96,6 +104,7 @@ TEST_CASE("narrow_cast")
|
||||
CHECK(uc == 44);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.5) // NO-FORMAT: attribute
|
||||
TEST_CASE("narrow")
|
||||
{
|
||||
int n = 120;
|
||||
@@ -117,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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user