forked from microsoft/GSL
Compare commits
289 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1999b48a51 | |||
| 3da256d03b | |||
| 601b55ea61 | |||
| 3a5b83db35 | |||
| 94d6a35726 | |||
| 14acdcd7a8 | |||
| 4eb554d7c2 | |||
| 70e1317ab6 | |||
| 61534ca3ad | |||
| afa2f3fd9a | |||
| fb1243d735 | |||
| 9f6a9a5807 | |||
| aeb65efada | |||
| b43855631a | |||
| 9cb376c050 | |||
| 7341c5d1b5 | |||
| 044849d6fa | |||
| 24dc828cbb | |||
| 8b8c25fa66 | |||
| f7aae78ff6 | |||
| efbce17ca4 | |||
| ffbfcc0a9f | |||
| 5ca02327c4 | |||
| 8d907dadfb | |||
| b7d9d754ac | |||
| 809aee2315 | |||
| 6ef56d73da | |||
| 2f9d873043 | |||
| f85166aa8b | |||
| b0b933b842 | |||
| bc7ea7aac7 | |||
| 611674d60b | |||
| 6e2398b524 | |||
| ff45864dba | |||
| 15dd17aa5b | |||
| c5dd0e6d40 | |||
| 01d206f4d8 | |||
| 226a854a97 | |||
| 5e21831494 | |||
| 04809f8559 | |||
| 511faf07d4 | |||
| 610c40333d | |||
| 30c068781f | |||
| f4c2292f9d | |||
| 0357a02921 | |||
| ddde9e153d | |||
| 6eab19d3c1 | |||
| f8bcb7d9eb | |||
| 9b3ac8d681 | |||
| 1dd1320c8b | |||
| d90fefea6d | |||
| 06adf557e9 | |||
| ce4d689f4f | |||
| b30524088a | |||
| 769f01900d | |||
| 4b643918a1 | |||
| a3b86971d9 | |||
| 4a6a7a095d | |||
| d2fdeda06e | |||
| fc54e0d89a | |||
| 5d54cada8e | |||
| 32e5fea6ac | |||
| 0f60c68ab9 | |||
| 60372b6468 | |||
| 89271b89c1 | |||
| ac37004274 | |||
| 3144082909 | |||
| c853017be3 | |||
| 94f43d4adf | |||
| 691a78c016 | |||
| 46603698ec | |||
| f4c608fd39 | |||
| 8ba6cb1074 | |||
| 8d6ca323fa | |||
| 6b01a0488b | |||
| b6b1e9c3cf | |||
| 67a7f7eaef | |||
| 41ae38f197 | |||
| 926aaeca56 | |||
| cce6ee563e | |||
| dd78144c2e | |||
| 849f14083a | |||
| 9c0c6b246c | |||
| 886fc95142 | |||
| ebe8844344 | |||
| d8fa68c4a5 | |||
| b81d6e40e1 | |||
| 377b2db537 | |||
| 202f332702 | |||
| 3f0d733466 | |||
| a49ff1b8df | |||
| 3b9d15f49f | |||
| 45f016d96f | |||
| ff5f7973a2 | |||
| 7fcc142ffc | |||
| 432be4852c | |||
| 5cf1610cfe | |||
| d7e1611137 | |||
| 5a1e4f3953 | |||
| 61c6ef8d42 | |||
| db2134485a | |||
| 0c6ce424ab | |||
| e9fea77bcb | |||
| 4ec7058b56 | |||
| 49e7ed1ebf | |||
| 592c28c6d1 | |||
| 877816faa4 | |||
| 2b7a8f1f2f | |||
| e0dc8095b3 | |||
| 81c2a1da15 | |||
| 827fafd32c | |||
| 24646c6f7c | |||
| f4ee6ee73b | |||
| 1815791af8 | |||
| d9d6ea8196 | |||
| 3e40b3fa4b | |||
| d0fdbdbffa | |||
| a430823b43 | |||
| 9bb900e834 | |||
| 17e372c155 | |||
| 5b8cf5422b | |||
| eabd9358f0 | |||
| ad71477183 | |||
| c31593dd0d | |||
| 8579165d0a | |||
| b4dd39615a | |||
| 6b23937baf | |||
| 6e20bfbba2 | |||
| 57dd11b20f | |||
| c61b1503ad | |||
| 7ba7f87475 | |||
| d976d41494 | |||
| 26a68c882b | |||
| 95730a80c4 | |||
| 72312b6474 | |||
| adc5fb0d14 | |||
| b29a18d3a8 | |||
| 5082a21b04 | |||
| 8edc449efb | |||
| 5caf336e02 | |||
| ecff9e623c | |||
| f828c55ec7 | |||
| 586c4e52f8 | |||
| e1a37d0430 | |||
| f0061bfa2a | |||
| 8655dc1583 | |||
| d768179ff6 | |||
| 81f56796a1 | |||
| 4cbd894812 | |||
| d08ff53e61 | |||
| 186f5d21c1 | |||
| cdedae897c | |||
| 888b9b9723 | |||
| 395a5bf550 | |||
| 96b6964b30 | |||
| a1e6fcbc46 | |||
| 2d878b94ee | |||
| b076205338 | |||
| 75936c3109 | |||
| cfd82aef4e | |||
| 3c0b38b777 | |||
| 2bc6a7cb12 | |||
| c7f9b3301a | |||
| 6eccc81c5f | |||
| 4b823b1651 | |||
| 3bf4106a44 | |||
| fa8a8117a0 | |||
| b186b6cc68 | |||
| b33bd4aebe | |||
| 0fefba89da | |||
| f04907c2f6 | |||
| 7786da91c9 | |||
| 40bc3c3f00 | |||
| 8577033f13 | |||
| 3539bd8008 | |||
| 17ad4495fb | |||
| 6c5c708877 | |||
| 0931262acf | |||
| 5099e8fa3e | |||
| 4f6f05d463 | |||
| ec05ecd6b1 | |||
| 0784866608 | |||
| 9a88262544 | |||
| b39a9732f8 | |||
| 87eaa45445 | |||
| 43aca2646b | |||
| 603b4671c1 | |||
| 2b10729386 | |||
| 7004ef506c | |||
| 5e0d76a1a7 | |||
| 7e99e76c97 | |||
| 263440f2a1 | |||
| a7759e6d3f | |||
| 128b4356ac | |||
| 8e481ebe19 | |||
| 4610f26b33 | |||
| d0e5daf441 | |||
| b213c89700 | |||
| 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 | |||
| 0551cad467 | |||
| b74b286d5e | |||
| 2a1ef25406 | |||
| 7d78b743e4 | |||
| 6418b5f4de | |||
| 6eeed739f1 | |||
| 9ff6e19ea9 | |||
| 7a7d025ffa | |||
| be3c3c2731 | |||
| 0f68d133fa | |||
| 88aca1caf3 | |||
| 2e4d0d7e22 | |||
| 5a7093f983 | |||
| b673375719 | |||
| c02ddae4bc | |||
| 2bf9f137a6 | |||
| 457fb25609 | |||
| 8428e083e4 | |||
| 1995e86d1a | |||
| 585f48ce55 | |||
| 86be2366c7 | |||
| 55aad0ab6d | |||
| 5016ce4a4d | |||
| 6241b3faa6 | |||
| 831584d947 | |||
| f1a2e91e4e | |||
| cea0d0ac2b | |||
| 6a75903c79 | |||
| b6c531f7c1 | |||
| 73022d1103 | |||
| f4a715816c | |||
| 1f76fbd168 | |||
| ffe8ffb452 | |||
| e3ffe1c5cb | |||
| e2b57d16f9 | |||
| 9e1645b990 | |||
| 0a31a14d09 | |||
| 030454e3e9 | |||
| d452c3b061 | |||
| 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:'
|
||||
|
||||
+430
-118
@@ -1,212 +1,519 @@
|
||||
# Based on https://github.com/ldionne/hana/blob/master/.travis.yml
|
||||
|
||||
language: cpp
|
||||
sudo: false
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
# Use Linux unless specified otherwise
|
||||
os: linux
|
||||
dist: trusty
|
||||
dist: bionic
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- ${TRAVIS_BUILD_DIR}/deps
|
||||
|
||||
matrix:
|
||||
stages:
|
||||
- name: Latest # build jobs to run first and always
|
||||
- name: Validation # run other jobs
|
||||
- name: Legacy # build with all other supported compilers
|
||||
|
||||
jobs:
|
||||
include:
|
||||
|
||||
##########################################################################
|
||||
# Clang on OSX
|
||||
# Travis seems to take longer to start OSX instances,
|
||||
# so leave this first for the overall build to be faster
|
||||
# Validate CMake configuration
|
||||
##########################################################################
|
||||
|
||||
# XCode 8.3
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Debug
|
||||
- name: CMake 3.1.3 - latest
|
||||
stage: Validation
|
||||
env: &CMAKE_VERSION_LIST
|
||||
- CMAKE_VERSION: '"3.17.0 3.16.5 3.15.7 3.14.7 3.13.5 3.12.4 3.11.4 3.10.3 3.9.6 3.8.2 3.7.2 3.6.3 3.5.2 3.4.3 3.3.2 3.2.3 3.1.3"'
|
||||
- GSL_CXX_STANDARD: 14
|
||||
addons: # Get latest release (candidate)
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: 'deb https://apt.kitware.com/ubuntu/ bionic main'
|
||||
key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc'
|
||||
- sourceline: 'deb https://apt.kitware.com/ubuntu/ bionic-rc main'
|
||||
packages:
|
||||
- cmake
|
||||
script:
|
||||
- |
|
||||
cd ./build
|
||||
( set -eu
|
||||
for CMAKE in ${CMAKE_path[@]}; do test_CMake_generate $CMAKE; done
|
||||
export CXX=clang++
|
||||
for CMAKE in ${CMAKE_path[@]}; do test_CMake_generate $CMAKE; done
|
||||
)
|
||||
|
||||
- name: CMake 3.2.3 - 3.17.0
|
||||
stage: Validation
|
||||
os: osx
|
||||
osx_image: xcode11.3
|
||||
env:
|
||||
- CMAKE_VERSION: '"3.17.0 3.16.5 3.15.7 3.14.7 3.13.5 3.12.4 3.11.4 3.10.3 3.9.6 3.8.2 3.7.2 3.6.3 3.5.2 3.4.3 3.3.2 3.2.3"'
|
||||
script:
|
||||
- |
|
||||
cd ./build
|
||||
( set -eu
|
||||
for CMAKE in ${CMAKE_path[@]}; do test_CMake_generate $CMAKE; done
|
||||
)
|
||||
|
||||
##########################################################################
|
||||
# AppleClang on OSX
|
||||
##########################################################################
|
||||
|
||||
# Xcode 8.3
|
||||
- name: AppleClang Xcode-8.3 C++14 Debug
|
||||
stage: Legacy
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode8.3
|
||||
compiler: clang
|
||||
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Release
|
||||
- name: AppleClang Xcode-8.3 C++14 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode8.3
|
||||
compiler: clang
|
||||
|
||||
# XCode 9.1
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Debug
|
||||
# Xcode 9.0 earliest C++17 support
|
||||
- name: AppleClang Xcode-9.0 C++17 Debug
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
os: osx
|
||||
osx_image: xcode9.1
|
||||
compiler: clang
|
||||
osx_image: xcode9 # AppleClang 9.1.0 same compiler in Xcode 9.0, 9.1 and 9.2
|
||||
- name: AppleClang Xcode-9.0 C++17 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
os: osx
|
||||
osx_image: xcode9
|
||||
- name: AppleClang Xcode-9.0 C++14 Debug
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode9
|
||||
- name: AppleClang Xcode-9.0 C++14 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode9
|
||||
|
||||
- env: COMPILER=clang++ BUILD_TYPE=Release
|
||||
# Xcode 9.4
|
||||
- name: AppleClang Xcode-9.4 C++14 Debug
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode9.1
|
||||
compiler: clang
|
||||
osx_image: xcode9.4 # AppleClang 9.1.0 same compiler as Xcode 9.3
|
||||
- name: AppleClang Xcode-9.4 C++14 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode9.4
|
||||
- name: AppleClang Xcode-9.4 C++17 Debug
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
os: osx
|
||||
osx_image: xcode9.4
|
||||
- name: AppleClang Xcode-9.4 C++17 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
os: osx
|
||||
osx_image: xcode9.4
|
||||
|
||||
# Xcode 10.1
|
||||
- name: AppleClang Xcode-10.1 C++14 Debug
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode10.1 # AppleClang 10.0.0 same compiler as Xcode 10.0
|
||||
- name: AppleClang Xcode-10.1 C++14 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode10.1
|
||||
- name: AppleClang Xcode-10.1 C++17 Debug
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
os: osx
|
||||
osx_image: xcode10.1
|
||||
- name: AppleClang Xcode-10.1 C++17 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
os: osx
|
||||
osx_image: xcode10.1
|
||||
|
||||
# Xcode 10.3
|
||||
- name: AppleClang Xcode-10.3 C++14 Debug
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode10.3 # AppleClang 10.0.1 same compiler as Xcode 10.2
|
||||
- name: AppleClang Xcode-10.3 C++14 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode10.3
|
||||
- name: AppleClang Xcode-10.3 C++17 Debug
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
os: osx
|
||||
osx_image: xcode10.3
|
||||
- name: AppleClang Xcode-10.3 C++17 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
os: osx
|
||||
osx_image: xcode10.3
|
||||
|
||||
# Xcode 11.3
|
||||
- name: AppleClang Xcode-11.3 C++17 Debug
|
||||
stage: Latest
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
os: osx
|
||||
osx_image: xcode11.3 # AppleClang 11.0.0 linker update / same as Xcode 11.2
|
||||
- name: AppleClang Xcode-11.3 C++17 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
os: osx
|
||||
osx_image: xcode11.3
|
||||
- name: AppleClang Xcode-11.3 C++14 Debug
|
||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode11.3
|
||||
- name: AppleClang Xcode-11.3 C++14 Release
|
||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
os: osx
|
||||
osx_image: xcode11.3
|
||||
|
||||
##########################################################################
|
||||
# Clang on Linux
|
||||
##########################################################################
|
||||
|
||||
# Clang 3.6
|
||||
- env: COMPILER=clang++-3.6 BUILD_TYPE=Debug
|
||||
- name: Clang-3.6 C++14 Debug
|
||||
stage: Legacy
|
||||
dist: xenial
|
||||
env: CXX=clang++-3.6 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang36
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.6
|
||||
|
||||
- env: COMPILER=clang++-3.6 BUILD_TYPE=Release
|
||||
- name: Clang-3.6 C++14 Release
|
||||
dist: xenial
|
||||
env: CXX=clang++-3.6 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang36
|
||||
|
||||
# Clang 3.7
|
||||
- env: COMPILER=clang++-3.7 BUILD_TYPE=Debug
|
||||
- name: Clang-3.7 C++14 Debug
|
||||
dist: xenial
|
||||
env: CXX=clang++-3.7 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang37
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.7
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.7
|
||||
|
||||
- env: COMPILER=clang++-3.7 BUILD_TYPE=Release
|
||||
- name: Clang-3.7 C++14 Release
|
||||
dist: xenial
|
||||
env: CXX=clang++-3.7 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang37
|
||||
|
||||
# Clang 3.8
|
||||
- env: COMPILER=clang++-3.8 BUILD_TYPE=Debug
|
||||
- name: Clang-3.8 C++14 Debug
|
||||
dist: xenial
|
||||
env: CXX=clang++-3.8 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang38
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- env: COMPILER=clang++-3.8 BUILD_TYPE=Release
|
||||
- name: Clang-3.8 C++14 Release
|
||||
dist: xenial
|
||||
env: CXX=clang++-3.8 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang38
|
||||
|
||||
# Clang 3.9
|
||||
- env: COMPILER=clang++-3.9 BUILD_TYPE=Debug
|
||||
- name: Clang-3.9 C++14 Debug
|
||||
env: CXX=clang++-3.9 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang39
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.9
|
||||
|
||||
- env: COMPILER=clang++-3.9 BUILD_TYPE=Release
|
||||
- name: Clang-3.9 C++14 Release
|
||||
env: CXX=clang++-3.9 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang39
|
||||
|
||||
# Clang 4.0
|
||||
- env: COMPILER=clang++-4.0 BUILD_TYPE=Debug
|
||||
- name: Clang-4.0 C++14 Debug
|
||||
env: CXX=clang++-4.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang40
|
||||
apt:
|
||||
packages:
|
||||
- clang-4.0
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
|
||||
- env: COMPILER=clang++-4.0 BUILD_TYPE=Release
|
||||
- name: Clang-4.0 C++14 Release
|
||||
env: CXX=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
|
||||
- name: Clang-5.0 C++14 Debug
|
||||
env: CXX=clang++-5.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang50
|
||||
apt:
|
||||
packages:
|
||||
- clang-5.0
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-4.0 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
- name: Clang-5.0 C++14 Release
|
||||
env: CXX=clang++-5.0 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang50
|
||||
- name: Clang-5.0 C++17 Debug
|
||||
env: CXX=clang++-5.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
addons: *clang50
|
||||
- name: Clang 5.0 C++17 Release
|
||||
env: CXX=clang++-5.0 BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
addons: *clang50
|
||||
|
||||
- env: COMPILER=clang++-5.0 BUILD_TYPE=Release
|
||||
addons: *clang40
|
||||
# Clang 6.0
|
||||
- name: Clang-6.0 C++14 Debug
|
||||
env: CXX=clang++-6.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang60
|
||||
apt:
|
||||
packages:
|
||||
- clang-6.0
|
||||
- name: Clang 6.0 C++14 Release
|
||||
env: CXX=clang++-6.0 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang60
|
||||
- name: Clang-6.0 C++17 Debug
|
||||
env: CXX=clang++-6.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
addons: *clang60
|
||||
- name: Clang 6.0 C++17 Release
|
||||
env: CXX=clang++-6.0 BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
addons: *clang60
|
||||
|
||||
# Clang 7 (default on Xenial and Bionic images)
|
||||
- name: Clang-7 C++14 Debug
|
||||
env: CXX=clang++ BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
- name: Clang-7 C++14 Release
|
||||
env: CXX=clang++ BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
- name: Clang-7 C++17 Debug
|
||||
env: CXX=clang++ BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
- name: Clang-7 C++17 Release
|
||||
env: CXX=clang++ BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
|
||||
# Clang 8
|
||||
- name: Clang-8 C++14 Debug
|
||||
env: CXX=clang++-8 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang8
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main'
|
||||
key_url: https://apt.llvm.org/llvm-snapshot.gpg.key
|
||||
packages:
|
||||
- clang-8
|
||||
- name: Clang-8 C++14 Release
|
||||
env: CXX=clang++-8 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang8
|
||||
- name: Clang-8 C++17 Debug
|
||||
env: CXX=clang++-8 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
addons: *clang8
|
||||
- name: Clang-8 C++17 Release
|
||||
env: CXX=clang++-8 BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
addons: *clang8
|
||||
|
||||
# Clang 9
|
||||
- name: Clang-9 C++14 Debug
|
||||
env: CXX=clang++-9 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang9
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
|
||||
key_url: https://apt.llvm.org/llvm-snapshot.gpg.key
|
||||
packages:
|
||||
- clang-9
|
||||
- name: Clang-9 C++14 Release
|
||||
env: CXX=clang++-9 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang9
|
||||
- name: Clang-9 C++17 Debug
|
||||
env: CXX=clang++-9 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
addons: *clang9
|
||||
- name: Clang-9 C++17 Release
|
||||
env: CXX=clang++-9 BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
addons: *clang9
|
||||
|
||||
# Clang 10
|
||||
- name: Clang-10 C++14 Debug
|
||||
stage: Latest
|
||||
env: CXX=clang++-10 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &clang10
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main'
|
||||
key_url: https://apt.llvm.org/llvm-snapshot.gpg.key
|
||||
packages:
|
||||
- clang-10
|
||||
- name: Clang-10 C++14 Release
|
||||
env: CXX=clang++-10 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *clang10
|
||||
- name: Clang-10 C++17 Debug
|
||||
env: CXX=clang++-10 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
addons: *clang10
|
||||
- name: Clang-10 C++17 Release
|
||||
env: CXX=clang++-10 BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
addons: *clang10
|
||||
|
||||
##########################################################################
|
||||
# GCC on Linux
|
||||
##########################################################################
|
||||
|
||||
# GCC 5
|
||||
- env: COMPILER=g++-5 BUILD_TYPE=Debug
|
||||
addons: &gcc5
|
||||
apt:
|
||||
packages: g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- env: COMPILER=g++-5 BUILD_TYPE=Release
|
||||
addons: *gcc5
|
||||
# GCC 5 (default on the Xenial image)
|
||||
- name: GCC-5 C++14 Debug
|
||||
stage: Legacy
|
||||
dist: xenial
|
||||
env: CXX=g++-5 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
- name: GCC-5 C++14 Release
|
||||
dist: xenial
|
||||
env: CXX=g++-5 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
|
||||
# GCC 6
|
||||
- env: COMPILER=g++-6 BUILD_TYPE=Debug
|
||||
- name: GCC-6 C++14 Debug
|
||||
env: CXX=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
|
||||
- name: GCC-6 C++14 Release
|
||||
env: CXX=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 (default on the Bionic image)
|
||||
- name: GCC-7 C++14 Debug
|
||||
env: CXX=g++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
- name: GCC-7 C++14 Release
|
||||
env: CXX=g++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
- name: GCC-7 C++17 Debug
|
||||
env: CXX=g++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
- name: GCC-7 C++17 Release
|
||||
env: CXX=g++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
|
||||
#- env: COMPILER=g++-7 BUILD_TYPE=Release
|
||||
# addons: *gcc7
|
||||
# GCC 8
|
||||
- name: GCC-8 C++14 Debug
|
||||
env: CXX=g++-8 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &gcc8
|
||||
apt:
|
||||
packages: g++-8
|
||||
- name: GCC-8 C++14 Release
|
||||
env: CXX=g++-8 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *gcc8
|
||||
- name: GCC-8 C++17 Debug
|
||||
env: CXX=g++-8 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
addons: *gcc8
|
||||
- name: GCC-8 C++17 Release
|
||||
env: CXX=g++-8 BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
addons: *gcc8
|
||||
|
||||
# GCC 9
|
||||
- name: GCC-9 C++14 Debug
|
||||
stage: Latest
|
||||
env: CXX=g++-9 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
||||
addons: &gcc9
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: ppa:ubuntu-toolchain-r/test
|
||||
packages:
|
||||
- g++-9
|
||||
- name: GCC-9 C++14 Release
|
||||
env: CXX=g++-9 BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
||||
addons: *gcc9
|
||||
- name: GCC-9 C++17 Debug
|
||||
env: CXX=g++-9 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
||||
addons: *gcc9
|
||||
- name: GCC-9 C++17 Release
|
||||
env: CXX=g++-9 BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
||||
addons: *gcc9
|
||||
|
||||
before_install:
|
||||
- |
|
||||
# Configuration
|
||||
JOBS=2 # Travis machines have 2 cores
|
||||
# Dependencies required by the CI (cached directory)
|
||||
DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
|
||||
- |
|
||||
# Setup
|
||||
mkdir -p "${DEPS_DIR:?}" && cd "${DEPS_DIR:?}"
|
||||
mkdir -p ~/tools && cd ~/tools
|
||||
if [[ ${TRAVIS_OS_NAME:?} == "osx" ]]; then
|
||||
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
|
||||
fi
|
||||
- |
|
||||
# Helper functions
|
||||
# usage: if [[ $(check_url '<url>') ]]; then ...
|
||||
function check_url {( set +e
|
||||
if [[ "$1" =~ 'github.com' ]]; then # check for first byte
|
||||
if curl --fail --silent --output /dev/null --connect-timeout 12 --range 0-0 "$1"
|
||||
then echo true; fi
|
||||
else # request head
|
||||
if curl --fail --silent --output /dev/null --connect-timeout 12 --head "$1"
|
||||
then echo true; fi
|
||||
fi
|
||||
return
|
||||
)}
|
||||
|
||||
install:
|
||||
# Set the ${CXX} variable properly
|
||||
- export CXX=${COMPILER}
|
||||
- ${CXX} --version
|
||||
|
||||
# Dependencies required by the CI are installed in ${TRAVIS_BUILD_DIR}/deps/
|
||||
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
|
||||
- mkdir -p "${DEPS_DIR}"
|
||||
- cd "${DEPS_DIR}"
|
||||
|
||||
# Travis machines have 2 cores
|
||||
- JOBS=2
|
||||
|
||||
############################################################################
|
||||
# Install a recent CMake (unless already installed on OS X)
|
||||
# Install a different CMake version (or several)
|
||||
############################################################################
|
||||
- CMAKE_VERSION=3.7.2
|
||||
- |
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||
CMAKE_URL="https://cmake.org/files/v${CMAKE_VERSION%.[0-9]}/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz"
|
||||
mkdir cmake && travis_retry wget --no-check-certificate -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
|
||||
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
||||
else
|
||||
brew install cmake || brew upgrade cmake
|
||||
# Install CMake versions
|
||||
( set -euo pipefail
|
||||
if [[ ${CMAKE_VERSION:-} ]]; then
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||
OS="Linux"; EXT="sh"
|
||||
if [[ ! ("${CMAKE_VERSION:-}" =~ .+[' '].+) ]]; then
|
||||
# Single entry -> default CMake version
|
||||
CMAKE_DEFAULT_DIR="/usr/local"
|
||||
fi
|
||||
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then OS="Darwin"; EXT="tar.gz"
|
||||
else echo "CMake install not supported for this OS."; exit 1
|
||||
fi
|
||||
CMAKE_INSTALLER="install-cmake.${EXT}"
|
||||
fi
|
||||
for VERSION in ${CMAKE_VERSION:-}; do
|
||||
CMAKE_URL="https://github.com/Kitware/CMake/releases/download/v${VERSION}/cmake-${VERSION}-${OS}-x86_64.${EXT}"
|
||||
if [[ $(check_url "$CMAKE_URL") ]]; then
|
||||
curl -sSL ${CMAKE_URL} -o ${CMAKE_INSTALLER}
|
||||
CMAKE_DIR="${CMAKE_DEFAULT_DIR:-"${HOME}/tools/cmake-${VERSION}"}"
|
||||
mkdir -p ${CMAKE_DIR}
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||
chmod +x ${CMAKE_INSTALLER}
|
||||
sudo ./${CMAKE_INSTALLER} --prefix=${CMAKE_DIR} --skip-license
|
||||
else # OSX
|
||||
mkdir -p ./CMake_tmp
|
||||
tar --extract --gzip --file=${CMAKE_INSTALLER} --directory=./CMake_tmp
|
||||
mv ./CMake_tmp/*/CMake.app/Contents/* ${CMAKE_DIR}
|
||||
fi
|
||||
rm --recursive --force ./CMake_tmp ${CMAKE_INSTALLER}
|
||||
else echo 'Invalid url!'; echo "Version: ${VERSION}"
|
||||
fi
|
||||
done
|
||||
)
|
||||
if [[ ${CMAKE_VERSION:-} && "${TRAVIS_OS_NAME:?}" == "osx" && ! ("${CMAKE_VERSION:-}" =~ .+[' '].+) ]]
|
||||
then # Single entry -> default CMake version
|
||||
export PATH=${HOME}/tools/cmake-${CMAKE_VERSION:?}/bin:$PATH
|
||||
fi
|
||||
CMAKE_path=("cmake") # start with installed CMake version
|
||||
for VERSION in ${CMAKE_VERSION:-}; do
|
||||
tmp_path="$HOME/tools/cmake-${VERSION:?}/bin/cmake"
|
||||
if [[ -x "$(command -v ${tmp_path:?})" ]]; then CMAKE_path+=("${tmp_path:?}"); fi
|
||||
done
|
||||
function test_CMake_generate {
|
||||
# $1: cmake or full path to cmake
|
||||
shopt -s extglob
|
||||
if [[ "$1" == "cmake" || -x "$(command -v $1)" && "$1" =~ .*cmake$ ]]; then
|
||||
echo "----------------"
|
||||
$1 --version
|
||||
echo "Configuration = ${BUILD_TYPE:-Debug}"
|
||||
$1 -DCMAKE_BUILD_TYPE=${BUILD_TYPE:-Debug} ${CMAKE_GEN_FLAGS[@]:?} ..
|
||||
rm -rf !(tests/googletest-*)
|
||||
if [[ ! ${BUILD_TYPE:-} ]]; then echo "" && echo "Configuration = Release"
|
||||
$1 -DCMAKE_BUILD_TYPE=Release ${CMAKE_GEN_FLAGS[@]:?} ..
|
||||
rm -rf !(tests/googletest-*)
|
||||
fi
|
||||
else echo "Non existing command: $1"
|
||||
fi
|
||||
}
|
||||
- |
|
||||
# CMake wrapper (Trusty, Xenial & Bionic); restore default behaviour.
|
||||
if [[ "${TRAVIS_OS_NAME:?}" == "linux" &&
|
||||
"$(lsb_release --codename)" =~ (trusty|xenial|bionic)$ ]]
|
||||
then
|
||||
if [[ -x $(command -v /usr/local/bin/cmake) ]]; then
|
||||
function cmake { command /usr/local/bin/cmake $@; }
|
||||
elif [[ -x $(command -v /usr/bin/cmake) ]]; then
|
||||
function cmake { command /usr/bin/cmake $@; }
|
||||
fi
|
||||
fi
|
||||
- cmake --version
|
||||
|
||||
############################################################################
|
||||
# [linux]: Install the right version of libc++
|
||||
# Based on https://github.com/ldionne/hana/blob/master/.travis.yml
|
||||
############################################################################
|
||||
- |
|
||||
LLVM_INSTALL=${DEPS_DIR}/llvm/install
|
||||
LLVM_INSTALL=${DEPS_DIR:?}/llvm/install
|
||||
# if in linux and compiler clang and llvm not installed
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" && "${CXX%%+*}" == "clang" && -n "$(ls -A ${LLVM_INSTALL})" ]]; then
|
||||
if [[ "${TRAVIS_OS_NAME:?}" == "linux" && "${CXX%%+*}" == "clang" && -n "$(ls -A ${LLVM_INSTALL:?})" ]]; then
|
||||
if [[ "${CXX}" == "clang++-3.6" ]]; then LLVM_VERSION="3.6.2";
|
||||
elif [[ "${CXX}" == "clang++-3.7" ]]; then LLVM_VERSION="3.7.1";
|
||||
elif [[ "${CXX}" == "clang++-3.8" ]]; then LLVM_VERSION="3.8.1";
|
||||
@@ -228,12 +535,17 @@ install:
|
||||
fi
|
||||
|
||||
before_script:
|
||||
# have CMake to generate build files
|
||||
- cd "${TRAVIS_BUILD_DIR}"
|
||||
- mkdir build && cd build
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
|
||||
- |
|
||||
cd "${TRAVIS_BUILD_DIR:?}"
|
||||
mkdir build && cd build
|
||||
if [[ ${GSL_CXX_STANDARD:-} ]]; then
|
||||
CMAKE_GEN_FLAGS=("-DGSL_CXX_STANDARD=$GSL_CXX_STANDARD")
|
||||
fi
|
||||
CMAKE_GEN_FLAGS+=("-Wdev -Werror=dev --warn-uninitialized")
|
||||
|
||||
script:
|
||||
# generate build files
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE:?} ${CMAKE_GEN_FLAGS[@]:?}
|
||||
# build and run tests
|
||||
- cmake --build . -- -j${JOBS}
|
||||
- ctest --output-on-failure -j${JOBS}
|
||||
|
||||
+56
-27
@@ -1,10 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.1.3...3.16)
|
||||
|
||||
project(GSL CXX)
|
||||
|
||||
include(ExternalProject)
|
||||
find_package(Git)
|
||||
|
||||
# Use GNUInstallDirs to provide the right locations on all platforms
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# creates a library GSL which is an interface (header files only)
|
||||
add_library(GSL INTERFACE)
|
||||
|
||||
@@ -14,22 +17,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,33 +48,53 @@ 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>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
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
|
||||
target_include_directories(GSL SYSTEM INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
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
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis>
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(TARGETS GSL EXPORT Microsoft.GSLConfig)
|
||||
install(
|
||||
DIRECTORY include/gsl
|
||||
DESTINATION include
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
# Make library importable by other projects
|
||||
install(EXPORT Microsoft.GSLConfig NAMESPACE Microsoft.GSL:: DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/Microsoft.GSL)
|
||||
export(TARGETS GSL NAMESPACE Microsoft.GSL:: FILE Microsoft.GSLConfig.cmake)
|
||||
|
||||
# Add Microsoft.GSL::GSL alias for GSL so that dependents can be agnostic about
|
||||
# whether GSL was added via `add_subdirectory` or `find_package`
|
||||
add_library(Microsoft.GSL::GSL ALIAS GSL)
|
||||
|
||||
option(GSL_TEST "Generate tests." ${GSL_STANDALONE_PROJECT})
|
||||
if (GSL_TEST)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -18,7 +18,7 @@ other platforms. Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for more inform
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
# Usage of Third Party Libraries
|
||||
This project makes use of the [Catch](https://github.com/philsquared/catch) testing library. Please see the [ThirdPartyNotices.txt](./ThirdPartyNotices.txt) file for details regarding the licensing of Catch.
|
||||
This project makes use of the [Google Test](https://github.com/google/googletest) testing library. Please see the [ThirdPartyNotices.txt](./ThirdPartyNotices.txt) file for details regarding the licensing of Google Test.
|
||||
|
||||
# Quick Start
|
||||
## Supported Platforms
|
||||
@@ -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 (3.2.3 for AppleClang) 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`.
|
||||
|
||||
@@ -69,6 +77,18 @@ These steps assume the source code of this repository has been cloned into a dir
|
||||
|
||||
All tests should pass - indicating your platform is fully supported and you are ready to use the GSL types!
|
||||
|
||||
## Building GSL - Using vcpkg
|
||||
|
||||
You can download and install GSL using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
vcpkg install ms-gsl
|
||||
|
||||
The GSL port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
## Using the libraries
|
||||
As the types are entirely implemented inline in headers, there are no linking requirements.
|
||||
|
||||
@@ -89,5 +109,14 @@ Include the library using:
|
||||
|
||||
#include <gsl/gsl>
|
||||
|
||||
## Usage in CMake
|
||||
|
||||
The library provides a Config file for CMake, once installed it can be found via
|
||||
|
||||
find_package(Microsoft.GSL CONFIG)
|
||||
|
||||
Which, when successful, will add library target called `Microsoft.GSL::GSL` which you can use via the usual
|
||||
`target_link_libraries` mechanism.
|
||||
|
||||
## Debugging visualization support
|
||||
For Visual Studio users, the file [GSL.natvis](./GSL.natvis) in the root directory of the repository can be added to your project if you would like more helpful visualization of GSL types in the Visual Studio debugger than would be offered by default.
|
||||
|
||||
+33
-31
@@ -2,38 +2,40 @@
|
||||
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.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Software: Google Test
|
||||
Owner: Google Inc.
|
||||
Source URL: github.com/google/googletest
|
||||
License: BSD 3 - Clause
|
||||
Text:
|
||||
Copyright 2008, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
1. Catch (https://github.com/philsquared/Catch)
|
||||
|
||||
|
||||
%% Catch NOTICES, INFORMATION, AND LICENSE BEGIN HERE
|
||||
=========================================
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
=========================================
|
||||
END OF Catch NOTICES, INFORMATION, AND LICENSE
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
+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,17 +31,14 @@
|
||||
#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
|
||||
{
|
||||
|
||||
template <class SrcElementType, std::ptrdiff_t SrcExtent, class DestElementType,
|
||||
std::ptrdiff_t DestExtent>
|
||||
// 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::size_t SrcExtent, class DestElementType,
|
||||
std::size_t DestExtent>
|
||||
void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest)
|
||||
{
|
||||
static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value,
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
+45
-57
@@ -17,29 +17,40 @@
|
||||
#ifndef GSL_CONTRACTS_H
|
||||
#define GSL_CONTRACTS_H
|
||||
|
||||
#include <exception>
|
||||
#include <stdexcept> // for logic_error
|
||||
|
||||
//
|
||||
// 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
|
||||
#if defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
|
||||
|
||||
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
|
||||
#endif
|
||||
#include <intrin.h>
|
||||
#define RANGE_CHECKS_FAILURE 0
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Winvalid-noreturn"
|
||||
#endif // defined(__clang__)
|
||||
|
||||
#else // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
|
||||
|
||||
#include <exception>
|
||||
|
||||
#endif // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
|
||||
|
||||
//
|
||||
// There are three configuration options for this GSL implementation's behavior
|
||||
// when pre/post conditions on the GSL types are violated:
|
||||
// make suppress attributes parse for some compilers
|
||||
// Hopefully temporary until suppression standardization occurs
|
||||
//
|
||||
// 1. GSL_TERMINATE_ON_CONTRACT_VIOLATION: std::terminate will be called (default)
|
||||
// 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown
|
||||
// 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens
|
||||
//
|
||||
#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) || defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) || \
|
||||
defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
|
||||
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION
|
||||
#endif
|
||||
#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__
|
||||
|
||||
#define GSL_STRINGIFY_DETAIL(x) #x
|
||||
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
|
||||
@@ -47,10 +58,12 @@
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#else
|
||||
|
||||
#define GSL_LIKELY(x) (!!(x))
|
||||
#define GSL_UNLIKELY(x) (!!(x))
|
||||
#endif
|
||||
#endif // defined(__clang__) || defined(__GNUC__)
|
||||
|
||||
//
|
||||
// GSL_ASSUME(cond)
|
||||
@@ -72,24 +85,28 @@
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
struct fail_fast : public std::logic_error
|
||||
{
|
||||
explicit fail_fast(char const* const message) : std::logic_error(message) {}
|
||||
};
|
||||
|
||||
namespace details
|
||||
{
|
||||
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
|
||||
|
||||
typedef void (*terminate_handler)();
|
||||
typedef void(__cdecl* terminate_handler)();
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
[[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;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
|
||||
|
||||
[[noreturn]] inline void terminate() noexcept
|
||||
{
|
||||
@@ -97,49 +114,20 @@ namespace details
|
||||
(*gsl::details::get_terminate_handler())();
|
||||
#else
|
||||
std::terminate();
|
||||
#endif
|
||||
#endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
|
||||
}
|
||||
|
||||
#if defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
|
||||
|
||||
template <typename Exception>
|
||||
[[noreturn]] void throw_exception(Exception&&)
|
||||
{
|
||||
gsl::details::terminate();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <typename Exception>
|
||||
[[noreturn]] void throw_exception(Exception&& exception)
|
||||
{
|
||||
throw exception;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace details
|
||||
} // namespace gsl
|
||||
|
||||
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
|
||||
|
||||
#define GSL_CONTRACT_CHECK(type, cond) \
|
||||
(GSL_LIKELY(cond) ? static_cast<void>(0) \
|
||||
: gsl::details::throw_exception(gsl::fail_fast( \
|
||||
"GSL: " type " failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__))))
|
||||
|
||||
#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
|
||||
|
||||
#define GSL_CONTRACT_CHECK(type, cond) \
|
||||
(GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate())
|
||||
|
||||
#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
|
||||
|
||||
#define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond)
|
||||
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
+47
-12
@@ -17,51 +17,84 @@
|
||||
#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__
|
||||
|
||||
#if GSL_USE_STD_BYTE
|
||||
#include <cstddef>
|
||||
#endif
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
#if GSL_USE_STD_BYTE
|
||||
|
||||
|
||||
using std::byte;
|
||||
using std::to_integer;
|
||||
|
||||
@@ -69,7 +102,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 +179,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);
|
||||
|
||||
+32
-18
@@ -21,12 +21,11 @@
|
||||
|
||||
#include <array>
|
||||
#include <cstddef> // for ptrdiff_t, size_t
|
||||
#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 +33,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 +58,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 +72,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 +90,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,16 +107,21 @@ 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());
|
||||
if (static_cast<U>(t) != u) throw narrowing_error{};
|
||||
if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{})))
|
||||
gsl::details::throw_exception(narrowing_error());
|
||||
throw narrowing_error{};
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -120,21 +129,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 +157,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")
|
||||
|
||||
+500
-455
File diff suppressed because it is too large
Load Diff
+119
-5
@@ -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,12 +77,17 @@ 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())
|
||||
{
|
||||
}
|
||||
|
||||
not_null(not_null&& other) = default;
|
||||
not_null(const not_null& other) = default;
|
||||
not_null& operator=(const not_null& other) = default;
|
||||
|
||||
@@ -94,7 +99,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 +118,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 +188,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
|
||||
|
||||
+396
-351
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,198 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GSL_SPAN_EXT_H
|
||||
#define GSL_SPAN_EXT_H
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// File: span_ext
|
||||
// Purpose: continue offering features that have been cut from the official
|
||||
// implementation of span.
|
||||
// While modernizing gsl::span a number of features needed to be removed to
|
||||
// be compliant with the design of std::span
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include <gsl/gsl_util> // for narrow_cast, narrow
|
||||
#include <gsl/span> // for span
|
||||
|
||||
#include <algorithm> // for lexicographical_compare
|
||||
#include <cstddef> // for ptrdiff_t, size_t
|
||||
#include <utility>
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
|
||||
// [span.comparison], span comparison operators
|
||||
template <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent>
|
||||
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::size_t Extent>
|
||||
constexpr bool operator!=(span<ElementType, Extent> l, span<ElementType, Extent> r)
|
||||
{
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t Extent>
|
||||
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::size_t Extent>
|
||||
constexpr bool operator<=(span<ElementType, Extent> l, span<ElementType, Extent> r)
|
||||
{
|
||||
return !(l > r);
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr bool operator>(span<ElementType, Extent> l, span<ElementType, Extent> r)
|
||||
{
|
||||
return r < l;
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr bool operator>=(span<ElementType, Extent> l, span<ElementType, Extent> r)
|
||||
{
|
||||
return !(l < r);
|
||||
}
|
||||
|
||||
//
|
||||
// make_span() - Utility functions for creating spans
|
||||
//
|
||||
template <class ElementType>
|
||||
constexpr span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::size_type count)
|
||||
{
|
||||
return span<ElementType>(ptr, count);
|
||||
}
|
||||
|
||||
template <class ElementType>
|
||||
constexpr span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem)
|
||||
{
|
||||
return span<ElementType>(firstElem, lastElem);
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t N>
|
||||
constexpr span<ElementType, N> make_span(ElementType (&arr)[N]) noexcept
|
||||
{
|
||||
return span<ElementType, N>(arr);
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
constexpr span<typename Container::value_type> make_span(Container& cont)
|
||||
{
|
||||
return span<typename Container::value_type>(cont);
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
constexpr span<const typename Container::value_type> make_span(const Container& cont)
|
||||
{
|
||||
return span<const typename Container::value_type>(cont);
|
||||
}
|
||||
|
||||
template <class Ptr>
|
||||
constexpr span<typename Ptr::element_type> make_span(Ptr& cont, std::size_t count)
|
||||
{
|
||||
return span<typename Ptr::element_type>(cont, count);
|
||||
}
|
||||
|
||||
template <class Ptr>
|
||||
constexpr span<typename Ptr::element_type> make_span(Ptr& cont)
|
||||
{
|
||||
return span<typename Ptr::element_type>(cont);
|
||||
}
|
||||
|
||||
// Specialization of gsl::at for span
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr ElementType& at(span<ElementType, Extent> s, index i)
|
||||
{
|
||||
// No bounds checking here because it is done in span::operator[] called below
|
||||
Ensures(i >= 0);
|
||||
return s[narrow_cast<std::size_t>(i)];
|
||||
}
|
||||
|
||||
// [span.obs] Free observer functions
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr std::ptrdiff_t ssize(const span<ElementType, Extent>& s) noexcept
|
||||
{
|
||||
return static_cast<std::ptrdiff_t>(s.size());
|
||||
}
|
||||
|
||||
// [span.iter] Free functions for begin/end functions
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr typename span<ElementType, Extent>::iterator
|
||||
begin(const span<ElementType, Extent>& s) noexcept
|
||||
{
|
||||
return s.begin();
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t Extent = dynamic_extent>
|
||||
constexpr typename span<ElementType, Extent>::iterator
|
||||
end(const span<ElementType, Extent>& s) noexcept
|
||||
{
|
||||
return s.end();
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr typename span<ElementType, Extent>::reverse_iterator
|
||||
rbegin(const span<ElementType, Extent>& s) noexcept
|
||||
{
|
||||
return s.rbegin();
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr typename span<ElementType, Extent>::reverse_iterator
|
||||
rend(const span<ElementType, Extent>& s) noexcept
|
||||
{
|
||||
return s.rend();
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr typename span<ElementType, Extent>::iterator
|
||||
cbegin(const span<ElementType, Extent>& s) noexcept
|
||||
{
|
||||
return s.begin();
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t Extent = dynamic_extent>
|
||||
constexpr typename span<ElementType, Extent>::iterator
|
||||
cend(const span<ElementType, Extent>& s) noexcept
|
||||
{
|
||||
return s.end();
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr typename span<ElementType, Extent>::reverse_iterator
|
||||
crbegin(const span<ElementType, Extent>& s) noexcept
|
||||
{
|
||||
return s.rbegin();
|
||||
}
|
||||
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr typename span<ElementType, Extent>::reverse_iterator
|
||||
crend(const span<ElementType, Extent>& s) noexcept
|
||||
{
|
||||
return s.rend();
|
||||
}
|
||||
|
||||
} // namespace gsl
|
||||
|
||||
#endif // GSL_SPAN_EXT_H
|
||||
+716
-715
File diff suppressed because it is too large
Load Diff
+173
-70
@@ -1,41 +1,86 @@
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
cmake_minimum_required(VERSION 3.0.2)
|
||||
|
||||
project(GSLTests CXX)
|
||||
|
||||
# will make visual studio generated project group files
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
list(APPEND CATCH_CMAKE_ARGS
|
||||
"-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/external"
|
||||
"-DNO_SELFTEST=true"
|
||||
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||
RESULT_VARIABLE result
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download
|
||||
)
|
||||
if(result)
|
||||
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
RESULT_VARIABLE result
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download
|
||||
)
|
||||
if(result)
|
||||
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
|
||||
endif()
|
||||
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
add_subdirectory(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/googletest-src
|
||||
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
if(GIT_FOUND)
|
||||
# add catch
|
||||
ExternalProject_Add(
|
||||
catch
|
||||
PREFIX ${CMAKE_BINARY_DIR}/catch
|
||||
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
||||
GIT_TAG v2.0.1
|
||||
CMAKE_ARGS ${CATCH_CMAKE_ARGS}
|
||||
LOG_DOWNLOAD 1
|
||||
UPDATE_DISCONNECTED 1
|
||||
)
|
||||
else()
|
||||
# assume catch is installed in a system directory
|
||||
add_custom_target(catch)
|
||||
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:MSVC>:
|
||||
/wd4996 # Use of function or classes marked [[deprecated]]
|
||||
/wd26409 # CppCoreCheck - GTest
|
||||
/wd26426 # CppCoreCheck - GTest
|
||||
/wd26440 # CppCoreCheck - GTest
|
||||
/wd26446 # CppCoreCheck - prefer gsl::at()
|
||||
/wd26472 # CppCoreCheck - use gsl::narrow(_cast)
|
||||
/wd26481 # CppCoreCheck - use span instead of pointer arithmetic
|
||||
$<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,1920>: # VS2015
|
||||
/wd4189 # variable is initialized but not referenced
|
||||
$<$<NOT:$<CONFIG:Debug>>: # Release, RelWithDebInfo
|
||||
/wd4702 # Unreachable code
|
||||
>
|
||||
>
|
||||
>
|
||||
$<$<CXX_COMPILER_ID:Clang>:
|
||||
-Weverything
|
||||
-Wno-c++98-compat
|
||||
-Wno-c++98-compat-pedantic
|
||||
-Wno-covered-switch-default # GTest
|
||||
-Wno-deprecated-declarations # Allow tests for [[deprecated]] elements
|
||||
-Wno-global-constructors # GTest
|
||||
-Wno-language-extension-token # GTest gtest-port.h
|
||||
-Wno-missing-braces
|
||||
-Wno-missing-prototypes
|
||||
-Wno-shift-sign-overflow # GTest gtest-port.h
|
||||
-Wno-undef # GTest
|
||||
-Wno-used-but-marked-unused # GTest EXPECT_DEATH
|
||||
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
|
||||
-Wno-unused-member-function
|
||||
-Wno-unused-variable
|
||||
>
|
||||
>
|
||||
)
|
||||
else()
|
||||
target_compile_options(gsl_tests_config INTERFACE
|
||||
-fno-strict-aliasing
|
||||
-Wall
|
||||
-Wcast-align
|
||||
@@ -43,53 +88,80 @@ 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
|
||||
>
|
||||
-Wno-deprecated-declarations # Allow tests for [[deprecated]] elements
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
-Weverything
|
||||
-Wno-c++98-compat
|
||||
-Wno-c++98-compat-pedantic
|
||||
-Wno-missing-braces
|
||||
-Wno-covered-switch-default # GTest
|
||||
-Wno-global-constructors # GTest
|
||||
-Wno-missing-prototypes
|
||||
-Wno-padded
|
||||
-Wno-unknown-attributes
|
||||
-Wno-used-but-marked-unused # GTest EXPECT_DEATH
|
||||
-Wno-weak-vtables
|
||||
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
|
||||
-Wno-unused-member-function
|
||||
-Wno-unused-variable
|
||||
>
|
||||
>
|
||||
$<$<CXX_COMPILER_ID:Clang>:
|
||||
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,4.99>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
|
||||
$<$<EQUAL:${GSL_CXX_STANDARD},17>:-Wno-undefined-func-template>
|
||||
>
|
||||
>
|
||||
$<$<CXX_COMPILER_ID:AppleClang>:
|
||||
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,9.1>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,10>>:
|
||||
$<$<EQUAL:${GSL_CXX_STANDARD},17>:-Wno-undefined-func-template>
|
||||
>
|
||||
>
|
||||
$<$<CXX_COMPILER_ID:GNU>:
|
||||
-Wdouble-promotion # float implicit to double
|
||||
-Wlogical-op # suspicious uses of logical operators
|
||||
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
|
||||
-Wduplicated-cond # duplicated if-else conditions
|
||||
-Wmisleading-indentation
|
||||
-Wnull-dereference
|
||||
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
|
||||
-Wno-unused-variable
|
||||
>
|
||||
>
|
||||
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7>>:
|
||||
-Wduplicated-branches # identical if-else branches
|
||||
>
|
||||
>
|
||||
)
|
||||
endif(MSVC)
|
||||
|
||||
# for tests to find the gtest header
|
||||
target_include_directories(gsl_tests_config SYSTEM INTERFACE
|
||||
googletest/googletest/include
|
||||
)
|
||||
|
||||
# for tests to find the catch header
|
||||
target_include_directories(gsl_tests_config INTERFACE
|
||||
${CMAKE_BINARY_DIR}/external/include
|
||||
)
|
||||
|
||||
# set definitions for tests
|
||||
target_compile_definitions(gsl_tests_config INTERFACE
|
||||
GSL_THROW_ON_CONTRACT_VIOLATION
|
||||
)
|
||||
|
||||
# create the main executable for each test. this reduces the compile time
|
||||
# of each test by pre-compiling catch.
|
||||
add_library(test_catch STATIC test.cpp)
|
||||
target_link_libraries(test_catch
|
||||
GSL
|
||||
gsl_tests_config
|
||||
)
|
||||
add_dependencies(test_catch catch)
|
||||
set_property(TARGET test_catch PROPERTY FOLDER "GSL_tests")
|
||||
set_property(TARGET PROPERTY FOLDER "GSL_tests")
|
||||
|
||||
function(add_gsl_test name)
|
||||
add_executable(${name} ${name}.cpp)
|
||||
target_link_libraries(${name}
|
||||
GSL
|
||||
test_catch
|
||||
gsl_tests_config
|
||||
gtest_main
|
||||
)
|
||||
add_dependencies(${name} catch)
|
||||
add_test(
|
||||
${name}
|
||||
${name}
|
||||
${name}
|
||||
${name}
|
||||
)
|
||||
# group all tests under GSL_tests
|
||||
set_property(TARGET ${name} PROPERTY FOLDER "GSL_tests")
|
||||
endfunction()
|
||||
|
||||
add_gsl_test(span_tests)
|
||||
add_gsl_test(span_ext_tests)
|
||||
add_gsl_test(span_compatibility_tests)
|
||||
add_gsl_test(multi_span_tests)
|
||||
add_gsl_test(strided_span_tests)
|
||||
add_gsl_test(string_span_tests)
|
||||
@@ -101,6 +173,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,43 +187,74 @@ 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 # disable exceptions in the Microsoft STL
|
||||
)
|
||||
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
|
||||
/wd26440 # CppCoreCheck - GTest
|
||||
/wd26446 # CppCoreCheck - prefer gsl::at()
|
||||
>
|
||||
$<$<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
|
||||
>
|
||||
)
|
||||
|
||||
# set definitions for tests
|
||||
target_compile_definitions(gsl_tests_config_noexcept INTERFACE
|
||||
GSL_TERMINATE_ON_CONTRACT_VIOLATION
|
||||
)
|
||||
$<$<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
|
||||
>
|
||||
$<$<CXX_COMPILER_ID:GNU>:
|
||||
-Wdouble-promotion # float implicit to double
|
||||
-Wlogical-op # suspicious uses of logical operators
|
||||
-Wuseless-cast # casting to its own type
|
||||
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
|
||||
-Wduplicated-cond # duplicated if-else conditions
|
||||
-Wmisleading-indentation
|
||||
-Wnull-dereference
|
||||
>
|
||||
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7>>:
|
||||
-Wduplicated-branches # identical if-else branches
|
||||
>
|
||||
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>>:
|
||||
-Wcast-align=strict # increase alignment (i.e. char* to int*)
|
||||
>
|
||||
>
|
||||
)
|
||||
endif(MSVC)
|
||||
|
||||
function(add_gsl_test_noexcept name)
|
||||
add_executable(${name} ${name}.cpp)
|
||||
target_link_libraries(${name}
|
||||
GSL
|
||||
gsl_tests_config_noexcept
|
||||
gtest_main
|
||||
)
|
||||
add_test(
|
||||
${name}
|
||||
@@ -160,5 +264,4 @@ function(add_gsl_test_noexcept name)
|
||||
set_property(TARGET ${name} PROPERTY FOLDER "GSL_tests_noexcept")
|
||||
endfunction()
|
||||
|
||||
add_gsl_test_noexcept(no_exception_throw_tests)
|
||||
add_gsl_test_noexcept(no_exception_ensure_tests)
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.0.2)
|
||||
project(googletest-download NONE)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e
|
||||
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
)
|
||||
+73
-56
@@ -14,37 +14,42 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHE...
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <gsl/gsl_algorithm> // for copy
|
||||
#include <gsl/span> // for span
|
||||
|
||||
#include <array> // for array
|
||||
#include <cstddef> // for size_t
|
||||
|
||||
namespace gsl {
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
}
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
} // namespace gsl
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
|
||||
TEST_CASE("same_type")
|
||||
TEST(algorithm_tests, same_type)
|
||||
{
|
||||
// dynamic source and destination span
|
||||
{
|
||||
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()));
|
||||
|
||||
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||
CHECK(dst[i] == src[i]);
|
||||
CHECK(dst[i + src.size()] == src[i]);
|
||||
for (std::size_t i = 0; i < src.size(); ++i)
|
||||
{
|
||||
EXPECT_TRUE(dst[i] == src[i]);
|
||||
EXPECT_TRUE(dst[i + src.size()] == src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,15 +58,16 @@ 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()));
|
||||
|
||||
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||
CHECK(dst[i] == src[i]);
|
||||
CHECK(dst[i + src.size()] == src[i]);
|
||||
for (std::size_t i = 0; i < src.size(); ++i)
|
||||
{
|
||||
EXPECT_TRUE(dst[i] == src[i]);
|
||||
EXPECT_TRUE(dst[i + src.size()] == src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,15 +76,16 @@ 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()));
|
||||
|
||||
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||
CHECK(dst[i] == src[i]);
|
||||
CHECK(dst[i + src.size()] == src[i]);
|
||||
for (std::size_t i = 0; i < src.size(); ++i)
|
||||
{
|
||||
EXPECT_TRUE(dst[i] == src[i]);
|
||||
EXPECT_TRUE(dst[i + src.size()] == src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,35 +94,37 @@ 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()));
|
||||
|
||||
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||
CHECK(dst[i] == src[i]);
|
||||
CHECK(dst[i + src.size()] == src[i]);
|
||||
for (std::size_t i = 0; i < src.size(); ++i)
|
||||
{
|
||||
EXPECT_TRUE(dst[i] == src[i]);
|
||||
EXPECT_TRUE(dst[i + src.size()] == src[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("compatible_type")
|
||||
TEST(algorithm_tests, compatible_type)
|
||||
{
|
||||
// dynamic source and destination span
|
||||
{
|
||||
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()));
|
||||
|
||||
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||
CHECK(dst[i] == src[i]);
|
||||
CHECK(dst[i + src.size()] == src[i]);
|
||||
for (std::size_t i = 0; i < src.size(); ++i)
|
||||
{
|
||||
EXPECT_TRUE(dst[i] == src[i]);
|
||||
EXPECT_TRUE(dst[i + src.size()] == src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,15 +133,16 @@ 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()));
|
||||
|
||||
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||
CHECK(dst[i] == src[i]);
|
||||
CHECK(dst[i + src.size()] == src[i]);
|
||||
for (std::size_t i = 0; i < src.size(); ++i)
|
||||
{
|
||||
EXPECT_TRUE(dst[i] == src[i]);
|
||||
EXPECT_TRUE(dst[i + src.size()] == src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,15 +151,16 @@ 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()));
|
||||
|
||||
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||
CHECK(dst[i] == src[i]);
|
||||
CHECK(dst[i + src.size()] == src[i]);
|
||||
for (std::size_t i = 0; i < src.size(); ++i)
|
||||
{
|
||||
EXPECT_TRUE(dst[i] == src[i]);
|
||||
EXPECT_TRUE(dst[i + src.size()] == src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,21 +169,22 @@ 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()));
|
||||
|
||||
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||
CHECK(dst[i] == src[i]);
|
||||
CHECK(dst[i + src.size()] == src[i]);
|
||||
for (std::size_t i = 0; i < src.size(); ++i)
|
||||
{
|
||||
EXPECT_TRUE(dst[i] == src[i]);
|
||||
EXPECT_TRUE(dst[i + src.size()] == src[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
TEST_CASE("incompatible_type")
|
||||
TEST(algorithm_tests, incompatible_type)
|
||||
{
|
||||
std::array<int, 4> src{1, 2, 3, 4};
|
||||
std::array<int*, 12> dst{};
|
||||
@@ -190,19 +202,24 @@ TEST_CASE("incompatible_type")
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("small_destination_span")
|
||||
TEST(algorithm_tests, small_destination_span)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. small_destination_span";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
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);
|
||||
CHECK_THROWS_AS(copy(src_span_static, dst_span_dyn), fail_fast);
|
||||
EXPECT_DEATH(copy(src_span_dyn, dst_span_dyn), deathstring);
|
||||
EXPECT_DEATH(copy(src_span_dyn, dst_span_static), deathstring);
|
||||
EXPECT_DEATH(copy(src_span_static, dst_span_dyn), deathstring);
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
|
||||
+26
-11
@@ -14,33 +14,48 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHECK...
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <gsl/gsl_assert> // for fail_fast (ptr only), Ensures, Expects
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
|
||||
int f(int i)
|
||||
{
|
||||
Expects(i > 0 && i < 10);
|
||||
return i;
|
||||
}
|
||||
|
||||
TEST_CASE("expects")
|
||||
{
|
||||
CHECK(f(2) == 2);
|
||||
CHECK_THROWS_AS(f(10), fail_fast);
|
||||
}
|
||||
|
||||
int g(int i)
|
||||
{
|
||||
i++;
|
||||
Ensures(i > 0 && i < 10);
|
||||
return i;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("ensures")
|
||||
TEST(assertion_tests, expects)
|
||||
{
|
||||
CHECK(g(2) == 3);
|
||||
CHECK_THROWS_AS(g(9), fail_fast);
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. expects";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
EXPECT_TRUE(f(2) == 2);
|
||||
EXPECT_DEATH(f(10), deathstring);
|
||||
}
|
||||
|
||||
|
||||
TEST(assertion_tests, ensures)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. ensures";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
EXPECT_TRUE(g(2) == 3);
|
||||
EXPECT_DEATH(g(9), deathstring);
|
||||
}
|
||||
|
||||
+54
-35
@@ -14,7 +14,7 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK_THROW...
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/gsl_util> // for at
|
||||
|
||||
@@ -23,73 +23,92 @@
|
||||
#include <initializer_list> // for initializer_list
|
||||
#include <vector> // for vector
|
||||
|
||||
namespace gsl {
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
}
|
||||
|
||||
using gsl::fail_fast;
|
||||
|
||||
TEST_CASE("static_array")
|
||||
TEST(at_tests, static_array)
|
||||
{
|
||||
int a[4] = {1, 2, 3, 4};
|
||||
const int(&c_a)[4] = a;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
CHECK(&gsl::at(a, i) == &a[i]);
|
||||
CHECK(&gsl::at(c_a, i) == &a[i]);
|
||||
EXPECT_TRUE(&gsl::at(a, i) == &a[i]);
|
||||
EXPECT_TRUE(&gsl::at(c_a, i) == &a[i]);
|
||||
}
|
||||
|
||||
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. static_array";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
|
||||
}
|
||||
|
||||
TEST_CASE("std_array")
|
||||
TEST(at_tests, std_array)
|
||||
{
|
||||
std::array<int, 4> a = {1, 2, 3, 4};
|
||||
const std::array<int, 4>& c_a = a;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
CHECK(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
|
||||
CHECK(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
|
||||
EXPECT_TRUE(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
|
||||
EXPECT_TRUE(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
|
||||
}
|
||||
|
||||
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. std_array";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
|
||||
}
|
||||
|
||||
TEST_CASE("StdVector")
|
||||
TEST(at_tests, std_vector)
|
||||
{
|
||||
std::vector<int> a = {1, 2, 3, 4};
|
||||
const std::vector<int>& c_a = a;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
CHECK(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
|
||||
CHECK(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
|
||||
EXPECT_TRUE(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
|
||||
EXPECT_TRUE(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
|
||||
}
|
||||
|
||||
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. std_vector";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
|
||||
}
|
||||
|
||||
TEST_CASE("InitializerList")
|
||||
TEST(at_tests, 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);
|
||||
CHECK(gsl::at({1, 2, 3, 4}, i) == i + 1);
|
||||
EXPECT_TRUE(gsl::at(a, i) == i + 1);
|
||||
EXPECT_TRUE(gsl::at({1, 2, 3, 4}, i) == i + 1);
|
||||
}
|
||||
|
||||
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at({1, 2, 3, 4}, -1), fail_fast);
|
||||
CHECK_THROWS_AS(gsl::at({1, 2, 3, 4}, 4), fail_fast);
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. InitializerList";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, 4), deathstring);
|
||||
}
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910
|
||||
|
||||
+17
-14
@@ -14,16 +14,12 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, TEST_CASE
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/multi_span> // for static_bounds, static_bounds_dynamic_range_t
|
||||
|
||||
#include <cstddef> // for ptrdiff_t, size_t
|
||||
|
||||
namespace gsl {
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
|
||||
@@ -32,7 +28,7 @@ namespace
|
||||
void use(std::ptrdiff_t&) {}
|
||||
}
|
||||
|
||||
TEST_CASE("basic_bounds")
|
||||
TEST(bounds_tests, basic_bounds)
|
||||
{
|
||||
for (auto point : static_bounds<dynamic_range, 3, 4>{2}) {
|
||||
for (decltype(point)::size_type j = 0;
|
||||
@@ -44,7 +40,7 @@ TEST_CASE("basic_bounds")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("bounds_basic")
|
||||
TEST(bounds_tests, bounds_basic)
|
||||
{
|
||||
static_bounds<3, 4, 5> b;
|
||||
const auto a = b.slice();
|
||||
@@ -53,7 +49,7 @@ TEST_CASE("bounds_basic")
|
||||
x.slice().slice();
|
||||
}
|
||||
|
||||
TEST_CASE("arrayview_iterator")
|
||||
TEST(bounds_tests, arrayview_iterator)
|
||||
{
|
||||
static_bounds<4, dynamic_range, 2> bounds{3};
|
||||
|
||||
@@ -71,7 +67,7 @@ TEST_CASE("arrayview_iterator")
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("bounds_convertible")
|
||||
TEST(bounds_tests, bounds_convertible)
|
||||
{
|
||||
static_bounds<7, 4, 2> b1;
|
||||
static_bounds<7, dynamic_range, 2> b2 = b1;
|
||||
@@ -84,16 +80,23 @@ TEST_CASE("bounds_convertible")
|
||||
static_bounds<7, 4, 2> b4 = b3;
|
||||
(void) b4;
|
||||
|
||||
static_bounds<dynamic_range> b11;
|
||||
|
||||
static_bounds<dynamic_range> b5;
|
||||
static_bounds<34> b6;
|
||||
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. bounds_convertible";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
b5 = static_bounds<20>();
|
||||
CHECK_THROWS_AS(b6 = b5, fail_fast);
|
||||
EXPECT_DEATH(b6 = b5, ".*");
|
||||
b5 = static_bounds<34>();
|
||||
b6 = b5;
|
||||
|
||||
CHECK(b5 == b6);
|
||||
CHECK(b5.size() == b6.size());
|
||||
EXPECT_TRUE(b5 == b6);
|
||||
EXPECT_TRUE(b5.size() == b6.size());
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
|
||||
+93
-88
@@ -14,7 +14,7 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/gsl_byte> // for to_byte, to_integer, byte, operator&, ope...
|
||||
|
||||
@@ -23,102 +23,107 @@ using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
TEST_CASE("construction")
|
||||
{
|
||||
{
|
||||
const byte b = static_cast<byte>(4);
|
||||
CHECK(static_cast<unsigned char>(b) == 4);
|
||||
}
|
||||
|
||||
{
|
||||
const byte b = byte(12);
|
||||
CHECK(static_cast<unsigned char>(b) == 12);
|
||||
}
|
||||
|
||||
{
|
||||
const byte b = to_byte<12>();
|
||||
CHECK(static_cast<unsigned char>(b) == 12);
|
||||
}
|
||||
{
|
||||
const unsigned char uc = 12;
|
||||
const byte b = to_byte(uc);
|
||||
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);
|
||||
//}
|
||||
}
|
||||
|
||||
TEST_CASE("bitwise_operations")
|
||||
{
|
||||
const byte b = to_byte<0xFF>();
|
||||
|
||||
byte a = to_byte<0x00>();
|
||||
CHECK((b | a) == to_byte<0xFF>());
|
||||
CHECK(a == to_byte<0x00>());
|
||||
|
||||
a |= b;
|
||||
CHECK(a == to_byte<0xFF>());
|
||||
|
||||
a = to_byte<0x01>();
|
||||
CHECK((b & a) == to_byte<0x01>());
|
||||
|
||||
a &= b;
|
||||
CHECK(a == to_byte<0x01>());
|
||||
|
||||
CHECK((b ^ a) == to_byte<0xFE>());
|
||||
|
||||
CHECK(a == to_byte<0x01>());
|
||||
a ^= b;
|
||||
CHECK(a == to_byte<0xFE>());
|
||||
|
||||
a = to_byte<0x01>();
|
||||
CHECK(~a == to_byte<0xFE>());
|
||||
|
||||
a = to_byte<0xFF>();
|
||||
CHECK((a << 4) == to_byte<0xF0>());
|
||||
CHECK((a >> 4) == to_byte<0x0F>());
|
||||
|
||||
a <<= 4;
|
||||
CHECK(a == to_byte<0xF0>());
|
||||
a >>= 4;
|
||||
CHECK(a == to_byte<0x0F>());
|
||||
}
|
||||
|
||||
TEST_CASE("to_integer")
|
||||
{
|
||||
const byte b = to_byte<0x12>();
|
||||
|
||||
CHECK(0x12 == gsl::to_integer<char>(b));
|
||||
CHECK(0x12 == gsl::to_integer<short>(b));
|
||||
CHECK(0x12 == gsl::to_integer<long>(b));
|
||||
CHECK(0x12 == gsl::to_integer<long long>(b));
|
||||
|
||||
CHECK(0x12 == gsl::to_integer<unsigned char>(b));
|
||||
CHECK(0x12 == gsl::to_integer<unsigned short>(b));
|
||||
CHECK(0x12 == gsl::to_integer<unsigned long>(b));
|
||||
CHECK(0x12 == gsl::to_integer<unsigned long long>(b));
|
||||
|
||||
// CHECK(0x12 == gsl::to_integer<float>(b)); // expect compile-time error
|
||||
// CHECK(0x12 == gsl::to_integer<double>(b)); // expect compile-time error
|
||||
}
|
||||
|
||||
int modify_both(gsl::byte & b, int& i)
|
||||
int modify_both(gsl::byte& b, int& i)
|
||||
{
|
||||
i = 10;
|
||||
b = to_byte<5>();
|
||||
return i;
|
||||
}
|
||||
|
||||
TEST_CASE("aliasing")
|
||||
TEST(byte_tests, construction)
|
||||
{
|
||||
{
|
||||
const byte b = static_cast<byte>(4);
|
||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 4);
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(es.49)
|
||||
{
|
||||
const byte b = byte(12);
|
||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
|
||||
}
|
||||
|
||||
{
|
||||
const byte b = to_byte<12>();
|
||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
|
||||
}
|
||||
{
|
||||
const unsigned char uc = 12;
|
||||
const byte b = to_byte(uc);
|
||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
{
|
||||
const byte b { 14 };
|
||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 14);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(byte_tests, bitwise_operations)
|
||||
{
|
||||
const byte b = to_byte<0xFF>();
|
||||
|
||||
byte a = to_byte<0x00>();
|
||||
EXPECT_TRUE((b | a) == to_byte<0xFF>());
|
||||
EXPECT_TRUE(a == to_byte<0x00>());
|
||||
|
||||
a |= b;
|
||||
EXPECT_TRUE(a == to_byte<0xFF>());
|
||||
|
||||
a = to_byte<0x01>();
|
||||
EXPECT_TRUE((b & a) == to_byte<0x01>());
|
||||
|
||||
a &= b;
|
||||
EXPECT_TRUE(a == to_byte<0x01>());
|
||||
|
||||
EXPECT_TRUE((b ^ a) == to_byte<0xFE>());
|
||||
|
||||
EXPECT_TRUE(a == to_byte<0x01>());
|
||||
a ^= b;
|
||||
EXPECT_TRUE(a == to_byte<0xFE>());
|
||||
|
||||
a = to_byte<0x01>();
|
||||
EXPECT_TRUE(~a == to_byte<0xFE>());
|
||||
|
||||
a = to_byte<0xFF>();
|
||||
EXPECT_TRUE((a << 4) == to_byte<0xF0>());
|
||||
EXPECT_TRUE((a >> 4) == to_byte<0x0F>());
|
||||
|
||||
a <<= 4;
|
||||
EXPECT_TRUE(a == to_byte<0xF0>());
|
||||
a >>= 4;
|
||||
EXPECT_TRUE(a == to_byte<0x0F>());
|
||||
}
|
||||
|
||||
TEST(byte_tests, to_integer)
|
||||
{
|
||||
const byte b = to_byte<0x12>();
|
||||
|
||||
EXPECT_TRUE(0x12 == gsl::to_integer<char>(b));
|
||||
EXPECT_TRUE(0x12 == gsl::to_integer<short>(b));
|
||||
EXPECT_TRUE(0x12 == gsl::to_integer<long>(b));
|
||||
EXPECT_TRUE(0x12 == gsl::to_integer<long long>(b));
|
||||
|
||||
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned char>(b));
|
||||
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned short>(b));
|
||||
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned long>(b));
|
||||
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned long long>(b));
|
||||
|
||||
// EXPECT_TRUE(0x12 == gsl::to_integer<float>(b)); // expect compile-time error
|
||||
// EXPECT_TRUE(0x12 == gsl::to_integer<double>(b)); // expect compile-time error
|
||||
}
|
||||
|
||||
TEST(byte_tests, aliasing)
|
||||
{
|
||||
int i{0};
|
||||
const int res = modify_both(reinterpret_cast<byte&>(i), i);
|
||||
CHECK(res == i);
|
||||
EXPECT_TRUE(res == i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
|
||||
+682
-517
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <gsl/gsl_util> // for narrow
|
||||
|
||||
int narrow_no_throw()
|
||||
{
|
||||
long long bigNumber = 0x0fffffffffffffff;
|
||||
return gsl::narrow<int>(bigNumber);
|
||||
}
|
||||
|
||||
void test_terminate()
|
||||
{
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
void setup_termination_handler()
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
auto& handler = gsl::details::get_terminate_handler();
|
||||
handler = &test_terminate;
|
||||
|
||||
#else
|
||||
|
||||
std::set_terminate(test_terminate);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
setup_termination_handler();
|
||||
narrow_no_throw();
|
||||
return -1;
|
||||
}
|
||||
+307
-103
@@ -14,7 +14,7 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
|
||||
|
||||
@@ -25,12 +25,13 @@
|
||||
#include <string> // for basic_string, operator==, string, operator<<
|
||||
#include <typeinfo> // for type_info
|
||||
|
||||
namespace gsl {
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
} //namespace
|
||||
|
||||
struct MyBase
|
||||
{
|
||||
};
|
||||
@@ -63,6 +64,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 +72,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 +80,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 +88,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 +96,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 +104,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,79 +118,149 @@ 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; }
|
||||
|
||||
TEST_CASE("TestNotNullConstructors")
|
||||
int* return_pointer() { return nullptr; }
|
||||
|
||||
TEST(notnull_tests, 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
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. TestNotNullConstructors";
|
||||
std::abort();
|
||||
});
|
||||
{
|
||||
// from shared pointer
|
||||
int i = 12;
|
||||
auto rp = RefCounted<int>(&i);
|
||||
not_null<int*> p(rp);
|
||||
EXPECT_TRUE(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;
|
||||
EXPECT_DEATH((not_null<decltype(pi)>(pi)), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// from pointer to local
|
||||
int t = 42;
|
||||
|
||||
not_null<int*> x = &t;
|
||||
helper(&t);
|
||||
helper_const(&t);
|
||||
|
||||
EXPECT_TRUE(*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);
|
||||
|
||||
EXPECT_TRUE(*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);
|
||||
|
||||
EXPECT_TRUE(*x == 42);
|
||||
}
|
||||
|
||||
{
|
||||
// from not_null const pointer, using auto
|
||||
int t = 42;
|
||||
const int* cp = &t;
|
||||
|
||||
auto x = not_null<const int*>{cp};
|
||||
|
||||
EXPECT_TRUE(*x == 42);
|
||||
}
|
||||
|
||||
{
|
||||
// from returned pointer
|
||||
|
||||
EXPECT_DEATH(helper(return_pointer()), deathstring);
|
||||
EXPECT_DEATH(helper_const(return_pointer()), deathstring);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void ostream_helper(T v)
|
||||
{
|
||||
not_null<T*> p(&v);
|
||||
{
|
||||
std::ostringstream os;
|
||||
std::ostringstream ref;
|
||||
os << p;
|
||||
ref << &v;
|
||||
CHECK(os.str() == ref.str());
|
||||
os << static_cast<void*>(p);
|
||||
ref << static_cast<void*>(&v);
|
||||
EXPECT_TRUE(os.str() == ref.str());
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
std::ostringstream ref;
|
||||
os << *p;
|
||||
ref << v;
|
||||
CHECK(os.str() == ref.str());
|
||||
EXPECT_TRUE(os.str() == ref.str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("TestNotNullostream")
|
||||
TEST(notnull_tests, 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");
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("TestNotNullCasting")
|
||||
TEST(notnull_tests, 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);
|
||||
EXPECT_TRUE(q == p);
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
q = u; // no viable conversion possible between MyBase* and Unrelated*
|
||||
@@ -192,21 +269,26 @@ 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());
|
||||
CHECK(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get()));
|
||||
not_null<Unrelated*> t(reinterpret_cast<Unrelated*>(p.get()));
|
||||
EXPECT_TRUE(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get()));
|
||||
}
|
||||
|
||||
TEST_CASE("TestNotNullAssignment")
|
||||
TEST(notnull_tests, TestNotNullAssignment)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. TestNotNullAssignmentd";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
int i = 12;
|
||||
not_null<int*> p = &i;
|
||||
CHECK(helper(p));
|
||||
not_null<int*> p(&i);
|
||||
EXPECT_TRUE(helper(p));
|
||||
|
||||
int* q = nullptr;
|
||||
CHECK_THROWS_AS(p = q, fail_fast);
|
||||
EXPECT_DEATH(p = not_null<int*>(q), deathstring);
|
||||
}
|
||||
|
||||
TEST_CASE("TestNotNullRawPointerComparison")
|
||||
TEST(notnull_tests, TestNotNullRawPointerComparison)
|
||||
{
|
||||
int ints[2] = {42, 43};
|
||||
int* p1 = &ints[0];
|
||||
@@ -215,57 +297,56 @@ TEST_CASE("TestNotNullRawPointerComparison")
|
||||
using NotNull1 = not_null<decltype(p1)>;
|
||||
using NotNull2 = not_null<decltype(p2)>;
|
||||
|
||||
CHECK((NotNull1(p1) == NotNull1(p1)) == true);
|
||||
CHECK((NotNull1(p1) == NotNull2(p2)) == false);
|
||||
EXPECT_TRUE((NotNull1(p1) == NotNull1(p1)) == true);
|
||||
EXPECT_TRUE((NotNull1(p1) == NotNull2(p2)) == false);
|
||||
|
||||
CHECK((NotNull1(p1) != NotNull1(p1)) == false);
|
||||
CHECK((NotNull1(p1) != NotNull2(p2)) == true);
|
||||
EXPECT_TRUE((NotNull1(p1) != NotNull1(p1)) == false);
|
||||
EXPECT_TRUE((NotNull1(p1) != NotNull2(p2)) == true);
|
||||
|
||||
CHECK((NotNull1(p1) < NotNull1(p1)) == false);
|
||||
CHECK((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
|
||||
CHECK((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
|
||||
EXPECT_TRUE((NotNull1(p1) < NotNull1(p1)) == false);
|
||||
EXPECT_TRUE((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
|
||||
EXPECT_TRUE((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
|
||||
|
||||
CHECK((NotNull1(p1) > NotNull1(p1)) == false);
|
||||
CHECK((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
|
||||
CHECK((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
|
||||
|
||||
CHECK((NotNull1(p1) <= NotNull1(p1)) == true);
|
||||
CHECK((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
|
||||
CHECK((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
|
||||
EXPECT_TRUE((NotNull1(p1) > NotNull1(p1)) == false);
|
||||
EXPECT_TRUE((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
|
||||
EXPECT_TRUE((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
|
||||
|
||||
EXPECT_TRUE((NotNull1(p1) <= NotNull1(p1)) == true);
|
||||
EXPECT_TRUE((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
|
||||
EXPECT_TRUE((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
|
||||
}
|
||||
|
||||
TEST_CASE("TestNotNullDereferenceOperator")
|
||||
TEST(notnull_tests, TestNotNullDereferenceOperator)
|
||||
{
|
||||
{
|
||||
auto sp1 = std::make_shared<NonCopyableNonMovable>();
|
||||
|
||||
using NotNullSp1 = not_null<decltype(sp1)>;
|
||||
CHECK(typeid(*sp1) == typeid(*NotNullSp1(sp1)));
|
||||
CHECK(std::addressof(*NotNullSp1(sp1)) == std::addressof(*sp1));
|
||||
EXPECT_TRUE(typeid(*sp1) == typeid(*NotNullSp1(sp1)));
|
||||
EXPECT_TRUE(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)>;
|
||||
CHECK(typeid(*NotNull1(p1)) == typeid(*p1));
|
||||
CHECK(*NotNull1(p1) == 42);
|
||||
EXPECT_TRUE(typeid(*NotNull1(p1)) == typeid(*p1));
|
||||
EXPECT_TRUE(*NotNull1(p1) == 42);
|
||||
*NotNull1(p1) = 43;
|
||||
CHECK(ints[0] == 43);
|
||||
EXPECT_TRUE(ints[0] == 43);
|
||||
}
|
||||
|
||||
{
|
||||
int v = 42;
|
||||
gsl::not_null<int*> p(&v);
|
||||
CHECK(typeid(*p) == typeid(*(&v)));
|
||||
EXPECT_TRUE(typeid(*p) == typeid(*(&v)));
|
||||
*p = 43;
|
||||
CHECK(v == 43);
|
||||
EXPECT_TRUE(v == 43);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("TestNotNullSharedPtrComparison")
|
||||
TEST(notnull_tests, TestNotNullSharedPtrComparison)
|
||||
{
|
||||
auto sp1 = std::make_shared<int>(42);
|
||||
auto sp2 = std::make_shared<const int>(43);
|
||||
@@ -273,30 +354,30 @@ TEST_CASE("TestNotNullSharedPtrComparison")
|
||||
using NotNullSp1 = not_null<decltype(sp1)>;
|
||||
using NotNullSp2 = not_null<decltype(sp2)>;
|
||||
|
||||
CHECK((NotNullSp1(sp1) == NotNullSp1(sp1)) == true);
|
||||
CHECK((NotNullSp1(sp1) == NotNullSp2(sp2)) == false);
|
||||
EXPECT_TRUE((NotNullSp1(sp1) == NotNullSp1(sp1)) == true);
|
||||
EXPECT_TRUE((NotNullSp1(sp1) == NotNullSp2(sp2)) == false);
|
||||
|
||||
CHECK((NotNullSp1(sp1) != NotNullSp1(sp1)) == false);
|
||||
CHECK((NotNullSp1(sp1) != NotNullSp2(sp2)) == true);
|
||||
EXPECT_TRUE((NotNullSp1(sp1) != NotNullSp1(sp1)) == false);
|
||||
EXPECT_TRUE((NotNullSp1(sp1) != NotNullSp2(sp2)) == true);
|
||||
|
||||
CHECK((NotNullSp1(sp1) < NotNullSp1(sp1)) == false);
|
||||
CHECK((NotNullSp1(sp1) < NotNullSp2(sp2)) == (sp1 < sp2));
|
||||
CHECK((NotNullSp2(sp2) < NotNullSp1(sp1)) == (sp2 < sp1));
|
||||
EXPECT_TRUE((NotNullSp1(sp1) < NotNullSp1(sp1)) == false);
|
||||
EXPECT_TRUE((NotNullSp1(sp1) < NotNullSp2(sp2)) == (sp1 < sp2));
|
||||
EXPECT_TRUE((NotNullSp2(sp2) < NotNullSp1(sp1)) == (sp2 < sp1));
|
||||
|
||||
CHECK((NotNullSp1(sp1) > NotNullSp1(sp1)) == false);
|
||||
CHECK((NotNullSp1(sp1) > NotNullSp2(sp2)) == (sp1 > sp2));
|
||||
CHECK((NotNullSp2(sp2) > NotNullSp1(sp1)) == (sp2 > sp1));
|
||||
EXPECT_TRUE((NotNullSp1(sp1) > NotNullSp1(sp1)) == false);
|
||||
EXPECT_TRUE((NotNullSp1(sp1) > NotNullSp2(sp2)) == (sp1 > sp2));
|
||||
EXPECT_TRUE((NotNullSp2(sp2) > NotNullSp1(sp1)) == (sp2 > sp1));
|
||||
|
||||
CHECK((NotNullSp1(sp1) <= NotNullSp1(sp1)) == true);
|
||||
CHECK((NotNullSp1(sp1) <= NotNullSp2(sp2)) == (sp1 <= sp2));
|
||||
CHECK((NotNullSp2(sp2) <= NotNullSp1(sp1)) == (sp2 <= sp1));
|
||||
EXPECT_TRUE((NotNullSp1(sp1) <= NotNullSp1(sp1)) == true);
|
||||
EXPECT_TRUE((NotNullSp1(sp1) <= NotNullSp2(sp2)) == (sp1 <= sp2));
|
||||
EXPECT_TRUE((NotNullSp2(sp2) <= NotNullSp1(sp1)) == (sp2 <= sp1));
|
||||
|
||||
CHECK((NotNullSp1(sp1) >= NotNullSp1(sp1)) == true);
|
||||
CHECK((NotNullSp1(sp1) >= NotNullSp2(sp2)) == (sp1 >= sp2));
|
||||
CHECK((NotNullSp2(sp2) >= NotNullSp1(sp1)) == (sp2 >= sp1));
|
||||
EXPECT_TRUE((NotNullSp1(sp1) >= NotNullSp1(sp1)) == true);
|
||||
EXPECT_TRUE((NotNullSp1(sp1) >= NotNullSp2(sp2)) == (sp1 >= sp2));
|
||||
EXPECT_TRUE((NotNullSp2(sp2) >= NotNullSp1(sp1)) == (sp2 >= sp1));
|
||||
}
|
||||
|
||||
TEST_CASE("TestNotNullCustomPtrComparison")
|
||||
TEST(notnull_tests, TestNotNullCustomPtrComparison)
|
||||
{
|
||||
int ints[2] = {42, 43};
|
||||
CustomPtr<int> p1(&ints[0]);
|
||||
@@ -305,27 +386,150 @@ TEST_CASE("TestNotNullCustomPtrComparison")
|
||||
using NotNull1 = not_null<decltype(p1)>;
|
||||
using NotNull2 = not_null<decltype(p2)>;
|
||||
|
||||
CHECK((NotNull1(p1) == NotNull1(p1)) == "true");
|
||||
CHECK((NotNull1(p1) == NotNull2(p2)) == "false");
|
||||
EXPECT_TRUE((NotNull1(p1) == NotNull1(p1)) == "true");
|
||||
EXPECT_TRUE((NotNull1(p1) == NotNull2(p2)) == "false");
|
||||
|
||||
CHECK((NotNull1(p1) != NotNull1(p1)) == "false");
|
||||
CHECK((NotNull1(p1) != NotNull2(p2)) == "true");
|
||||
EXPECT_TRUE((NotNull1(p1) != NotNull1(p1)) == "false");
|
||||
EXPECT_TRUE((NotNull1(p1) != NotNull2(p2)) == "true");
|
||||
|
||||
CHECK((NotNull1(p1) < NotNull1(p1)) == "false");
|
||||
CHECK((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
|
||||
CHECK((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
|
||||
EXPECT_TRUE((NotNull1(p1) < NotNull1(p1)) == "false");
|
||||
EXPECT_TRUE((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
|
||||
EXPECT_TRUE((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
|
||||
|
||||
CHECK((NotNull1(p1) > NotNull1(p1)) == "false");
|
||||
CHECK((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
|
||||
CHECK((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
|
||||
EXPECT_TRUE((NotNull1(p1) > NotNull1(p1)) == "false");
|
||||
EXPECT_TRUE((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
|
||||
EXPECT_TRUE((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
|
||||
|
||||
CHECK((NotNull1(p1) <= NotNull1(p1)) == "true");
|
||||
CHECK((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
|
||||
CHECK((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
|
||||
EXPECT_TRUE((NotNull1(p1) <= NotNull1(p1)) == "true");
|
||||
EXPECT_TRUE((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
|
||||
EXPECT_TRUE((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
|
||||
|
||||
CHECK((NotNull1(p1) >= NotNull1(p1)) == "true");
|
||||
CHECK((NotNull1(p1) >= NotNull2(p2)) == (p1 >= p2));
|
||||
CHECK((NotNull2(p2) >= NotNull1(p1)) == (p2 >= p1));
|
||||
EXPECT_TRUE((NotNull1(p1) >= NotNull1(p1)) == "true");
|
||||
EXPECT_TRUE((NotNull1(p1) >= NotNull2(p2)) == (p1 >= p2));
|
||||
EXPECT_TRUE((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)
|
||||
|
||||
TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
|
||||
{
|
||||
{
|
||||
int i = 42;
|
||||
|
||||
not_null x{&i};
|
||||
helper(not_null{&i});
|
||||
helper_const(not_null{&i});
|
||||
|
||||
EXPECT_TRUE(*x == 42);
|
||||
}
|
||||
|
||||
{
|
||||
int i = 42;
|
||||
int* p = &i;
|
||||
|
||||
not_null x{p};
|
||||
helper(not_null{p});
|
||||
helper_const(not_null{p});
|
||||
|
||||
EXPECT_TRUE(*x == 42);
|
||||
}
|
||||
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. TestNotNullConstructorTypeDeduction";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
{
|
||||
auto workaround_macro = []() {
|
||||
int* p1 = nullptr;
|
||||
const not_null x{p1};
|
||||
};
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = []() {
|
||||
const int* p1 = nullptr;
|
||||
const not_null x{p1};
|
||||
};
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
|
||||
EXPECT_DEATH(helper(not_null{p}), deathstring);
|
||||
EXPECT_DEATH(helper_const(not_null{p}), deathstring);
|
||||
}
|
||||
|
||||
#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(notnull_tests, TestMakeNotNull)
|
||||
{
|
||||
{
|
||||
int i = 42;
|
||||
|
||||
const auto x = make_not_null(&i);
|
||||
helper(make_not_null(&i));
|
||||
helper_const(make_not_null(&i));
|
||||
|
||||
EXPECT_TRUE(*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));
|
||||
|
||||
EXPECT_TRUE(*x == 42);
|
||||
}
|
||||
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. TestMakeNotNull";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
{
|
||||
const auto workaround_macro = []() {
|
||||
int* p1 = nullptr;
|
||||
const auto x = make_not_null(p1);
|
||||
EXPECT_TRUE(*x == 42);
|
||||
};
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
const auto workaround_macro = []() {
|
||||
const int* p1 = nullptr;
|
||||
const auto x = make_not_null(p1);
|
||||
EXPECT_TRUE(*x == 42);
|
||||
};
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
|
||||
EXPECT_DEATH(helper(make_not_null(p)), deathstring);
|
||||
EXPECT_DEATH(helper_const(make_not_null(p)), deathstring);
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
EXPECT_DEATH(make_not_null(nullptr), deathstring);
|
||||
EXPECT_DEATH(helper(make_not_null(nullptr)), deathstring);
|
||||
EXPECT_DEATH(helper_const(make_not_null(nullptr)), deathstring);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -14,24 +14,25 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/pointers> // for owner
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute
|
||||
void f(int* i) { *i += 1; }
|
||||
|
||||
TEST_CASE("basic_test")
|
||||
TEST(owner_tests, basic_test)
|
||||
{
|
||||
owner<int*> p = new int(120);
|
||||
CHECK(*p == 120);
|
||||
EXPECT_TRUE(*p == 120);
|
||||
f(p);
|
||||
CHECK(*p == 121);
|
||||
EXPECT_TRUE(*p == 121);
|
||||
delete p;
|
||||
}
|
||||
|
||||
TEST_CASE("check_pointer_constraint")
|
||||
TEST(owner_tests, check_pointer_constraint)
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,360 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/gsl_util> // for narrow_cast, at
|
||||
#include <gsl/span_ext> // for operator==, operator!=, make_span
|
||||
|
||||
#include <array> // for array
|
||||
#include <iostream> // for cerr
|
||||
#include <vector> // for vector
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
} // namespace
|
||||
|
||||
TEST(span_ext_test, make_span_from_pointer_length_constructor)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. from_pointer_length_constructor";
|
||||
std::abort();
|
||||
});
|
||||
int arr[4] = {1, 2, 3, 4};
|
||||
|
||||
{
|
||||
auto s = make_span(&arr[0], 2);
|
||||
EXPECT_TRUE(s.size() == 2);
|
||||
EXPECT_TRUE(s.data() == &arr[0]);
|
||||
EXPECT_TRUE(s[0] == 1);
|
||||
EXPECT_TRUE(s[1] == 2);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
auto s = make_span(p, narrow_cast<span<int>::size_type>(0));
|
||||
EXPECT_TRUE(s.size() == 0);
|
||||
EXPECT_TRUE(s.data() == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
auto workaround_macro = [=]() { make_span(p, 2); };
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_pointer_pointer_construction)
|
||||
{
|
||||
int arr[4] = {1, 2, 3, 4};
|
||||
|
||||
{
|
||||
auto s = make_span(&arr[0], &arr[2]);
|
||||
EXPECT_TRUE(s.size() == 2);
|
||||
EXPECT_TRUE(s.data() == &arr[0]);
|
||||
EXPECT_TRUE(s[0] == 1);
|
||||
EXPECT_TRUE(s[1] == 2);
|
||||
}
|
||||
|
||||
{
|
||||
auto s = make_span(&arr[0], &arr[0]);
|
||||
EXPECT_TRUE(s.size() == 0);
|
||||
EXPECT_TRUE(s.data() == &arr[0]);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
auto s = make_span(p, p);
|
||||
EXPECT_TRUE(s.size() == 0);
|
||||
EXPECT_TRUE(s.data() == nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_array_constructor)
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
|
||||
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
|
||||
{
|
||||
const auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == 5);
|
||||
EXPECT_TRUE(s.data() == std::addressof(arr[0]));
|
||||
}
|
||||
|
||||
{
|
||||
const auto s = make_span(std::addressof(arr2d[0]), 1);
|
||||
EXPECT_TRUE(s.size() == 1);
|
||||
EXPECT_TRUE(s.data() == std::addressof(arr2d[0]));
|
||||
}
|
||||
|
||||
{
|
||||
const auto s = make_span(std::addressof(arr3d[0]), 1);
|
||||
EXPECT_TRUE(s.size() == 1);
|
||||
EXPECT_TRUE(s.data() == std::addressof(arr3d[0]));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_dynamic_array_constructor)
|
||||
{
|
||||
double(*arr)[3][4] = new double[100][3][4];
|
||||
|
||||
{
|
||||
auto s = make_span(&arr[0][0][0], 10);
|
||||
EXPECT_TRUE(s.size() == 10);
|
||||
EXPECT_TRUE(s.data() == &arr[0][0][0]);
|
||||
}
|
||||
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_std_array_constructor)
|
||||
{
|
||||
std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
|
||||
{
|
||||
auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == arr.size());
|
||||
EXPECT_TRUE(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
|
||||
EXPECT_TRUE(s1.size() == 4);
|
||||
EXPECT_TRUE(s2.size() == 0);
|
||||
#else
|
||||
EXPECT_TRUE(s1.size() == s2.size());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_const_std_array_constructor)
|
||||
{
|
||||
const std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
|
||||
{
|
||||
auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == arr.size());
|
||||
EXPECT_TRUE(s.data() == arr.data());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_std_array_const_constructor)
|
||||
{
|
||||
std::array<const int, 4> arr = {1, 2, 3, 4};
|
||||
|
||||
{
|
||||
auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == arr.size());
|
||||
EXPECT_TRUE(s.data() == arr.data());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_container_constructor)
|
||||
{
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
const std::vector<int> cv = v;
|
||||
|
||||
{
|
||||
auto s = make_span(v);
|
||||
EXPECT_TRUE(s.size() == v.size());
|
||||
EXPECT_TRUE(s.data() == v.data());
|
||||
|
||||
auto cs = make_span(cv);
|
||||
EXPECT_TRUE(cs.size() == cv.size());
|
||||
EXPECT_TRUE(cs.data() == cv.data());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_test, interop_with_gsl_at)
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
span<int> s{arr};
|
||||
EXPECT_TRUE(at(s, 0) == 1);
|
||||
EXPECT_TRUE(at(s, 1) == 2);
|
||||
}
|
||||
|
||||
TEST(span_ext_test, iterator_free_functions)
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
span<int> s{a};
|
||||
|
||||
EXPECT_TRUE((std::is_same<decltype(s.begin()), decltype(begin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(s.end()), decltype(end(s))>::value));
|
||||
|
||||
EXPECT_TRUE((std::is_same<decltype(std::cbegin(s)), decltype(cbegin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(std::cend(s)), decltype(cend(s))>::value));
|
||||
|
||||
EXPECT_TRUE((std::is_same<decltype(s.rbegin()), decltype(rbegin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(s.rend()), decltype(rend(s))>::value));
|
||||
|
||||
EXPECT_TRUE((std::is_same<decltype(std::crbegin(s)), decltype(crbegin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(std::crend(s)), decltype(crend(s))>::value));
|
||||
|
||||
EXPECT_TRUE(s.begin() == begin(s));
|
||||
EXPECT_TRUE(s.end() == end(s));
|
||||
|
||||
EXPECT_TRUE(s.rbegin() == rbegin(s));
|
||||
EXPECT_TRUE(s.rend() == rend(s));
|
||||
|
||||
EXPECT_TRUE(s.begin() == cbegin(s));
|
||||
EXPECT_TRUE(s.end() == cend(s));
|
||||
|
||||
EXPECT_TRUE(s.rbegin() == crbegin(s));
|
||||
EXPECT_TRUE(s.rend() == crend(s));
|
||||
}
|
||||
|
||||
TEST(span_ext_test, ssize_free_function)
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
span<int> s{a};
|
||||
|
||||
EXPECT_FALSE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value));
|
||||
EXPECT_TRUE(s.size() == static_cast<std::size_t>(ssize(s)));
|
||||
}
|
||||
|
||||
TEST(span_ext_test, comparison_operators)
|
||||
{
|
||||
{
|
||||
span<int> s1;
|
||||
span<int> s2;
|
||||
EXPECT_TRUE(s1 == s2);
|
||||
EXPECT_FALSE(s1 != s2);
|
||||
EXPECT_FALSE(s1 < s2);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s1 >= s2);
|
||||
EXPECT_TRUE(s2 == s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_TRUE(s2 <= s1);
|
||||
EXPECT_FALSE(s2 > s1);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
}
|
||||
|
||||
{
|
||||
int arr[] = {2, 1};
|
||||
span<int> s1 = arr;
|
||||
span<int> s2 = arr;
|
||||
|
||||
EXPECT_TRUE(s1 == s2);
|
||||
EXPECT_FALSE(s1 != s2);
|
||||
EXPECT_FALSE(s1 < s2);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s1 >= s2);
|
||||
EXPECT_TRUE(s2 == s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s2 <= s1);
|
||||
EXPECT_FALSE(s2 > s1);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
}
|
||||
|
||||
{
|
||||
int arr[] = {2, 1}; // bigger
|
||||
|
||||
span<int> s1;
|
||||
span<int> s2 = arr;
|
||||
|
||||
EXPECT_TRUE(s1 != s2);
|
||||
EXPECT_TRUE(s2 != s1);
|
||||
EXPECT_FALSE(s1 == s2);
|
||||
EXPECT_FALSE(s2 == s1);
|
||||
EXPECT_TRUE(s1 < s2);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s2 <= s1);
|
||||
EXPECT_TRUE(s2 > s1);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
EXPECT_FALSE(s1 >= s2);
|
||||
}
|
||||
|
||||
{
|
||||
int arr1[] = {1, 2};
|
||||
int arr2[] = {1, 2};
|
||||
span<int> s1 = arr1;
|
||||
span<int> s2 = arr2;
|
||||
|
||||
EXPECT_TRUE(s1 == s2);
|
||||
EXPECT_FALSE(s1 != s2);
|
||||
EXPECT_FALSE(s1 < s2);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s1 >= s2);
|
||||
EXPECT_TRUE(s2 == s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s2 <= s1);
|
||||
EXPECT_FALSE(s2 > s1);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
}
|
||||
|
||||
{
|
||||
int arr[] = {1, 2, 3};
|
||||
|
||||
span<int> s1 = {&arr[0], 2}; // shorter
|
||||
span<int> s2 = arr; // longer
|
||||
|
||||
EXPECT_TRUE(s1 != s2);
|
||||
EXPECT_TRUE(s2 != s1);
|
||||
EXPECT_FALSE(s1 == s2);
|
||||
EXPECT_FALSE(s2 == s1);
|
||||
EXPECT_TRUE(s1 < s2);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s2 <= s1);
|
||||
EXPECT_TRUE(s2 > s1);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
EXPECT_FALSE(s1 >= s2);
|
||||
}
|
||||
|
||||
{
|
||||
int arr1[] = {1, 2}; // smaller
|
||||
int arr2[] = {2, 1}; // bigger
|
||||
|
||||
span<int> s1 = arr1;
|
||||
span<int> s2 = arr2;
|
||||
|
||||
EXPECT_TRUE(s1 != s2);
|
||||
EXPECT_TRUE(s2 != s1);
|
||||
EXPECT_FALSE(s1 == s2);
|
||||
EXPECT_FALSE(s2 == s1);
|
||||
EXPECT_TRUE(s1 < s2);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s2 <= s1);
|
||||
EXPECT_TRUE(s2 > s1);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
EXPECT_FALSE(s1 >= s2);
|
||||
}
|
||||
}
|
||||
+1075
-1295
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,190 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#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; }
|
||||
|
||||
TEST(strict_notnull_tests, 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);
|
||||
|
||||
EXPECT_TRUE(*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);
|
||||
|
||||
EXPECT_TRUE(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);
|
||||
|
||||
EXPECT_TRUE(snn == nn1);
|
||||
EXPECT_TRUE(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);
|
||||
|
||||
EXPECT_TRUE(snn1 == nn);
|
||||
EXPECT_TRUE(snn2 == nn);
|
||||
|
||||
std::hash<strict_not_null<int*>> hash_snn;
|
||||
std::hash<not_null<int*>> hash_nn;
|
||||
|
||||
EXPECT_TRUE(hash_nn(snn1) == hash_nn(nn));
|
||||
EXPECT_TRUE(hash_snn(snn1) == hash_nn(nn));
|
||||
EXPECT_TRUE(hash_nn(snn1) == hash_nn(snn2));
|
||||
EXPECT_TRUE(hash_snn(snn1) == hash_snn(nn));
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
strict_not_null<int*> p{nullptr};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
}
|
||||
|
||||
TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. TestStrictNotNullConstructorTypeDeduction";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
{
|
||||
int i = 42;
|
||||
|
||||
strict_not_null x{&i};
|
||||
helper(strict_not_null{&i});
|
||||
helper_const(strict_not_null{&i});
|
||||
|
||||
EXPECT_TRUE(*x == 42);
|
||||
}
|
||||
|
||||
{
|
||||
int i = 42;
|
||||
int* p = &i;
|
||||
|
||||
strict_not_null x{p};
|
||||
helper(strict_not_null{p});
|
||||
helper_const(strict_not_null{p});
|
||||
|
||||
EXPECT_TRUE(*x == 42);
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = []() {
|
||||
int* p1 = nullptr;
|
||||
const strict_not_null x{p1};
|
||||
};
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
auto workaround_macro = []() {
|
||||
const int* p1 = nullptr;
|
||||
const strict_not_null x{p1};
|
||||
};
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
|
||||
EXPECT_DEATH(helper(strict_not_null{p}), deathstring);
|
||||
EXPECT_DEATH(helper_const(strict_not_null{p}), deathstring);
|
||||
}
|
||||
|
||||
#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)
|
||||
+268
-235
@@ -14,8 +14,7 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHECK...
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <gsl/gsl_byte> // for byte
|
||||
#include <gsl/gsl_util> // for narrow_cast
|
||||
#include <gsl/multi_span> // for strided_span, index, multi_span, strided_...
|
||||
@@ -26,24 +25,80 @@
|
||||
#include <type_traits> // for integral_constant<>::value, is_convertible
|
||||
#include <vector> // for vector
|
||||
|
||||
namespace gsl {
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
|
||||
struct BaseClass
|
||||
{
|
||||
};
|
||||
struct DerivedClass : BaseClass
|
||||
{
|
||||
};
|
||||
|
||||
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 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});
|
||||
#endif
|
||||
strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);
|
||||
|
||||
EXPECT_TRUE(strided.size() == length);
|
||||
EXPECT_TRUE(strided.bounds().index_bounds()[0] == length);
|
||||
for (auto i = 0; i < strided.size(); ++i) {
|
||||
EXPECT_TRUE(strided[i] == av[2 * i + 1]);
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
for (auto num : strided) {
|
||||
EXPECT_TRUE(num == av[2 * idx + 1]);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("span_section_test")
|
||||
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};
|
||||
auto section = av.section({0, 1, 0}, {3, 1, 2});
|
||||
|
||||
for (auto i = 0; i < section.extent<0>(); ++i) {
|
||||
for (auto j = 0; j < section.extent<1>(); ++j)
|
||||
for (auto k = 0; k < section.extent<2>(); ++k) {
|
||||
auto idx = multi_span_index<3>{i, j, k}; // avoid braces in the EXPECT_TRUE macro
|
||||
EXPECT_TRUE(section[idx] == expected[2 * i + 2 * j + k]);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i = 0; i < section.extent<0>(); ++i) {
|
||||
for (auto j = 0; j < section.extent<1>(); ++j)
|
||||
for (auto k = 0; k < section.extent<2>(); ++k)
|
||||
EXPECT_TRUE(section[i][j][k] == expected[2 * i + 2 * j + k]);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (const auto num : section) {
|
||||
EXPECT_TRUE(num == expected[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, span_section_test)
|
||||
{
|
||||
int a[30][4][5];
|
||||
|
||||
@@ -53,48 +108,54 @@ TEST_CASE("span_section_test")
|
||||
(void) subsub;
|
||||
}
|
||||
|
||||
TEST_CASE("span_section")
|
||||
TEST(strided_span_tests, span_section)
|
||||
{
|
||||
std::vector<int> data(5 * 10);
|
||||
std::iota(begin(data), end(data), 0);
|
||||
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[{0, 0}] == 12));
|
||||
CHECK((av_section_1[{0, 1}] == 13));
|
||||
CHECK((av_section_1[{1, 0}] == 22));
|
||||
CHECK((av_section_1[{2, 3}] == 35));
|
||||
EXPECT_TRUE(!av_section_1.empty());
|
||||
EXPECT_TRUE((av_section_1[{0, 0}] == 12));
|
||||
EXPECT_TRUE((av_section_1[{0, 1}] == 13));
|
||||
EXPECT_TRUE((av_section_1[{1, 0}] == 22));
|
||||
EXPECT_TRUE((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[{0, 0}] == 24));
|
||||
CHECK((av_section_2[{0, 1}] == 25));
|
||||
CHECK((av_section_2[{1, 0}] == 34));
|
||||
EXPECT_TRUE(!av_section_2.empty());
|
||||
EXPECT_TRUE((av_section_2[{0, 0}] == 24));
|
||||
EXPECT_TRUE((av_section_2[{0, 1}] == 25));
|
||||
EXPECT_TRUE((av_section_2[{1, 0}] == 34));
|
||||
}
|
||||
|
||||
TEST_CASE("strided_span_constructors")
|
||||
TEST(strided_span_tests, strided_span_constructors)
|
||||
{
|
||||
// Check stride constructor
|
||||
// EXPECT_TRUE stride constructor
|
||||
{
|
||||
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
const int carr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
|
||||
strided_span<int, 1> sav1{arr, {{9}, {1}}}; // T -> T
|
||||
CHECK(sav1.bounds().index_bounds() == multi_span_index<1>{9});
|
||||
CHECK(sav1.bounds().stride() == 1);
|
||||
CHECK((sav1[0] == 1 && sav1[8] == 9));
|
||||
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{9});
|
||||
EXPECT_TRUE(sav1.bounds().stride() == 1);
|
||||
EXPECT_TRUE(sav1[0] == 1);
|
||||
EXPECT_TRUE(sav1[8] == 9);
|
||||
|
||||
strided_span<const int, 1> sav2{carr, {{4}, {2}}}; // const T -> const T
|
||||
CHECK(sav2.bounds().index_bounds() == multi_span_index<1>{4});
|
||||
CHECK(sav2.bounds().strides() == multi_span_index<1>{2});
|
||||
CHECK((sav2[0] == 1 && sav2[3] == 7));
|
||||
EXPECT_TRUE(sav2.bounds().index_bounds() == multi_span_index<1>{4});
|
||||
EXPECT_TRUE(sav2.bounds().strides() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav2[0] == 1);
|
||||
EXPECT_TRUE(sav2[3] == 7);
|
||||
|
||||
strided_span<int, 2> sav3{arr, {{2, 2}, {6, 2}}}; // T -> const T
|
||||
CHECK((sav3.bounds().index_bounds() == multi_span_index<2>{2, 2}));
|
||||
CHECK((sav3.bounds().strides() == multi_span_index<2>{6, 2}));
|
||||
CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7));
|
||||
EXPECT_TRUE((sav3.bounds().index_bounds() == multi_span_index<2>{2, 2}));
|
||||
EXPECT_TRUE((sav3.bounds().strides() == multi_span_index<2>{6, 2}));
|
||||
EXPECT_TRUE((sav3[{0, 0}]) == 1);
|
||||
EXPECT_TRUE((sav3[{0, 1}]) == 3);
|
||||
EXPECT_TRUE((sav3[{1, 0}]) == 7);
|
||||
}
|
||||
|
||||
// Check multi_span constructor
|
||||
// EXPECT_TRUE multi_span constructor
|
||||
{
|
||||
int arr[] = {1, 2};
|
||||
|
||||
@@ -103,11 +164,11 @@ TEST_CASE("strided_span_constructors")
|
||||
const multi_span<int> src = arr;
|
||||
|
||||
strided_span<int, 1> sav{src, {2, 1}};
|
||||
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav[1] == 2);
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(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}};
|
||||
@@ -115,29 +176,29 @@ TEST_CASE("strided_span_constructors")
|
||||
strided_span<const int, 1> sav_c{multi_span<const int>{src},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#endif
|
||||
CHECK(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav_c.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav_c[1] == 2);
|
||||
EXPECT_TRUE(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_c.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(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},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#endif
|
||||
CHECK(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav_v.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav_v[1] == 2);
|
||||
EXPECT_TRUE(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_v.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(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},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#endif
|
||||
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav_cv[1] == 2);
|
||||
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_cv[1] == 2);
|
||||
}
|
||||
|
||||
// From const-qualified source
|
||||
@@ -145,20 +206,20 @@ TEST_CASE("strided_span_constructors")
|
||||
const multi_span<const int> src{arr};
|
||||
|
||||
strided_span<const int, 1> sav_c{src, {2, 1}};
|
||||
CHECK(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav_c.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav_c[1] == 2);
|
||||
EXPECT_TRUE(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_c.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(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},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#endif
|
||||
|
||||
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav_cv[1] == 2);
|
||||
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_cv[1] == 2);
|
||||
}
|
||||
|
||||
// From volatile-qualified source
|
||||
@@ -166,19 +227,19 @@ TEST_CASE("strided_span_constructors")
|
||||
const multi_span<volatile int> src{arr};
|
||||
|
||||
strided_span<volatile int, 1> sav_v{src, {2, 1}};
|
||||
CHECK(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav_v.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav_v[1] == 2);
|
||||
EXPECT_TRUE(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_v.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(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},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#endif
|
||||
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav_cv[1] == 2);
|
||||
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_cv[1] == 2);
|
||||
}
|
||||
|
||||
// From cv-qualified source
|
||||
@@ -186,19 +247,19 @@ TEST_CASE("strided_span_constructors")
|
||||
const multi_span<const volatile int> src{arr};
|
||||
|
||||
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
|
||||
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav_cv[1] == 2);
|
||||
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_cv[1] == 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Check const-casting constructor
|
||||
// EXPECT_TRUE const-casting constructor
|
||||
{
|
||||
int arr[2] = {4, 5};
|
||||
|
||||
const multi_span<int, 2> av(arr, 2);
|
||||
multi_span<const int, 2> av2{av};
|
||||
CHECK(av2[1] == 5);
|
||||
EXPECT_TRUE(av2[1] == 5);
|
||||
|
||||
static_assert(
|
||||
std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value,
|
||||
@@ -206,34 +267,35 @@ TEST_CASE("strided_span_constructors")
|
||||
|
||||
const strided_span<int, 1> src{arr, {2, 1}};
|
||||
strided_span<const int, 1> sav{src};
|
||||
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav.bounds().stride() == 1);
|
||||
CHECK(sav[1] == 5);
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav.bounds().stride() == 1);
|
||||
EXPECT_TRUE(sav[1] == 5);
|
||||
|
||||
static_assert(
|
||||
std::is_convertible<const strided_span<int, 1>, strided_span<const int, 1>>::value,
|
||||
"ctor is not implicit!");
|
||||
}
|
||||
|
||||
// Check copy constructor
|
||||
// EXPECT_TRUE copy constructor
|
||||
{
|
||||
int arr1[2] = {3, 4};
|
||||
const strided_span<int, 1> src1{arr1, {2, 1}};
|
||||
strided_span<int, 1> sav1{src1};
|
||||
|
||||
CHECK(sav1.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav1.bounds().stride() == 1);
|
||||
CHECK(sav1[0] == 3);
|
||||
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav1.bounds().stride() == 1);
|
||||
EXPECT_TRUE(sav1[0] == 3);
|
||||
|
||||
int arr2[6] = {1, 2, 3, 4, 5, 6};
|
||||
const strided_span<const int, 2> src2{arr2, {{3, 2}, {2, 1}}};
|
||||
strided_span<const int, 2> sav2{src2};
|
||||
CHECK((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
|
||||
CHECK((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
|
||||
CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
|
||||
EXPECT_TRUE((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
|
||||
EXPECT_TRUE((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
|
||||
EXPECT_TRUE((sav2[{0, 0}]) == 1);
|
||||
EXPECT_TRUE((sav2[{2, 0}]) == 5);
|
||||
}
|
||||
|
||||
// Check const-casting assignment operator
|
||||
// EXPECT_TRUE const-casting assignment operator
|
||||
{
|
||||
int arr1[2] = {1, 2};
|
||||
int arr2[6] = {3, 4, 5, 6, 7, 8};
|
||||
@@ -241,37 +303,38 @@ TEST_CASE("strided_span_constructors")
|
||||
const strided_span<int, 1> src{arr1, {{2}, {1}}};
|
||||
strided_span<const int, 1> sav{arr2, {{3}, {2}}};
|
||||
strided_span<const int, 1>& sav_ref = (sav = src);
|
||||
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav[0] == 1);
|
||||
CHECK(&sav_ref == &sav);
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav[0] == 1);
|
||||
EXPECT_TRUE(&sav_ref == &sav);
|
||||
}
|
||||
|
||||
// Check copy assignment operator
|
||||
// EXPECT_TRUE copy assignment operator
|
||||
{
|
||||
int arr1[2] = {3, 4};
|
||||
int arr1b[1] = {0};
|
||||
const strided_span<int, 1> src1{arr1, {2, 1}};
|
||||
strided_span<int, 1> sav1{arr1b, {1, 1}};
|
||||
strided_span<int, 1>& sav1_ref = (sav1 = src1);
|
||||
CHECK(sav1.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav1.bounds().strides() == multi_span_index<1>{1});
|
||||
CHECK(sav1[0] == 3);
|
||||
CHECK(&sav1_ref == &sav1);
|
||||
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav1.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav1[0] == 3);
|
||||
EXPECT_TRUE(&sav1_ref == &sav1);
|
||||
|
||||
const int arr2[6] = {1, 2, 3, 4, 5, 6};
|
||||
const int arr2b[1] = {0};
|
||||
const strided_span<const int, 2> src2{arr2, {{3, 2}, {2, 1}}};
|
||||
strided_span<const int, 2> sav2{arr2b, {{1, 1}, {1, 1}}};
|
||||
strided_span<const int, 2>& sav2_ref = (sav2 = src2);
|
||||
CHECK((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
|
||||
CHECK((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
|
||||
CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
|
||||
CHECK(&sav2_ref == &sav2);
|
||||
EXPECT_TRUE((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
|
||||
EXPECT_TRUE((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
|
||||
EXPECT_TRUE((sav2[{0, 0}] == 1));
|
||||
EXPECT_TRUE((sav2[{2, 0}] == 5));
|
||||
EXPECT_TRUE(&sav2_ref == &sav2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("strided_span_slice")
|
||||
TEST(strided_span_tests, strided_span_slice)
|
||||
{
|
||||
std::vector<int> data(5 * 10);
|
||||
std::iota(begin(data), end(data), 0);
|
||||
@@ -286,18 +349,18 @@ TEST_CASE("strided_span_slice")
|
||||
{{5, 10}, {10, 1}}};
|
||||
|
||||
strided_span<int, 1> sav_sl = sav[2];
|
||||
CHECK(sav_sl[0] == 20);
|
||||
CHECK(sav_sl[9] == 29);
|
||||
EXPECT_TRUE(sav_sl[0] == 20);
|
||||
EXPECT_TRUE(sav_sl[9] == 29);
|
||||
|
||||
strided_span<const int, 1> csav_sl = sav[3];
|
||||
CHECK(csav_sl[0] == 30);
|
||||
CHECK(csav_sl[9] == 39);
|
||||
EXPECT_TRUE(csav_sl[0] == 30);
|
||||
EXPECT_TRUE(csav_sl[9] == 39);
|
||||
|
||||
CHECK(sav[4][0] == 40);
|
||||
CHECK(sav[4][9] == 49);
|
||||
EXPECT_TRUE(sav[4][0] == 40);
|
||||
EXPECT_TRUE(sav[4][9] == 49);
|
||||
}
|
||||
|
||||
TEST_CASE("strided_span_column_major")
|
||||
TEST(strided_span_tests, strided_span_column_major)
|
||||
{
|
||||
// strided_span may be used to accommodate more peculiar
|
||||
// use cases, such as column-major multidimensional array
|
||||
@@ -307,118 +370,123 @@ TEST_CASE("strided_span_column_major")
|
||||
strided_span<int, 2> cm_sav{cm_array, {{5, 3}, {1, 5}}};
|
||||
|
||||
// Accessing elements
|
||||
CHECK((cm_sav[{0, 0}] == 1));
|
||||
CHECK((cm_sav[{0, 1}] == 2));
|
||||
CHECK((cm_sav[{1, 0}] == 4));
|
||||
CHECK((cm_sav[{4, 2}] == 15));
|
||||
EXPECT_TRUE((cm_sav[{0, 0}] == 1));
|
||||
EXPECT_TRUE((cm_sav[{0, 1}] == 2));
|
||||
EXPECT_TRUE((cm_sav[{1, 0}] == 4));
|
||||
EXPECT_TRUE((cm_sav[{4, 2}] == 15));
|
||||
|
||||
// Slice
|
||||
strided_span<int, 1> cm_sl = cm_sav[3];
|
||||
|
||||
CHECK(cm_sl[0] == 10);
|
||||
CHECK(cm_sl[1] == 11);
|
||||
CHECK(cm_sl[2] == 12);
|
||||
EXPECT_TRUE(cm_sl[0] == 10);
|
||||
EXPECT_TRUE(cm_sl[1] == 11);
|
||||
EXPECT_TRUE(cm_sl[2] == 12);
|
||||
|
||||
// Section
|
||||
strided_span<int, 2> cm_sec = cm_sav.section({2, 1}, {3, 2});
|
||||
|
||||
CHECK((cm_sec.bounds().index_bounds() == multi_span_index<2>{3, 2}));
|
||||
CHECK((cm_sec[{0, 0}] == 8));
|
||||
CHECK((cm_sec[{0, 1}] == 9));
|
||||
CHECK((cm_sec[{1, 0}] == 11));
|
||||
CHECK((cm_sec[{2, 1}] == 15));
|
||||
EXPECT_TRUE((cm_sec.bounds().index_bounds() == multi_span_index<2>{3, 2}));
|
||||
EXPECT_TRUE((cm_sec[{0, 0}] == 8));
|
||||
EXPECT_TRUE((cm_sec[{0, 1}] == 9));
|
||||
EXPECT_TRUE((cm_sec[{1, 0}] == 11));
|
||||
EXPECT_TRUE((cm_sec[{2, 1}] == 15));
|
||||
}
|
||||
|
||||
TEST_CASE("strided_span_bounds")
|
||||
TEST(strided_span_tests, strided_span_bounds)
|
||||
{
|
||||
int arr[] = {0, 1, 2, 3};
|
||||
multi_span<int> av(arr);
|
||||
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. strided_span_bounds";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
{
|
||||
// incorrect sections
|
||||
|
||||
CHECK_THROWS_AS(av.section(0, 0)[0], fail_fast);
|
||||
CHECK_THROWS_AS(av.section(1, 0)[0], fail_fast);
|
||||
CHECK_THROWS_AS(av.section(1, 1)[1], fail_fast);
|
||||
EXPECT_DEATH(av.section(0, 0)[0], deathstring);
|
||||
EXPECT_DEATH(av.section(1, 0)[0], deathstring);
|
||||
EXPECT_DEATH(av.section(1, 1)[1], deathstring);
|
||||
|
||||
CHECK_THROWS_AS(av.section(2, 5), fail_fast);
|
||||
CHECK_THROWS_AS(av.section(5, 2), fail_fast);
|
||||
CHECK_THROWS_AS(av.section(5, 0), fail_fast);
|
||||
CHECK_THROWS_AS(av.section(0, 5), fail_fast);
|
||||
CHECK_THROWS_AS(av.section(5, 5), fail_fast);
|
||||
EXPECT_DEATH(av.section(2, 5), deathstring);
|
||||
EXPECT_DEATH(av.section(5, 2), deathstring);
|
||||
EXPECT_DEATH(av.section(5, 0), deathstring);
|
||||
EXPECT_DEATH(av.section(0, 5), deathstring);
|
||||
EXPECT_DEATH(av.section(5, 5), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// zero stride
|
||||
strided_span<int, 1> sav{av, {{4}, {}}};
|
||||
CHECK(sav[0] == 0);
|
||||
CHECK(sav[3] == 0);
|
||||
CHECK_THROWS_AS(sav[4], fail_fast);
|
||||
EXPECT_TRUE(sav[0] == 0);
|
||||
EXPECT_TRUE(sav[3] == 0);
|
||||
EXPECT_DEATH(sav[4], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// zero extent
|
||||
strided_span<int, 1> sav{av, {{}, {1}}};
|
||||
CHECK_THROWS_AS(sav[0], fail_fast);
|
||||
EXPECT_DEATH(sav[0], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// zero extent and stride
|
||||
strided_span<int, 1> sav{av, {{}, {}}};
|
||||
CHECK_THROWS_AS(sav[0], fail_fast);
|
||||
EXPECT_DEATH(sav[0], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// strided array ctor with matching strided bounds
|
||||
strided_span<int, 1> sav{arr, {4, 1}};
|
||||
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{4});
|
||||
CHECK(sav[3] == 3);
|
||||
CHECK_THROWS_AS(sav[4], fail_fast);
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{4});
|
||||
EXPECT_TRUE(sav[3] == 3);
|
||||
EXPECT_DEATH(sav[4], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// strided array ctor with smaller strided bounds
|
||||
strided_span<int, 1> sav{arr, {2, 1}};
|
||||
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav[1] == 1);
|
||||
CHECK_THROWS_AS(sav[2], fail_fast);
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav[1] == 1);
|
||||
EXPECT_DEATH(sav[2], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// strided array ctor with fitting irregular bounds
|
||||
strided_span<int, 1> sav{arr, {2, 3}};
|
||||
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
CHECK(sav[0] == 0);
|
||||
CHECK(sav[1] == 3);
|
||||
CHECK_THROWS_AS(sav[2], fail_fast);
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav[0] == 0);
|
||||
EXPECT_TRUE(sav[1] == 3);
|
||||
EXPECT_DEATH(sav[2], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// bounds cross data boundaries - from static arrays
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{arr, {3, 2}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{arr, {3, 3}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{arr, {4, 5}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{arr, {5, 1}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{arr, {5, 5}}), fail_fast);
|
||||
EXPECT_DEATH((strided_span<int, 1>{arr, {3, 2}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{arr, {3, 3}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{arr, {4, 5}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{arr, {5, 1}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{arr, {5, 5}}), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// bounds cross data boundaries - from array view
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av, {3, 2}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av, {3, 3}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av, {4, 5}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av, {5, 1}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av, {5, 5}}), fail_fast);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av, {3, 2}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av, {3, 3}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av, {4, 5}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av, {5, 1}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av, {5, 5}}), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// bounds cross data boundaries - from dynamic arrays
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {3, 2}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {3, 3}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {4, 5}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {5, 1}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {5, 5}}), fail_fast);
|
||||
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 2, {2, 2}}), fail_fast);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {3, 2}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {3, 3}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {4, 5}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {5, 1}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {5, 5}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 2, {2, 2}}), deathstring);
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
@@ -445,11 +513,16 @@ TEST_CASE("strided_span_bounds")
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("strided_span_type_conversion")
|
||||
TEST(strided_span_tests, strided_span_type_conversion)
|
||||
{
|
||||
int arr[] = {0, 1, 2, 3};
|
||||
multi_span<int> av(arr);
|
||||
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. strided_span_type_conversion";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
{
|
||||
strided_span<int, 1> sav{av.data(), av.size(), {av.size() / 2, 2}};
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
@@ -470,10 +543,10 @@ TEST_CASE("strided_span_type_conversion")
|
||||
strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}};
|
||||
strided_span<const byte, 2> sav2{bytes.data(), bytes.size(), bounds};
|
||||
strided_span<const int, 2> sav3 = sav2.as_strided_span<const int>();
|
||||
CHECK(sav3[0][0] == 0);
|
||||
CHECK(sav3[1][0] == 2);
|
||||
CHECK_THROWS_AS(sav3[1][1], fail_fast);
|
||||
CHECK_THROWS_AS(sav3[0][1], fail_fast);
|
||||
EXPECT_TRUE(sav3[0][0] == 0);
|
||||
EXPECT_TRUE(sav3[1][0] == 2);
|
||||
EXPECT_DEATH(sav3[1][1], deathstring);
|
||||
EXPECT_DEATH(sav3[0][1], deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with regular strides - from multi_span
|
||||
@@ -483,10 +556,10 @@ TEST_CASE("strided_span_type_conversion")
|
||||
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||
strided_span<int, 2> sav3 = sav2.as_strided_span<int>();
|
||||
CHECK(sav3[0][0] == 0);
|
||||
CHECK(sav3[1][0] == 2);
|
||||
CHECK_THROWS_AS(sav3[1][1], fail_fast);
|
||||
CHECK_THROWS_AS(sav3[0][1], fail_fast);
|
||||
EXPECT_TRUE(sav3[0][0] == 0);
|
||||
EXPECT_TRUE(sav3[1][0] == 2);
|
||||
EXPECT_DEATH(sav3[1][1], deathstring);
|
||||
EXPECT_DEATH(sav3[0][1], deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with not enough elements - last dimension of the array is too small
|
||||
@@ -495,7 +568,7 @@ TEST_CASE("strided_span_type_conversion")
|
||||
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with not enough elements - strides are too small
|
||||
@@ -504,7 +577,7 @@ TEST_CASE("strided_span_type_conversion")
|
||||
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with not enough elements - last dimension does not divide by the new
|
||||
@@ -514,7 +587,7 @@ TEST_CASE("strided_span_type_conversion")
|
||||
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with not enough elements - strides does not divide by the new
|
||||
@@ -524,82 +597,63 @@ TEST_CASE("strided_span_type_conversion")
|
||||
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with irregular strides - from raw data
|
||||
{
|
||||
strided_bounds<1> bounds{bytes.size() / 2, 2};
|
||||
strided_span<const byte, 1> sav2{bytes.data(), bytes.size(), bounds};
|
||||
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with irregular strides - from multi_span
|
||||
{
|
||||
strided_bounds<1> bounds{bytes.size() / 2, 2};
|
||||
strided_span<const byte, 1> sav2{bytes, bounds};
|
||||
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("empty_strided_spans")
|
||||
TEST(strided_span_tests, empty_strided_spans)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. empty_strided_spans";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
{
|
||||
multi_span<int, 0> empty_av(nullptr);
|
||||
strided_span<int, 1> empty_sav{empty_av, {0, 1}};
|
||||
|
||||
CHECK(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
|
||||
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);
|
||||
EXPECT_TRUE(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
|
||||
EXPECT_TRUE(empty_sav.empty());
|
||||
EXPECT_DEATH(empty_sav[0], deathstring);
|
||||
EXPECT_DEATH(empty_sav.begin()[0], deathstring);
|
||||
EXPECT_DEATH(empty_sav.cbegin()[0], deathstring);
|
||||
|
||||
for (const auto& v : empty_sav) {
|
||||
(void) v;
|
||||
CHECK(false);
|
||||
EXPECT_TRUE(false);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
strided_span<int, 1> empty_sav{nullptr, 0, {0, 1}};
|
||||
|
||||
CHECK(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
|
||||
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);
|
||||
EXPECT_TRUE(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
|
||||
EXPECT_DEATH(empty_sav[0], deathstring);
|
||||
EXPECT_DEATH(empty_sav.begin()[0], deathstring);
|
||||
EXPECT_DEATH(empty_sav.cbegin()[0], deathstring);
|
||||
|
||||
for (const auto& v : empty_sav) {
|
||||
(void) v;
|
||||
CHECK(false);
|
||||
EXPECT_TRUE(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void iterate_every_other_element(multi_span<int, dynamic_range> av)
|
||||
{
|
||||
// pick every other element
|
||||
|
||||
auto length = av.size() / 2;
|
||||
#if _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});
|
||||
#endif
|
||||
strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);
|
||||
|
||||
CHECK(strided.size() == length);
|
||||
CHECK(strided.bounds().index_bounds()[0] == length);
|
||||
for (auto i = 0; i < strided.size(); ++i) {
|
||||
CHECK(strided[i] == av[2 * i + 1]);
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
for (auto num : strided) {
|
||||
CHECK(num == av[2 * idx + 1]);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("strided_span_section_iteration")
|
||||
TEST(strided_span_tests, strided_span_section_iteration)
|
||||
{
|
||||
int arr[8] = {4, 0, 5, 1, 6, 2, 7, 3};
|
||||
|
||||
@@ -616,7 +670,7 @@ TEST_CASE("strided_span_section_iteration")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("dynamic_strided_span_section_iteration")
|
||||
TEST(strided_span_tests, dynamic_strided_span_section_iteration)
|
||||
{
|
||||
auto arr = new int[8];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
@@ -630,33 +684,7 @@ TEST_CASE("dynamic_strided_span_section_iteration")
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
|
||||
{
|
||||
const int expected[6] = {2, 3, 10, 11, 18, 19};
|
||||
auto section = av.section({0, 1, 0}, {3, 1, 2});
|
||||
|
||||
for (auto i = 0; i < section.extent<0>(); ++i) {
|
||||
for (auto j = 0; j < section.extent<1>(); ++j)
|
||||
for (auto k = 0; k < section.extent<2>(); ++k) {
|
||||
auto idx = multi_span_index<3>{i, j, k}; // avoid braces in the CHECK macro
|
||||
CHECK(section[idx] == expected[2 * i + 2 * j + k]);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i = 0; i < section.extent<0>(); ++i) {
|
||||
for (auto j = 0; j < section.extent<1>(); ++j)
|
||||
for (auto k = 0; k < section.extent<2>(); ++k)
|
||||
CHECK(section[i][j][k] == expected[2 * i + 2 * j + k]);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (const auto num : section) {
|
||||
CHECK(num == expected[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("strided_span_section_iteration_3d")
|
||||
TEST(strided_span_tests, strided_span_section_iteration_3d)
|
||||
{
|
||||
int arr[3][4][2]{};
|
||||
for (auto i = 0; i < 3; ++i) {
|
||||
@@ -670,7 +698,7 @@ TEST_CASE("strided_span_section_iteration_3d")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("dynamic_strided_span_section_iteration_3d")
|
||||
TEST(strided_span_tests, dynamic_strided_span_section_iteration_3d)
|
||||
{
|
||||
const auto height = 12, width = 2;
|
||||
const auto size = height * width;
|
||||
@@ -702,8 +730,13 @@ TEST_CASE("dynamic_strided_span_section_iteration_3d")
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
TEST_CASE("strided_span_conversion")
|
||||
TEST(strided_span_tests, strided_span_conversion)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. strided_span_conversion";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
// get an multi_span of 'c' values from the list of X's
|
||||
|
||||
struct X
|
||||
@@ -720,10 +753,10 @@ 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);
|
||||
EXPECT_TRUE(av.bounds().index_bounds()[0] == 4);
|
||||
EXPECT_TRUE(av.bounds().index_bounds()[1] == 12);
|
||||
|
||||
// get the last 4 columns
|
||||
auto section = av.section({0, 2 * s}, {4, s}); // { { arr[0].c[0], arr[0].c[1], arr[0].c[2],
|
||||
@@ -733,8 +766,8 @@ TEST_CASE("strided_span_conversion")
|
||||
// convert to array 4x1 array of integers
|
||||
auto cs = section.as_strided_span<int>(); // { { arr[0].c }, {arr[1].c } , ... }
|
||||
|
||||
CHECK(cs.bounds().index_bounds()[0] == 4);
|
||||
CHECK(cs.bounds().index_bounds()[1] == 1);
|
||||
EXPECT_TRUE(cs.bounds().index_bounds()[0] == 4);
|
||||
EXPECT_TRUE(cs.bounds().index_bounds()[1] == 1);
|
||||
|
||||
// transpose to 1x4 array
|
||||
strided_bounds<2> reverse_bounds{
|
||||
@@ -746,12 +779,12 @@ TEST_CASE("strided_span_conversion")
|
||||
// slice to get a one-dimensional array of c's
|
||||
strided_span<int, 1> result = transposed[0];
|
||||
|
||||
CHECK(result.bounds().index_bounds()[0] == 4);
|
||||
CHECK_THROWS_AS(result.bounds().index_bounds()[1], fail_fast);
|
||||
EXPECT_TRUE(result.bounds().index_bounds()[0] == 4);
|
||||
EXPECT_DEATH(result.bounds().index_bounds()[1], deathstring);
|
||||
|
||||
int i = 0;
|
||||
for (auto& num : result) {
|
||||
CHECK(num == arr[i].c);
|
||||
EXPECT_TRUE(num == arr[i].c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
+376
-328
File diff suppressed because it is too large
Load Diff
@@ -1,18 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch/catch.hpp>
|
||||
+42
-33
@@ -14,7 +14,7 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/gsl_util> // for narrow, finally, narrow_cast, narrowing_e...
|
||||
|
||||
@@ -23,98 +23,107 @@
|
||||
#include <limits> // for numeric_limits
|
||||
#include <stdint.h> // for uint32_t, int32_t
|
||||
#include <type_traits> // for is_same
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
TEST_CASE("sanity check for gsl::index typedef")
|
||||
namespace
|
||||
{
|
||||
void f(int& i) { i += 1; }
|
||||
static int j = 0;
|
||||
void g() { j += 1; }
|
||||
}
|
||||
|
||||
|
||||
TEST(utils_tests, sanity_check_for_gsl_index_typedef)
|
||||
{
|
||||
static_assert(std::is_same<gsl::index, std::ptrdiff_t>::value,
|
||||
"gsl::index represents wrong arithmetic type");
|
||||
}
|
||||
|
||||
void f(int& i) { i += 1; }
|
||||
|
||||
TEST_CASE("finally_lambda")
|
||||
TEST(utils_tests, finally_lambda)
|
||||
{
|
||||
int i = 0;
|
||||
{
|
||||
auto _ = finally([&]() { f(i); });
|
||||
CHECK(i == 0);
|
||||
EXPECT_TRUE(i == 0);
|
||||
}
|
||||
CHECK(i == 1);
|
||||
EXPECT_TRUE(i == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("finally_lambda_move")
|
||||
TEST(utils_tests, finally_lambda_move)
|
||||
{
|
||||
int i = 0;
|
||||
{
|
||||
auto _1 = finally([&]() { f(i); });
|
||||
{
|
||||
auto _2 = std::move(_1);
|
||||
CHECK(i == 0);
|
||||
EXPECT_TRUE(i == 0);
|
||||
}
|
||||
CHECK(i == 1);
|
||||
EXPECT_TRUE(i == 1);
|
||||
{
|
||||
auto _2 = std::move(_1);
|
||||
CHECK(i == 1);
|
||||
EXPECT_TRUE(i == 1);
|
||||
}
|
||||
CHECK(i == 1);
|
||||
EXPECT_TRUE(i == 1);
|
||||
}
|
||||
CHECK(i == 1);
|
||||
EXPECT_TRUE(i == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("finally_function_with_bind")
|
||||
TEST(utils_tests, finally_function_with_bind)
|
||||
{
|
||||
int i = 0;
|
||||
{
|
||||
auto _ = finally(std::bind(&f, std::ref(i)));
|
||||
CHECK(i == 0);
|
||||
EXPECT_TRUE(i == 0);
|
||||
}
|
||||
CHECK(i == 1);
|
||||
EXPECT_TRUE(i == 1);
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
void g() { j += 1; }
|
||||
TEST_CASE("finally_function_ptr")
|
||||
TEST(utils_tests, finally_function_ptr)
|
||||
{
|
||||
j = 0;
|
||||
{
|
||||
auto _ = finally(&g);
|
||||
CHECK(j == 0);
|
||||
EXPECT_TRUE(j == 0);
|
||||
}
|
||||
CHECK(j == 1);
|
||||
EXPECT_TRUE(j == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("narrow_cast")
|
||||
TEST(utils_tests, narrow_cast)
|
||||
{
|
||||
int n = 120;
|
||||
char c = narrow_cast<char>(n);
|
||||
CHECK(c == 120);
|
||||
EXPECT_TRUE(c == 120);
|
||||
|
||||
n = 300;
|
||||
unsigned char uc = narrow_cast<unsigned char>(n);
|
||||
CHECK(uc == 44);
|
||||
EXPECT_TRUE(uc == 44);
|
||||
}
|
||||
|
||||
TEST_CASE("narrow")
|
||||
TEST(utils_tests, narrow)
|
||||
{
|
||||
int n = 120;
|
||||
const char c = narrow<char>(n);
|
||||
CHECK(c == 120);
|
||||
EXPECT_TRUE(c == 120);
|
||||
|
||||
n = 300;
|
||||
CHECK_THROWS_AS(narrow<char>(n), narrowing_error);
|
||||
EXPECT_THROW(narrow<char>(n), narrowing_error);
|
||||
|
||||
const auto int32_max = std::numeric_limits<int32_t>::max();
|
||||
const auto int32_min = std::numeric_limits<int32_t>::min();
|
||||
|
||||
CHECK(narrow<uint32_t>(int32_t(0)) == 0);
|
||||
CHECK(narrow<uint32_t>(int32_t(1)) == 1);
|
||||
CHECK(narrow<uint32_t>(int32_max) == static_cast<uint32_t>(int32_max));
|
||||
EXPECT_TRUE(narrow<uint32_t>(int32_t(0)) == 0);
|
||||
EXPECT_TRUE(narrow<uint32_t>(int32_t(1)) == 1);
|
||||
EXPECT_TRUE(narrow<uint32_t>(int32_max) == static_cast<uint32_t>(int32_max));
|
||||
|
||||
CHECK_THROWS_AS(narrow<uint32_t>(int32_t(-1)), narrowing_error);
|
||||
CHECK_THROWS_AS(narrow<uint32_t>(int32_min), narrowing_error);
|
||||
EXPECT_THROW(narrow<uint32_t>(int32_t(-1)), narrowing_error);
|
||||
EXPECT_THROW(narrow<uint32_t>(int32_min), narrowing_error);
|
||||
|
||||
n = -42;
|
||||
CHECK_THROWS_AS(narrow<unsigned>(n), narrowing_error);
|
||||
EXPECT_THROW(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