mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Merge remote-tracking branch 'origin/main' into final_action-revision
This commit is contained in:
commit
8840d87199
2
.github/workflows/android.yml
vendored
2
.github/workflows/android.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
|||||||
echo "Emulator starting"
|
echo "Emulator starting"
|
||||||
|
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: cmake -Werror=dev -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=16 -DANDROID_ABI=x86_64 -DCMAKE_BUILD_TYPE=Debug ..
|
run: cmake -Werror=dev -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/25.0.8775105/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=16 -DANDROID_ABI=x86_64 -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build . --parallel
|
run: cmake --build . --parallel
|
||||||
|
6
.github/workflows/ios.yml
vendored
6
.github/workflows/ios.yml
vendored
@ -25,11 +25,11 @@ jobs:
|
|||||||
-GXcode \
|
-GXcode \
|
||||||
-DCMAKE_SYSTEM_NAME=iOS \
|
-DCMAKE_SYSTEM_NAME=iOS \
|
||||||
"-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
|
"-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
|
||||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=8 \
|
-DCMAKE_OSX_DEPLOYMENT_TARGET=9 \
|
||||||
-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
|
-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
|
||||||
"-DMACOSX_BUNDLE_GUI_IDENTIFIER=GSL.\$(EXECUTABLE_NAME)" \
|
"-DMACOSX_BUNDLE_GUI_IDENTIFIER=GSL.\$(EXECUTABLE_NAME)" \
|
||||||
-DMACOSX_BUNDLE_BUNDLE_VERSION=3.0.1 \
|
-DMACOSX_BUNDLE_BUNDLE_VERSION=3.1.0 \
|
||||||
-DMACOSX_BUNDLE_SHORT_VERSION_STRING=3.0.1 \
|
-DMACOSX_BUNDLE_SHORT_VERSION_STRING=3.1.0 \
|
||||||
..
|
..
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
|
337
.travis.yml
337
.travis.yml
@ -1,337 +0,0 @@
|
|||||||
|
|
||||||
language: cpp
|
|
||||||
notifications:
|
|
||||||
email: false
|
|
||||||
|
|
||||||
# Use Linux unless specified otherwise
|
|
||||||
os: linux
|
|
||||||
dist: bionic
|
|
||||||
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- ${TRAVIS_BUILD_DIR}/deps
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- name: Latest # Compiler with the latest major version
|
|
||||||
- name: Previous # Compilers with the major version Latest - 1
|
|
||||||
- name: Validation # run other jobs
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
include:
|
|
||||||
|
|
||||||
##########################################################################
|
|
||||||
# Validate CMake configuration
|
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
- 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 10.3
|
|
||||||
- name: AppleClang Xcode-10.3 C++14 Debug
|
|
||||||
stage: Previous
|
|
||||||
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.4
|
|
||||||
- name: AppleClang Xcode-11.4 C++17 Debug
|
|
||||||
stage: Latest
|
|
||||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
|
|
||||||
os: osx
|
|
||||||
osx_image: xcode11.4
|
|
||||||
- name: AppleClang Xcode-11.4 C++17 Release
|
|
||||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
|
|
||||||
os: osx
|
|
||||||
osx_image: xcode11.4
|
|
||||||
- name: AppleClang Xcode-11.4 C++14 Debug
|
|
||||||
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
|
|
||||||
os: osx
|
|
||||||
osx_image: xcode11.4
|
|
||||||
- name: AppleClang Xcode-11.4 C++14 Release
|
|
||||||
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
|
|
||||||
os: osx
|
|
||||||
osx_image: xcode11.4
|
|
||||||
|
|
||||||
##########################################################################
|
|
||||||
# Clang on Linux
|
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
# Clang 9
|
|
||||||
- name: Clang-9 C++14 Debug
|
|
||||||
stage: Previous
|
|
||||||
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 8
|
|
||||||
- name: GCC-8 C++14 Debug
|
|
||||||
stage: Previous
|
|
||||||
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:
|
|
||||||
############################################################################
|
|
||||||
# Install a different CMake version (or several)
|
|
||||||
############################################################################
|
|
||||||
- |
|
|
||||||
# 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
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
# [linux]: Install the right version of libc++
|
|
||||||
# Based on https://github.com/ldionne/hana/blob/master/.travis.yml
|
|
||||||
############################################################################
|
|
||||||
- |
|
|
||||||
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 [[ "${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";
|
|
||||||
elif [[ "${CXX}" == "clang++-3.9" ]]; then LLVM_VERSION="3.9.1";
|
|
||||||
fi
|
|
||||||
LLVM_URL="http://llvm.org/releases/${LLVM_VERSION}/llvm-${LLVM_VERSION}.src.tar.xz"
|
|
||||||
LIBCXX_URL="http://llvm.org/releases/${LLVM_VERSION}/libcxx-${LLVM_VERSION}.src.tar.xz"
|
|
||||||
LIBCXXABI_URL="http://llvm.org/releases/${LLVM_VERSION}/libcxxabi-${LLVM_VERSION}.src.tar.xz"
|
|
||||||
mkdir -p llvm llvm/build llvm/projects/libcxx llvm/projects/libcxxabi
|
|
||||||
travis_retry wget -O - ${LLVM_URL} | tar --strip-components=1 -xJ -C llvm
|
|
||||||
travis_retry wget -O - ${LIBCXX_URL} | tar --strip-components=1 -xJ -C llvm/projects/libcxx
|
|
||||||
travis_retry wget -O - ${LIBCXXABI_URL} | tar --strip-components=1 -xJ -C llvm/projects/libcxxabi
|
|
||||||
(cd llvm/build && cmake .. -DCMAKE_INSTALL_PREFIX=${LLVM_INSTALL})
|
|
||||||
(cd llvm/build/projects/libcxx && make install -j2)
|
|
||||||
(cd llvm/build/projects/libcxxabi && make install -j2)
|
|
||||||
export CXXFLAGS="-isystem ${LLVM_INSTALL}/include/c++/v1"
|
|
||||||
export LDFLAGS="-L ${LLVM_INSTALL}/lib -l c++ -l c++abi"
|
|
||||||
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${LLVM_INSTALL}/lib"
|
|
||||||
fi
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- |
|
|
||||||
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}
|
|
@ -4,7 +4,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
|||||||
include(guidelineSupportLibrary)
|
include(guidelineSupportLibrary)
|
||||||
|
|
||||||
project(GSL
|
project(GSL
|
||||||
VERSION 3.1.0
|
VERSION 4.0.0
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
)
|
)
|
||||||
|
|
||||||
|
40
README.md
40
README.md
@ -30,14 +30,14 @@ not_null | ☑ | restricts a pointer / smart po
|
|||||||
span | ☑ | a view over a contiguous sequence of memory. Based on the standardized verison of `std::span`, however `gsl::span` enforces bounds checking. See the [wiki](https://github.com/microsoft/GSL/wiki/gsl::span-and-std::span) for additional information.
|
span | ☑ | a view over a contiguous sequence of memory. Based on the standardized verison of `std::span`, however `gsl::span` enforces bounds checking. See the [wiki](https://github.com/microsoft/GSL/wiki/gsl::span-and-std::span) for additional information.
|
||||||
span_p | ☐ | spans a range starting from a pointer to the first place for which the predicate is true
|
span_p | ☐ | spans a range starting from a pointer to the first place for which the predicate is true
|
||||||
basic_zstring | ☑ | A pointer to a C-string (zero-terminated array) with a templated char type
|
basic_zstring | ☑ | A pointer to a C-string (zero-terminated array) with a templated char type
|
||||||
zstring | ☑ | An alias to `basic_zstring` with a char type of char
|
zstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of char
|
||||||
czstring | ☑ | An alias to `basic_zstring` with a char type of const char
|
czstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of const char
|
||||||
wzstring | ☑ | An alias to `basic_zstring` with a char type of wchar_t
|
wzstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of wchar_t
|
||||||
cwzstring | ☑ | An alias to `basic_zstring` with a char type of const wchar_t
|
cwzstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of const wchar_t
|
||||||
u16zstring | ☑ | An alias to `basic_zstring` with a char type of char16_t
|
u16zstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of char16_t
|
||||||
cu16zstring | ☑ | An alias to `basic_zstring` with a char type of const char16_t
|
cu16zstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of const char16_t
|
||||||
u32zstring | ☑ | An alias to `basic_zstring` with a char type of char32_t
|
u32zstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of char32_t
|
||||||
cu32zstring | ☑ | An alias to `basic_zstring` with a char type of const char32_t
|
cu32zstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of const char32_t
|
||||||
[**2. Owners**][cg-owners] | |
|
[**2. Owners**][cg-owners] | |
|
||||||
unique_ptr | ☑ | an alias to `std::unique_ptr`
|
unique_ptr | ☑ | an alias to `std::unique_ptr`
|
||||||
shared_ptr | ☑ | an alias to `std::shared_ptr`
|
shared_ptr | ☑ | an alias to `std::shared_ptr`
|
||||||
@ -85,17 +85,25 @@ This is based on [CppCoreGuidelines semi-specification](https://github.com/isocp
|
|||||||
[cg-concepts]: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#gslconcept-concepts
|
[cg-concepts]: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#gslconcept-concepts
|
||||||
|
|
||||||
# Quick Start
|
# Quick Start
|
||||||
## Supported Compilers
|
## Supported Compilers / Toolsets
|
||||||
The GSL officially supports the current and previous major release of MSVC, GCC, Clang, and XCode's Apple-Clang.
|
The GSL officially supports the latest and previous major versions of VS with MSVC & LLVM, GCC, Clang, and XCode with Apple-Clang.
|
||||||
See our latest test results for the most up-to-date list of supported configurations.
|
Within these two major versions, we try to target the latest minor updates / revisions (although this may be affected by
|
||||||
|
delays between a toolchain's release and when it becomes widely available for use).
|
||||||
|
Below is a table showing the versions currently being tested.
|
||||||
|
|
||||||
Compiler |Toolset Versions Currently Tested
|
Compiler |Toolset Versions Currently Tested
|
||||||
:------- |--:
|
:------- |--:
|
||||||
XCode |11.4 & 10.3
|
XCode | 13.2.1 & 12.5.1
|
||||||
GCC |9 & 8
|
GCC | 11[^1] & 10[^2]
|
||||||
Clang |11 & 10
|
Clang | 12[^2] & 11[^2]
|
||||||
Visual Studio with MSVC | VS2017 (15.9) & VS2019 (16.4)
|
Visual Studio with MSVC | VS2022[^3] & VS2019[^4]
|
||||||
Visual Studio with LLVM | VS2017 (Clang 9) & VS2019 (Clang 10)
|
Visual Studio with LLVM | VS2022[^3] & VS2019[^4]
|
||||||
|
|
||||||
|
|
||||||
|
[^1]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26).
|
||||||
|
[^2]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26). Should be the version specified [here](https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-Readme.md#language-and-runtime).
|
||||||
|
[^3]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26). Should be the version specified [here](https://github.com/actions/virtual-environments/blob/main/images/win/Windows2022-Readme.md#visual-studio-enterprise-2022).
|
||||||
|
[^4]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26). Should be the version specified [here](https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md#visual-studio-enterprise-2019).
|
||||||
|
|
||||||
---
|
---
|
||||||
If you successfully port GSL to another platform, we would love to hear from you!
|
If you successfully port GSL to another platform, we would love to hear from you!
|
||||||
|
41
SECURITY.md
Normal file
41
SECURITY.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
|
||||||
|
|
||||||
|
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
|
||||||
|
|
||||||
|
## Reporting Security Issues
|
||||||
|
|
||||||
|
**Please do not report security vulnerabilities through public GitHub issues.**
|
||||||
|
|
||||||
|
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
|
||||||
|
|
||||||
|
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
|
||||||
|
|
||||||
|
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
|
||||||
|
|
||||||
|
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
|
||||||
|
|
||||||
|
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
||||||
|
* Full paths of source file(s) related to the manifestation of the issue
|
||||||
|
* The location of the affected source code (tag/branch/commit or direct URL)
|
||||||
|
* Any special configuration required to reproduce the issue
|
||||||
|
* Step-by-step instructions to reproduce the issue
|
||||||
|
* Proof-of-concept or exploit code (if possible)
|
||||||
|
* Impact of the issue, including how an attacker might exploit the issue
|
||||||
|
|
||||||
|
This information will help us triage your report more quickly.
|
||||||
|
|
||||||
|
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
|
||||||
|
|
||||||
|
## Preferred Languages
|
||||||
|
|
||||||
|
We prefer all communications to be in English.
|
||||||
|
|
||||||
|
## Policy
|
||||||
|
|
||||||
|
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
|
||||||
|
|
||||||
|
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
@ -4,65 +4,63 @@ trigger:
|
|||||||
pr:
|
pr:
|
||||||
autoCancel: true
|
autoCancel: true
|
||||||
|
|
||||||
# GCC
|
|
||||||
stages:
|
stages:
|
||||||
- stage: GCC
|
- stage: GCC
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
variables:
|
|
||||||
- name: CC
|
|
||||||
value: gcc
|
|
||||||
- name: CXX
|
|
||||||
value: g++
|
|
||||||
jobs:
|
jobs:
|
||||||
- template: ./pipelines/jobs.yml
|
- template: ./pipelines/jobs.yml
|
||||||
parameters:
|
parameters:
|
||||||
jobName: 'Validate GCC latest'
|
compiler: gcc
|
||||||
imageName: ubuntu-20.04
|
image: ubuntu-20.04
|
||||||
- template: ./pipelines/jobs.yml
|
compilerVersions: [ 11, 10 ]
|
||||||
parameters:
|
setupfile: 'setup_gcc.yml'
|
||||||
jobName: 'Validate GCC Previous'
|
|
||||||
imageName: ubuntu-18.04
|
|
||||||
|
|
||||||
# Clang
|
|
||||||
- stage: Clang
|
- stage: Clang
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
variables:
|
|
||||||
- name: CC
|
|
||||||
value: clang
|
|
||||||
- name: CXX
|
|
||||||
value: clang++
|
|
||||||
jobs:
|
jobs:
|
||||||
- template: ./pipelines/jobs.yml
|
- template: ./pipelines/jobs.yml
|
||||||
parameters:
|
parameters:
|
||||||
jobName: 'Validate Clang latest'
|
compiler: clang
|
||||||
imageName: ubuntu-20.04
|
image: ubuntu-20.04
|
||||||
- template: ./pipelines/jobs.yml
|
compilerVersions: [ 12, 11 ]
|
||||||
parameters:
|
setupfile: 'setup_clang.yml'
|
||||||
jobName: 'Validate Clang Previous'
|
|
||||||
imageName: ubuntu-18.04
|
|
||||||
|
|
||||||
# MSVC
|
- stage: Xcode
|
||||||
- stage: MSVC
|
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: ./pipelines/jobs.yml
|
- template: ./pipelines/jobs.yml
|
||||||
parameters:
|
parameters:
|
||||||
jobName: 'Validate MSVC latest'
|
compiler: 'Xcode'
|
||||||
imageName: windows-latest
|
image: macOS-11
|
||||||
- template: ./pipelines/jobs.yml
|
compilerVersions: [ '12.5.1', '13.2.1' ]
|
||||||
parameters:
|
setupfile: 'setup_apple.yml'
|
||||||
jobName: 'Validate MSVC Previous'
|
|
||||||
imageName: vs2017-win2016
|
|
||||||
|
|
||||||
# Apple-Clang
|
- stage: VS_MSVC
|
||||||
- stage: Apple_Clang
|
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: ./pipelines/jobs.yml
|
- template: ./pipelines/jobs.yml
|
||||||
parameters:
|
parameters:
|
||||||
jobName: 'Validate Apple-Clang latest'
|
compiler: 'VS2019 (MSVC)'
|
||||||
imageName: macos-10.15
|
compilerVersions: [ 'default' ]
|
||||||
|
image: windows-2019
|
||||||
- template: ./pipelines/jobs.yml
|
- template: ./pipelines/jobs.yml
|
||||||
parameters:
|
parameters:
|
||||||
jobName: 'Validate Apple-Clang Previous'
|
compiler: 'VS2022 (MSVC)'
|
||||||
imageName: macos-10.14
|
compilerVersions: [ 'default' ]
|
||||||
|
image: windows-2022
|
||||||
|
|
||||||
|
- stage: VS_LLVM
|
||||||
|
dependsOn: []
|
||||||
|
jobs:
|
||||||
|
- template: ./pipelines/jobs.yml
|
||||||
|
parameters:
|
||||||
|
compiler: 'VS2019 (LLVM)'
|
||||||
|
compilerVersions: [ 'default' ]
|
||||||
|
image: windows-2019
|
||||||
|
extraCmakeArgs: '-T ClangCL'
|
||||||
|
- template: ./pipelines/jobs.yml
|
||||||
|
parameters:
|
||||||
|
compiler: 'VS2022 (LLVM)'
|
||||||
|
compilerVersions: [ 'default' ]
|
||||||
|
image: windows-2022
|
||||||
|
extraCmakeArgs: '-T ClangCL'
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
#ifndef GSL_ALGORITHM_H
|
#ifndef GSL_ALGORITHM_H
|
||||||
#define GSL_ALGORITHM_H
|
#define GSL_ALGORITHM_H
|
||||||
|
|
||||||
#include <gsl/assert> // for Expects
|
#include "assert" // for Expects
|
||||||
#include <gsl/span> // for dynamic_extent, span
|
#include "span" // for dynamic_extent, span
|
||||||
|
|
||||||
#include <algorithm> // for copy_n
|
#include <algorithm> // for copy_n
|
||||||
#include <cstddef> // for ptrdiff_t
|
#include <cstddef> // for ptrdiff_t
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
// Currently terminate is a no-op in this mode, so we add termination behavior back
|
// Currently terminate is a no-op in this mode, so we add termination behavior back
|
||||||
//
|
//
|
||||||
#if defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
|
#if defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
|
||||||
|
#define GSL_KERNEL_MODE
|
||||||
|
|
||||||
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
|
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
|
@ -17,16 +17,16 @@
|
|||||||
#ifndef GSL_GSL_H
|
#ifndef GSL_GSL_H
|
||||||
#define GSL_GSL_H
|
#define GSL_GSL_H
|
||||||
|
|
||||||
#include <gsl/algorithm> // copy
|
#include "algorithm" // copy
|
||||||
#include <gsl/assert> // Ensures/Expects
|
#include "assert" // Ensures/Expects
|
||||||
#include <gsl/byte> // byte
|
#include "byte" // byte
|
||||||
#include <gsl/pointers> // owner, not_null
|
#include "pointers" // owner, not_null
|
||||||
#include <gsl/span> // span
|
#include "span" // span
|
||||||
#include <gsl/string_span> // zstring, string_span, zstring_builder...
|
#include "string_span" // zstring, string_span, zstring_builder...
|
||||||
#include <gsl/util> // finally()/narrow_cast()...
|
#include "util" // finally()/narrow_cast()...
|
||||||
|
|
||||||
#ifdef __cpp_exceptions
|
#ifdef __cpp_exceptions
|
||||||
#include <gsl/narrow> // narrow()
|
#include "narrow" // narrow()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // GSL_GSL_H
|
#endif // GSL_GSL_H
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#pragma message("This header will soon be removed. Use <gsl/algorithm> instead of <gsl/gsl_algorithm>")
|
#pragma message( \
|
||||||
#include <gsl/algorithm>
|
"This header will soon be removed. Use <gsl/algorithm> instead of <gsl/gsl_algorithm>")
|
||||||
|
#include "algorithm"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#pragma message("This header will soon be removed. Use <gsl/assert> instead of <gsl/gsl_assert>")
|
#pragma message("This header will soon be removed. Use <gsl/assert> instead of <gsl/gsl_assert>")
|
||||||
#include <gsl/assert>
|
#include "assert"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#pragma message("This header will soon be removed. Use <gsl/byte> instead of <gsl/gsl_byte>")
|
#pragma message("This header will soon be removed. Use <gsl/byte> instead of <gsl/gsl_byte>")
|
||||||
#include <gsl/byte>
|
#include "byte"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#pragma message("This header will soon be removed. Use <gsl/narrow> instead of <gsl/gsl_narrow>")
|
#pragma message("This header will soon be removed. Use <gsl/narrow> instead of <gsl/gsl_narrow>")
|
||||||
#include <gsl/narrow>
|
#include "narrow"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#pragma message("This header will soon be removed. Use <gsl/util> instead of <gsl/gsl_util>")
|
#pragma message("This header will soon be removed. Use <gsl/util> instead of <gsl/gsl_util>")
|
||||||
#include <gsl/util>
|
#include "util"
|
||||||
|
@ -16,8 +16,9 @@
|
|||||||
|
|
||||||
#ifndef GSL_NARROW_H
|
#ifndef GSL_NARROW_H
|
||||||
#define GSL_NARROW_H
|
#define GSL_NARROW_H
|
||||||
#include <gsl/assert> // for Expects
|
#include "assert" // for GSL_SUPPRESS
|
||||||
#include <gsl/util> // for narrow_cast
|
#include "util" // for narrow_cast
|
||||||
|
#include <exception> // for std::exception
|
||||||
namespace gsl
|
namespace gsl
|
||||||
{
|
{
|
||||||
struct narrowing_error : public std::exception
|
struct narrowing_error : public std::exception
|
||||||
@ -26,19 +27,52 @@ struct narrowing_error : public std::exception
|
|||||||
};
|
};
|
||||||
|
|
||||||
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
|
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
|
||||||
template <class T, class U>
|
template <class T, class U, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
|
||||||
// clang-format off
|
// clang-format off
|
||||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||||
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
|
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
|
||||||
// clang-format on
|
GSL_SUPPRESS(es.46) // NO-FORMAT: attribute // The warning suggests that a floating->unsigned conversion can occur
|
||||||
|
// in the static_cast below, and that gsl::narrow should be used instead.
|
||||||
|
// Suppress this warning, since gsl::narrow is defined in terms of
|
||||||
|
// static_cast
|
||||||
|
// clang-format on
|
||||||
constexpr T narrow(U u) noexcept(false)
|
constexpr T narrow(U u) noexcept(false)
|
||||||
{
|
{
|
||||||
constexpr const bool is_different_signedness =
|
constexpr const bool is_different_signedness =
|
||||||
(std::is_signed<T>::value != std::is_signed<U>::value);
|
(std::is_signed<T>::value != std::is_signed<U>::value);
|
||||||
|
|
||||||
|
GSL_SUPPRESS(es.103) // NO-FORMAT: attribute // don't overflow
|
||||||
|
GSL_SUPPRESS(es.104) // NO-FORMAT: attribute // don't underflow
|
||||||
|
GSL_SUPPRESS(p.2) // NO-FORMAT: attribute // don't rely on undefined behavior
|
||||||
|
const T t = narrow_cast<T>(u); // While this is technically undefined behavior in some cases (i.e., if the source value is of floating-point type
|
||||||
|
// and cannot fit into the destination integral type), the resultant behavior is benign on the platforms
|
||||||
|
// that we target (i.e., no hardware trap representations are hit).
|
||||||
|
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
|
#endif
|
||||||
|
if (static_cast<U>(t) != u || (is_different_signedness && ((t < T{}) != (u < U{}))))
|
||||||
|
{
|
||||||
|
throw narrowing_error{};
|
||||||
|
}
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class U, typename std::enable_if<!std::is_arithmetic<T>::value>::type* = nullptr>
|
||||||
|
// clang-format off
|
||||||
|
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||||
|
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
|
||||||
|
// clang-format on
|
||||||
|
constexpr T narrow(U u) noexcept(false)
|
||||||
|
{
|
||||||
const T t = narrow_cast<T>(u);
|
const T t = narrow_cast<T>(u);
|
||||||
|
|
||||||
if (static_cast<U>(t) != u || (is_different_signedness && ((t < T{}) != (u < U{}))))
|
if (static_cast<U>(t) != u)
|
||||||
{
|
{
|
||||||
throw narrowing_error{};
|
throw narrowing_error{};
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#ifndef GSL_POINTERS_H
|
#ifndef GSL_POINTERS_H
|
||||||
#define GSL_POINTERS_H
|
#define GSL_POINTERS_H
|
||||||
|
|
||||||
#include <gsl/assert> // for Ensures, Expects
|
#include "assert" // for Ensures, Expects
|
||||||
|
|
||||||
#include <algorithm> // for forward
|
#include <algorithm> // for forward
|
||||||
#include <cstddef> // for ptrdiff_t, nullptr_t, size_t
|
#include <cstddef> // for ptrdiff_t, nullptr_t, size_t
|
||||||
@ -34,11 +34,18 @@ namespace gsl
|
|||||||
|
|
||||||
namespace details
|
namespace details
|
||||||
{
|
{
|
||||||
template<typename T, typename = void>
|
template <typename T, typename = void>
|
||||||
struct is_comparable_to_nullptr : std::false_type {};
|
struct is_comparable_to_nullptr : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_comparable_to_nullptr<T, std::enable_if_t<std::is_convertible<decltype(std::declval<T>() != nullptr), bool>::value>> : std::true_type {};
|
struct is_comparable_to_nullptr<
|
||||||
|
T,
|
||||||
|
std::enable_if_t<std::is_convertible<decltype(std::declval<T>() != nullptr), bool>::value>>
|
||||||
|
: std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -17,15 +17,21 @@
|
|||||||
#ifndef GSL_SPAN_H
|
#ifndef GSL_SPAN_H
|
||||||
#define GSL_SPAN_H
|
#define GSL_SPAN_H
|
||||||
|
|
||||||
#include <gsl/assert> // for Expects
|
#include "assert" // for Expects
|
||||||
#include <gsl/byte> // for byte
|
#include "byte" // for byte
|
||||||
#include <gsl/util> // for narrow_cast
|
#include "span_ext" // for span specialization of gsl::at and other span-related extensions
|
||||||
|
#include "util" // for narrow_cast
|
||||||
|
|
||||||
#include <array> // for array
|
#include <array> // for array
|
||||||
#include <cstddef> // for ptrdiff_t, size_t, nullptr_t
|
#include <cstddef> // for ptrdiff_t, size_t, nullptr_t
|
||||||
#include <iterator> // for reverse_iterator, distance, random_access_...
|
#include <iterator> // for reverse_iterator, distance, random_access_...
|
||||||
|
#include <memory> // for pointer_traits
|
||||||
#include <type_traits> // for enable_if_t, declval, is_convertible, inte...
|
#include <type_traits> // for enable_if_t, declval, is_convertible, inte...
|
||||||
|
|
||||||
|
#if defined(__has_include) && __has_include(<version>)
|
||||||
|
#include <version>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
|
||||||
@ -60,12 +66,6 @@
|
|||||||
namespace gsl
|
namespace gsl
|
||||||
{
|
{
|
||||||
|
|
||||||
// [views.constants], constants
|
|
||||||
constexpr const std::size_t dynamic_extent = narrow_cast<std::size_t>(-1);
|
|
||||||
|
|
||||||
template <class ElementType, std::size_t Extent = dynamic_extent>
|
|
||||||
class span;
|
|
||||||
|
|
||||||
// implementation details
|
// implementation details
|
||||||
namespace details
|
namespace details
|
||||||
{
|
{
|
||||||
@ -115,6 +115,9 @@ namespace details
|
|||||||
class span_iterator
|
class span_iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#if defined(__cpp_lib_ranges) || (defined(_MSVC_STL_VERSION) && defined(__cpp_lib_concepts))
|
||||||
|
using iterator_concept = std::contiguous_iterator_tag;
|
||||||
|
#endif // __cpp_lib_ranges
|
||||||
using iterator_category = std::random_access_iterator_tag;
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
using value_type = std::remove_cv_t<Type>;
|
using value_type = std::remove_cv_t<Type>;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
@ -334,8 +337,26 @@ namespace details
|
|||||||
pointer begin_ = nullptr;
|
pointer begin_ = nullptr;
|
||||||
pointer end_ = nullptr;
|
pointer end_ = nullptr;
|
||||||
pointer current_ = nullptr;
|
pointer current_ = nullptr;
|
||||||
};
|
|
||||||
|
|
||||||
|
template <typename Ptr>
|
||||||
|
friend struct std::pointer_traits;
|
||||||
|
};
|
||||||
|
}} // namespace gsl::details
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <class Type>
|
||||||
|
struct pointer_traits<::gsl::details::span_iterator<Type>>
|
||||||
|
{
|
||||||
|
using pointer = ::gsl::details::span_iterator<Type>;
|
||||||
|
using element_type = Type;
|
||||||
|
using difference_type = ptrdiff_t;
|
||||||
|
|
||||||
|
static constexpr element_type* to_address(const pointer i) noexcept { return i.current_; }
|
||||||
|
};
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
namespace gsl { namespace details {
|
||||||
template <std::size_t Ext>
|
template <std::size_t Ext>
|
||||||
class extent_type
|
class extent_type
|
||||||
{
|
{
|
||||||
@ -687,14 +708,11 @@ private:
|
|||||||
template <class OtherExtentType>
|
template <class OtherExtentType>
|
||||||
constexpr storage_type(KnownNotNull data, OtherExtentType ext)
|
constexpr storage_type(KnownNotNull data, OtherExtentType ext)
|
||||||
: ExtentType(ext), data_(data.p)
|
: ExtentType(ext), data_(data.p)
|
||||||
{
|
{}
|
||||||
Expects(ExtentType::size() != dynamic_extent);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OtherExtentType>
|
template <class OtherExtentType>
|
||||||
constexpr storage_type(pointer data, OtherExtentType ext) : ExtentType(ext), data_(data)
|
constexpr storage_type(pointer data, OtherExtentType ext) : ExtentType(ext), data_(data)
|
||||||
{
|
{
|
||||||
Expects(ExtentType::size() != dynamic_extent);
|
|
||||||
Expects(data || ExtentType::size() == 0);
|
Expects(data || ExtentType::size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,16 +27,29 @@
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <gsl/span> // for span
|
#include "assert" // GSL_KERNEL_MODE
|
||||||
#include <gsl/util> // for narrow_cast, narrow
|
#include "util" // for narrow_cast, narrow
|
||||||
|
|
||||||
#include <algorithm> // for lexicographical_compare
|
|
||||||
#include <cstddef> // for ptrdiff_t, size_t
|
#include <cstddef> // for ptrdiff_t, size_t
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#ifndef GSL_KERNEL_MODE
|
||||||
|
#include <algorithm> // for lexicographical_compare
|
||||||
|
#endif // GSL_KERNEL_MODE
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// [span.views.constants], constants
|
||||||
|
GSL_INLINE constexpr const std::size_t dynamic_extent = narrow_cast<std::size_t>(-1);
|
||||||
|
|
||||||
|
template <class ElementType, std::size_t Extent = dynamic_extent>
|
||||||
|
class span;
|
||||||
|
|
||||||
|
// std::equal and std::lexicographical_compare are not /kernel compatible
|
||||||
|
// so all comparison operators must be removed for kernel mode.
|
||||||
|
#ifndef GSL_KERNEL_MODE
|
||||||
|
|
||||||
// [span.comparison], span comparison operators
|
// [span.comparison], span comparison operators
|
||||||
template <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent>
|
template <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent>
|
||||||
constexpr bool operator==(span<ElementType, FirstExtent> l, span<ElementType, SecondExtent> r)
|
constexpr bool operator==(span<ElementType, FirstExtent> l, span<ElementType, SecondExtent> r)
|
||||||
@ -74,6 +87,8 @@ constexpr bool operator>=(span<ElementType, Extent> l, span<ElementType, Extent>
|
|||||||
return !(l < r);
|
return !(l < r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // GSL_KERNEL_MODE
|
||||||
|
|
||||||
//
|
//
|
||||||
// make_span() - Utility functions for creating spans
|
// make_span() - Utility functions for creating spans
|
||||||
//
|
//
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
#ifndef GSL_STRING_SPAN_H
|
#ifndef GSL_STRING_SPAN_H
|
||||||
#define GSL_STRING_SPAN_H
|
#define GSL_STRING_SPAN_H
|
||||||
|
|
||||||
#include <gsl/assert> // for Ensures, Expects
|
#include "assert" // for Ensures, Expects
|
||||||
#include <gsl/span_ext> // for operator!=, operator==, dynamic_extent
|
#include "span_ext" // for operator!=, operator==, dynamic_extent
|
||||||
#include <gsl/util> // for narrow_cast
|
#include "util" // for narrow_cast
|
||||||
|
|
||||||
#include <algorithm> // for equal, lexicographical_compare
|
#include <algorithm> // for equal, lexicographical_compare
|
||||||
#include <array> // for array
|
#include <array> // for array
|
||||||
@ -59,29 +59,21 @@ namespace gsl
|
|||||||
template <typename CharT, std::size_t Extent = dynamic_extent>
|
template <typename CharT, std::size_t Extent = dynamic_extent>
|
||||||
using basic_zstring = CharT*;
|
using basic_zstring = CharT*;
|
||||||
|
|
||||||
template <std::size_t Extent = dynamic_extent>
|
using czstring = basic_zstring<const char, dynamic_extent>;
|
||||||
using czstring = basic_zstring<const char, Extent>;
|
|
||||||
|
|
||||||
template <std::size_t Extent = dynamic_extent>
|
using cwzstring = basic_zstring<const wchar_t, dynamic_extent>;
|
||||||
using cwzstring = basic_zstring<const wchar_t, Extent>;
|
|
||||||
|
|
||||||
template <std::size_t Extent = dynamic_extent>
|
using cu16zstring = basic_zstring<const char16_t, dynamic_extent>;
|
||||||
using cu16zstring = basic_zstring<const char16_t, Extent>;
|
|
||||||
|
|
||||||
template <std::size_t Extent = dynamic_extent>
|
using cu32zstring = basic_zstring<const char32_t, dynamic_extent>;
|
||||||
using cu32zstring = basic_zstring<const char32_t, Extent>;
|
|
||||||
|
|
||||||
template <std::size_t Extent = dynamic_extent>
|
using zstring = basic_zstring<char, dynamic_extent>;
|
||||||
using zstring = basic_zstring<char, Extent>;
|
|
||||||
|
|
||||||
template <std::size_t Extent = dynamic_extent>
|
using wzstring = basic_zstring<wchar_t, dynamic_extent>;
|
||||||
using wzstring = basic_zstring<wchar_t, Extent>;
|
|
||||||
|
|
||||||
template <std::size_t Extent = dynamic_extent>
|
using u16zstring = basic_zstring<char16_t, dynamic_extent>;
|
||||||
using u16zstring = basic_zstring<char16_t, Extent>;
|
|
||||||
|
|
||||||
template <std::size_t Extent = dynamic_extent>
|
using u32zstring = basic_zstring<char32_t, dynamic_extent>;
|
||||||
using u32zstring = basic_zstring<char32_t, Extent>;
|
|
||||||
|
|
||||||
namespace details
|
namespace details
|
||||||
{
|
{
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#ifndef GSL_UTIL_H
|
#ifndef GSL_UTIL_H
|
||||||
#define GSL_UTIL_H
|
#define GSL_UTIL_H
|
||||||
|
|
||||||
#include <gsl/assert> // for Expects
|
#include "assert" // for Expects
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstddef> // for ptrdiff_t, size_t
|
#include <cstddef> // for ptrdiff_t, size_t
|
||||||
@ -25,6 +25,13 @@
|
|||||||
#include <type_traits> // for is_signed, integral_constant
|
#include <type_traits> // for is_signed, integral_constant
|
||||||
#include <utility> // for exchange, forward
|
#include <utility> // for exchange, forward
|
||||||
|
|
||||||
|
#if defined(__has_include) && __has_include(<version>)
|
||||||
|
#include <version>
|
||||||
|
#if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
|
||||||
|
#include <span>
|
||||||
|
#endif // __cpp_lib_span >= 202002L
|
||||||
|
#endif //__has_include(<version>)
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
@ -38,6 +45,12 @@
|
|||||||
#define GSL_NODISCARD
|
#define GSL_NODISCARD
|
||||||
#endif // defined(__cplusplus) && (__cplusplus >= 201703L)
|
#endif // defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||||
|
|
||||||
|
#if defined(__cpp_inline_variables)
|
||||||
|
#define GSL_INLINE inline
|
||||||
|
#else
|
||||||
|
#define GSL_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -81,8 +94,8 @@ GSL_NODISCARD auto finally(F&& f) noexcept
|
|||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
// clang-format off
|
// clang-format off
|
||||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||||
// clang-format on
|
// clang-format on
|
||||||
constexpr T narrow_cast(U&& u) noexcept
|
constexpr T narrow_cast(U&& u) noexcept
|
||||||
{
|
{
|
||||||
return static_cast<T>(std::forward<U>(u));
|
return static_cast<T>(std::forward<U>(u));
|
||||||
}
|
}
|
||||||
@ -94,7 +107,7 @@ template <class T, std::size_t N>
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||||
// clang-format on
|
// clang-format on
|
||||||
constexpr T& at(T (&arr)[N], const index i)
|
constexpr T& at(T (&arr)[N], const index i)
|
||||||
{
|
{
|
||||||
Expects(i >= 0 && i < narrow_cast<index>(N));
|
Expects(i >= 0 && i < narrow_cast<index>(N));
|
||||||
@ -105,7 +118,7 @@ template <class Cont>
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||||
// clang-format on
|
// clang-format on
|
||||||
constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()])
|
constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()])
|
||||||
{
|
{
|
||||||
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
|
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
|
||||||
@ -116,13 +129,21 @@ GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
|||||||
template <class T>
|
template <class T>
|
||||||
// clang-format off
|
// clang-format off
|
||||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||||
// clang-format on
|
// clang-format on
|
||||||
constexpr T at(const std::initializer_list<T> cont, const index i)
|
constexpr T at(const std::initializer_list<T> cont, const index i)
|
||||||
{
|
{
|
||||||
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
|
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
|
||||||
return *(cont.begin() + i);
|
return *(cont.begin() + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
|
||||||
|
template <class T, size_t extent = std::dynamic_extent>
|
||||||
|
constexpr auto at(std::span<T, extent> sp, const index i) -> decltype(sp[sp.size()])
|
||||||
|
{
|
||||||
|
Expects(i >= 0 && i < narrow_cast<index>(sp.size()));
|
||||||
|
return sp[gsl::narrow_cast<size_t>(i)];
|
||||||
|
}
|
||||||
|
#endif // __cpp_lib_span >= 202002L
|
||||||
} // namespace gsl
|
} // namespace gsl
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
@ -1,26 +1,43 @@
|
|||||||
parameters:
|
parameters:
|
||||||
jobName: ''
|
CXXVersions: [ 14, 17, 20 ]
|
||||||
imageName: ''
|
buildTypes: [ 'Debug', 'Release' ]
|
||||||
|
image: ''
|
||||||
|
|
||||||
|
compiler: ''
|
||||||
|
compilerVersions: ["default"] # if default value, simply uses whatever version is on the machine.
|
||||||
|
# the text of this default value doesn't actually matter.
|
||||||
|
setupfile: ''
|
||||||
|
extraCmakeArgs: ''
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
- job:
|
- ${{ each compilerVersion in parameters.compilerVersions }}:
|
||||||
displayName: ${{ parameters.imageName }}
|
- ${{ each CXXVersion in parameters.CXXVersions }}:
|
||||||
|
- ${{ each buildType in parameters.buildTypes }}:
|
||||||
|
- job:
|
||||||
|
displayName: ${{ format('{0} {1} C++{2} {3}', parameters.compiler, compilerVersion, CXXVersion, buildType) }}
|
||||||
pool:
|
pool:
|
||||||
vmImage: ${{ parameters.imageName }}
|
vmImage: ${{ parameters.image }}
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
14_debug:
|
|
||||||
GSL_CXX_STANDARD: '14'
|
|
||||||
BUILD_TYPE: 'Debug'
|
|
||||||
14_release:
|
|
||||||
GSL_CXX_STANDARD: '14'
|
|
||||||
BUILD_TYPE: 'Release'
|
|
||||||
17_debug:
|
|
||||||
GSL_CXX_STANDARD: '17'
|
|
||||||
BUILD_TYPE: 'Debug'
|
|
||||||
17_release:
|
|
||||||
GSL_CXX_STANDARD: '17'
|
|
||||||
BUILD_TYPE: 'Release'
|
|
||||||
continueOnError: false
|
continueOnError: false
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- template: ./steps.yml
|
- ${{ if not(eq(parameters.setupfile, '')) }}:
|
||||||
|
- template: ${{ parameters.setupfile }}
|
||||||
|
parameters:
|
||||||
|
version: ${{ compilerVersion }}
|
||||||
|
|
||||||
|
- task: CMake@1
|
||||||
|
name: Configure
|
||||||
|
inputs:
|
||||||
|
workingDirectory: build
|
||||||
|
cmakeArgs: '-DGSL_CXX_STANDARD=${{ CXXVersion }} -DCMAKE_BUILD_TYPE=${{ buildType }} -DCI_TESTING:BOOL=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -Werror=dev ${{ parameters.extraCmakeArgs }} .. '
|
||||||
|
|
||||||
|
- task: CMake@1
|
||||||
|
name: Build
|
||||||
|
inputs:
|
||||||
|
workingDirectory: build
|
||||||
|
cmakeArgs: '--build . '
|
||||||
|
|
||||||
|
- script: ctest . --output-on-failure --no-compress-output
|
||||||
|
name: CTest
|
||||||
|
workingDirectory: build
|
||||||
|
failOnStderr: true
|
||||||
|
9
pipelines/setup_apple.yml
Normal file
9
pipelines/setup_apple.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
parameters:
|
||||||
|
version: 0
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- script: |
|
||||||
|
if [ "${{ parameters.version }}" != "default" ]; then sudo xcode-select -switch /Applications/Xcode_${{ parameters.version }}.app; fi
|
||||||
|
|
||||||
|
displayName: "Setup Xcode Version"
|
||||||
|
failOnStderr: true
|
13
pipelines/setup_clang.yml
Normal file
13
pipelines/setup_clang.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
parameters:
|
||||||
|
version: 0
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- script: |
|
||||||
|
echo "##vso[task.setvariable variable=CXX;]${CXX}"
|
||||||
|
echo "##vso[task.setvariable variable=CC;]${CC}"
|
||||||
|
|
||||||
|
displayName: "Setup Clang Version"
|
||||||
|
failOnStderr: true
|
||||||
|
env:
|
||||||
|
CC: clang-${{ parameters.version }}
|
||||||
|
CXX: clang++-${{ parameters.version }}
|
14
pipelines/setup_gcc.yml
Normal file
14
pipelines/setup_gcc.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
parameters:
|
||||||
|
version: 0
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- script: |
|
||||||
|
echo "##vso[task.setvariable variable=CXX;]${CXX}"
|
||||||
|
echo "##vso[task.setvariable variable=CC;]${CC}"
|
||||||
|
if [ "${{ parameters.version }}" = "11" ]; then sudo apt-get install $CXX; fi
|
||||||
|
|
||||||
|
displayName: "Setup GCC Version"
|
||||||
|
failOnStderr: true
|
||||||
|
env:
|
||||||
|
CC: gcc-${{ parameters.version }}
|
||||||
|
CXX: g++-${{ parameters.version }}
|
@ -1,17 +0,0 @@
|
|||||||
steps:
|
|
||||||
- task: CMake@1
|
|
||||||
name: Configure
|
|
||||||
inputs:
|
|
||||||
workingDirectory: build
|
|
||||||
cmakeArgs: '-DCMAKE_CXX_STANDARD=$(GSL_CXX_STANDARD) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -Werror=dev .. '
|
|
||||||
|
|
||||||
- task: CMake@1
|
|
||||||
name: Build
|
|
||||||
inputs:
|
|
||||||
workingDirectory: build
|
|
||||||
cmakeArgs: '--build . '
|
|
||||||
|
|
||||||
- script: ctest . --output-on-failure --no-compress-output
|
|
||||||
name: CTest
|
|
||||||
workingDirectory: build
|
|
||||||
failOnStderr: true
|
|
@ -9,8 +9,12 @@ include(ExternalProject)
|
|||||||
# will make visual studio generated project group files
|
# will make visual studio generated project group files
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
|
if(CI_TESTING AND GSL_CXX_STANDARD EQUAL 20)
|
||||||
|
add_compile_definitions(FORCE_STD_SPAN_TESTS=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(IOS)
|
if(IOS)
|
||||||
add_compile_definitions(GTEST_HAS_DEATH_TEST=1)
|
add_compile_definitions(GTEST_HAS_DEATH_TEST=1 IOS_PROCESS_DELAY_WORKAROUND=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
pkg_search_module(GTestMain gtest_main)
|
pkg_search_module(GTestMain gtest_main)
|
||||||
@ -54,10 +58,11 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
|||||||
find_package(Microsoft.GSL REQUIRED)
|
find_package(Microsoft.GSL REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC AND (GSL_CXX_STANDARD EQUAL 17))
|
if (MSVC AND (GSL_CXX_STANDARD GREATER_EQUAL 17))
|
||||||
set(GSL_CPLUSPLUS_OPT -Zc:__cplusplus -permissive-)
|
set(GSL_CPLUSPLUS_OPT -Zc:__cplusplus -permissive-)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
# this interface adds compile options to how the tests are run
|
# this interface adds compile options to how the tests are run
|
||||||
# please try to keep entries ordered =)
|
# please try to keep entries ordered =)
|
||||||
add_library(gsl_tests_config INTERFACE)
|
add_library(gsl_tests_config INTERFACE)
|
||||||
@ -84,6 +89,7 @@ if(MSVC) # MSVC or simulating MSVC
|
|||||||
>
|
>
|
||||||
$<$<CXX_COMPILER_ID:Clang>:
|
$<$<CXX_COMPILER_ID:Clang>:
|
||||||
-Weverything
|
-Weverything
|
||||||
|
-Wfloat-equal
|
||||||
-Wno-c++98-compat
|
-Wno-c++98-compat
|
||||||
-Wno-c++98-compat-pedantic
|
-Wno-c++98-compat-pedantic
|
||||||
-Wno-covered-switch-default # GTest
|
-Wno-covered-switch-default # GTest
|
||||||
@ -101,6 +107,10 @@ if(MSVC) # MSVC or simulating MSVC
|
|||||||
>
|
>
|
||||||
>
|
>
|
||||||
)
|
)
|
||||||
|
check_cxx_compiler_flag("-Wno-reserved-identifier" WARN_RESERVED_ID)
|
||||||
|
if (WARN_RESERVED_ID)
|
||||||
|
target_compile_options(gsl_tests_config INTERFACE "-Wno-reserved-identifier")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
target_compile_options(gsl_tests_config INTERFACE
|
target_compile_options(gsl_tests_config INTERFACE
|
||||||
-fno-strict-aliasing
|
-fno-strict-aliasing
|
||||||
@ -113,6 +123,7 @@ else()
|
|||||||
-Wpedantic
|
-Wpedantic
|
||||||
-Wshadow
|
-Wshadow
|
||||||
-Wsign-conversion
|
-Wsign-conversion
|
||||||
|
-Wfloat-equal
|
||||||
-Wno-deprecated-declarations # Allow tests for [[deprecated]] elements
|
-Wno-deprecated-declarations # Allow tests for [[deprecated]] elements
|
||||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||||
-Weverything
|
-Weverything
|
||||||
@ -135,6 +146,11 @@ else()
|
|||||||
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,4.99>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
|
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,4.99>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
|
||||||
$<$<EQUAL:${GSL_CXX_STANDARD},17>:-Wno-undefined-func-template>
|
$<$<EQUAL:${GSL_CXX_STANDARD},17>:-Wno-undefined-func-template>
|
||||||
>
|
>
|
||||||
|
$<$<AND:$<EQUAL:${GSL_CXX_STANDARD},20>,$<OR:$<CXX_COMPILER_VERSION:11.0.0>,$<CXX_COMPILER_VERSION:10.0.0>>>:
|
||||||
|
-Wno-zero-as-null-pointer-constant # failing Clang Ubuntu 20.04 tests, seems to be a bug with clang 10.0.0
|
||||||
|
# and clang 11.0.0. (operator< is being re-written by the compiler
|
||||||
|
# as operator<=> and raising the warning)
|
||||||
|
>
|
||||||
>
|
>
|
||||||
$<$<CXX_COMPILER_ID:AppleClang>:
|
$<$<CXX_COMPILER_ID:AppleClang>:
|
||||||
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,9.1>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,10>>:
|
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,9.1>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,10>>:
|
||||||
@ -164,36 +180,27 @@ target_include_directories(gsl_tests_config SYSTEM INTERFACE
|
|||||||
googletest/googletest/include
|
googletest/googletest/include
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET PROPERTY FOLDER "GSL_tests")
|
add_executable(gsl_tests
|
||||||
|
algorithm_tests.cpp
|
||||||
|
assertion_tests.cpp
|
||||||
|
at_tests.cpp
|
||||||
|
byte_tests.cpp
|
||||||
|
notnull_tests.cpp
|
||||||
|
owner_tests.cpp
|
||||||
|
span_compatibility_tests.cpp
|
||||||
|
span_ext_tests.cpp
|
||||||
|
span_tests.cpp
|
||||||
|
strict_notnull_tests.cpp
|
||||||
|
string_span_tests.cpp
|
||||||
|
utils_tests.cpp
|
||||||
|
)
|
||||||
|
|
||||||
function(add_gsl_test name)
|
target_link_libraries(gsl_tests
|
||||||
add_executable(${name} ${name}.cpp)
|
|
||||||
target_link_libraries(${name}
|
|
||||||
Microsoft.GSL::GSL
|
Microsoft.GSL::GSL
|
||||||
gsl_tests_config
|
gsl_tests_config
|
||||||
${GTestMain_LIBRARIES}
|
${GTestMain_LIBRARIES}
|
||||||
)
|
)
|
||||||
add_test(
|
add_test(gsl_tests gsl_tests)
|
||||||
${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(string_span_tests)
|
|
||||||
add_gsl_test(at_tests)
|
|
||||||
add_gsl_test(notnull_tests)
|
|
||||||
add_gsl_test(assertion_tests)
|
|
||||||
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
|
# No exception tests
|
||||||
|
|
||||||
@ -222,12 +229,17 @@ if(MSVC) # MSVC or simulating MSVC
|
|||||||
>
|
>
|
||||||
$<$<CXX_COMPILER_ID:Clang>:
|
$<$<CXX_COMPILER_ID:Clang>:
|
||||||
-Weverything
|
-Weverything
|
||||||
|
-Wfloat-equal
|
||||||
-Wno-c++98-compat
|
-Wno-c++98-compat
|
||||||
-Wno-c++98-compat-pedantic
|
-Wno-c++98-compat-pedantic
|
||||||
-Wno-missing-prototypes
|
-Wno-missing-prototypes
|
||||||
-Wno-unknown-attributes
|
-Wno-unknown-attributes
|
||||||
>
|
>
|
||||||
)
|
)
|
||||||
|
check_cxx_compiler_flag("-Wno-reserved-identifier" WARN_RESERVED_ID)
|
||||||
|
if (WARN_RESERVED_ID)
|
||||||
|
target_compile_options(gsl_tests_config_noexcept INTERFACE "-Wno-reserved-identifier")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
target_compile_options(gsl_tests_config_noexcept INTERFACE
|
target_compile_options(gsl_tests_config_noexcept INTERFACE
|
||||||
-fno-exceptions
|
-fno-exceptions
|
||||||
@ -241,6 +253,7 @@ else()
|
|||||||
-Wpedantic
|
-Wpedantic
|
||||||
-Wshadow
|
-Wshadow
|
||||||
-Wsign-conversion
|
-Wsign-conversion
|
||||||
|
-Wfloat-equal
|
||||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||||
-Weverything
|
-Weverything
|
||||||
-Wno-c++98-compat
|
-Wno-c++98-compat
|
||||||
@ -268,19 +281,9 @@ else()
|
|||||||
)
|
)
|
||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
|
|
||||||
function(add_gsl_test_noexcept name)
|
add_executable(gsl_noexcept_tests no_exception_ensure_tests.cpp)
|
||||||
add_executable(${name} ${name}.cpp)
|
target_link_libraries(gsl_noexcept_tests
|
||||||
target_link_libraries(${name}
|
|
||||||
Microsoft.GSL::GSL
|
Microsoft.GSL::GSL
|
||||||
gsl_tests_config_noexcept
|
gsl_tests_config_noexcept
|
||||||
${GTestMain_LIBRARIES}
|
)
|
||||||
)
|
add_test(gsl_noexcept_tests gsl_noexcept_tests)
|
||||||
add_test(
|
|
||||||
${name}
|
|
||||||
${name}
|
|
||||||
)
|
|
||||||
# group all tests under GSL_tests_noexcept
|
|
||||||
set_property(TARGET ${name} PROPERTY FOLDER "GSL_tests_noexcept")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
add_gsl_test_noexcept(no_exception_ensure_tests)
|
|
||||||
|
@ -4,7 +4,7 @@ project(googletest-download NONE)
|
|||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
ExternalProject_Add(googletest
|
ExternalProject_Add(googletest
|
||||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||||
GIT_TAG 389cb68b87193358358ae87cc56d257fd0d80189
|
GIT_TAG 1b18723e874b256c1e39378c6774a90701d70f7a
|
||||||
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
|
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
|
||||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
|
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
|
@ -14,23 +14,19 @@
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <gsl/algorithm> // for copy
|
|
||||||
#include <gsl/span> // for span
|
|
||||||
#include <array> // for array
|
#include <array> // for array
|
||||||
#include <cstddef> // for size_t
|
#include <cstddef> // for size_t
|
||||||
|
#include <gsl/algorithm> // for copy
|
||||||
|
#include <gsl/span> // for span
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
namespace
|
#include "deathTestCommon.h"
|
||||||
{
|
|
||||||
static constexpr char deathstring[] = "Expected Death";
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
{
|
{
|
||||||
struct fail_fast;
|
struct fail_fast;
|
||||||
} // namespace gsl
|
} // namespace gsl
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
TEST(algorithm_tests, same_type)
|
TEST(algorithm_tests, same_type)
|
||||||
@ -76,8 +72,8 @@ TEST(algorithm_tests, same_type)
|
|||||||
std::array<int, 5> src{1, 2, 3, 4, 5};
|
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||||
std::array<int, 10> dst{};
|
std::array<int, 10> dst{};
|
||||||
|
|
||||||
const span<int> src_span(src);
|
const gsl::span<int> src_span(src);
|
||||||
const span<int, 10> dst_span(dst);
|
const gsl::span<int, 10> dst_span(dst);
|
||||||
|
|
||||||
copy(src_span, dst_span);
|
copy(src_span, dst_span);
|
||||||
copy(src_span, dst_span.subspan(src_span.size()));
|
copy(src_span, dst_span.subspan(src_span.size()));
|
||||||
@ -204,10 +200,11 @@ TEST(algorithm_tests, incompatible_type)
|
|||||||
|
|
||||||
TEST(algorithm_tests, small_destination_span)
|
TEST(algorithm_tests, small_destination_span)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. small_destination_span";
|
std::cerr << "Expected Death. small_destination_span";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
std::array<int, 12> src{1, 2, 3, 4};
|
std::array<int, 12> src{1, 2, 3, 4};
|
||||||
std::array<int, 4> dst{};
|
std::array<int, 4> dst{};
|
||||||
@ -217,9 +214,9 @@ TEST(algorithm_tests, small_destination_span)
|
|||||||
const span<int> dst_span_dyn(dst);
|
const span<int> dst_span_dyn(dst);
|
||||||
const span<int, 4> dst_span_static(dst);
|
const span<int, 4> dst_span_static(dst);
|
||||||
|
|
||||||
EXPECT_DEATH(copy(src_span_dyn, dst_span_dyn), deathstring);
|
EXPECT_DEATH(copy(src_span_dyn, dst_span_dyn), expected);
|
||||||
EXPECT_DEATH(copy(src_span_dyn, dst_span_static), deathstring);
|
EXPECT_DEATH(copy(src_span_dyn, dst_span_static), expected);
|
||||||
EXPECT_DEATH(copy(src_span_static, dst_span_dyn), deathstring);
|
EXPECT_DEATH(copy(src_span_static, dst_span_dyn), expected);
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
copy(src_span_static, dst_span_static);
|
copy(src_span_static, dst_span_static);
|
||||||
|
@ -14,14 +14,14 @@
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include "deathTestCommon.h"
|
||||||
#include <gsl/assert> // for fail_fast (ptr only), Ensures, Expects
|
#include <gsl/assert> // for fail_fast (ptr only), Ensures, Expects
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
static constexpr char deathstring[] = "Expected Death";
|
|
||||||
|
|
||||||
int f(int i)
|
int f(int i)
|
||||||
{
|
{
|
||||||
@ -39,23 +39,22 @@ int g(int i)
|
|||||||
|
|
||||||
TEST(assertion_tests, expects)
|
TEST(assertion_tests, expects)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. expects";
|
std::cerr << "Expected Death. expects";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_TRUE(f(2) == 2);
|
EXPECT_TRUE(f(2) == 2);
|
||||||
EXPECT_DEATH(f(10), deathstring);
|
EXPECT_DEATH(f(10), GetExpectedDeathString(terminateHandler));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST(assertion_tests, ensures)
|
TEST(assertion_tests, ensures)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. ensures";
|
std::cerr << "Expected Death. ensures";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_TRUE(g(2) == 3);
|
EXPECT_TRUE(g(2) == 3);
|
||||||
EXPECT_DEATH(g(9), deathstring);
|
EXPECT_DEATH(g(9), GetExpectedDeathString(terminateHandler));
|
||||||
}
|
}
|
||||||
|
@ -22,31 +22,33 @@
|
|||||||
#include <cstddef> // for size_t
|
#include <cstddef> // for size_t
|
||||||
#include <initializer_list> // for initializer_list
|
#include <initializer_list> // for initializer_list
|
||||||
#include <vector> // for vector
|
#include <vector> // for vector
|
||||||
|
#if defined(__cplusplus) && __cplusplus >= 202002L
|
||||||
|
#include <span>
|
||||||
|
#endif // __cplusplus >= 202002L
|
||||||
|
|
||||||
namespace
|
#include "deathTestCommon.h"
|
||||||
{
|
|
||||||
static constexpr char deathstring[] = "Expected Death";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(at_tests, static_array)
|
TEST(at_tests, static_array)
|
||||||
{
|
{
|
||||||
int a[4] = {1, 2, 3, 4};
|
int a[4] = {1, 2, 3, 4};
|
||||||
const int(&c_a)[4] = a;
|
const int(&c_a)[4] = a;
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
EXPECT_TRUE(&gsl::at(a, i) == &a[i]);
|
EXPECT_TRUE(&gsl::at(a, i) == &a[i]);
|
||||||
EXPECT_TRUE(&gsl::at(c_a, i) == &a[i]);
|
EXPECT_TRUE(&gsl::at(c_a, i) == &a[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. static_array";
|
std::cerr << "Expected Death. static_array";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
EXPECT_DEATH(gsl::at(a, -1), expected);
|
||||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
EXPECT_DEATH(gsl::at(a, 4), expected);
|
||||||
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
|
EXPECT_DEATH(gsl::at(c_a, -1), expected);
|
||||||
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
|
EXPECT_DEATH(gsl::at(c_a, 4), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(at_tests, std_array)
|
TEST(at_tests, std_array)
|
||||||
@ -54,20 +56,22 @@ TEST(at_tests, std_array)
|
|||||||
std::array<int, 4> a = {1, 2, 3, 4};
|
std::array<int, 4> a = {1, 2, 3, 4};
|
||||||
const std::array<int, 4>& c_a = a;
|
const std::array<int, 4>& c_a = a;
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
EXPECT_TRUE(&gsl::at(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)]);
|
EXPECT_TRUE(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. std_array";
|
std::cerr << "Expected Death. std_array";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
EXPECT_DEATH(gsl::at(a, -1), expected);
|
||||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
EXPECT_DEATH(gsl::at(a, 4), expected);
|
||||||
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
|
EXPECT_DEATH(gsl::at(c_a, -1), expected);
|
||||||
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
|
EXPECT_DEATH(gsl::at(c_a, 4), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(at_tests, std_vector)
|
TEST(at_tests, std_vector)
|
||||||
@ -75,42 +79,74 @@ TEST(at_tests, std_vector)
|
|||||||
std::vector<int> a = {1, 2, 3, 4};
|
std::vector<int> a = {1, 2, 3, 4};
|
||||||
const std::vector<int>& c_a = a;
|
const std::vector<int>& c_a = a;
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
EXPECT_TRUE(&gsl::at(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)]);
|
EXPECT_TRUE(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. std_vector";
|
std::cerr << "Expected Death. std_vector";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
EXPECT_DEATH(gsl::at(a, -1), expected);
|
||||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
EXPECT_DEATH(gsl::at(a, 4), expected);
|
||||||
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
|
EXPECT_DEATH(gsl::at(c_a, -1), expected);
|
||||||
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
|
EXPECT_DEATH(gsl::at(c_a, 4), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(at_tests, InitializerList)
|
TEST(at_tests, InitializerList)
|
||||||
{
|
{
|
||||||
const 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) {
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
EXPECT_TRUE(gsl::at(a, i) == i + 1);
|
EXPECT_TRUE(gsl::at(a, i) == i + 1);
|
||||||
EXPECT_TRUE(gsl::at({1, 2, 3, 4}, i) == i + 1);
|
EXPECT_TRUE(gsl::at({1, 2, 3, 4}, i) == i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. InitializerList";
|
std::cerr << "Expected Death. InitializerList";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
EXPECT_DEATH(gsl::at(a, -1), expected);
|
||||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
EXPECT_DEATH(gsl::at(a, 4), expected);
|
||||||
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, -1), deathstring);
|
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, -1), expected);
|
||||||
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, 4), deathstring);
|
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, 4), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(FORCE_STD_SPAN_TESTS) || defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
|
||||||
|
TEST(at_tests, std_span)
|
||||||
|
{
|
||||||
|
std::vector<int> vec{1, 2, 3, 4, 5};
|
||||||
|
std::span sp{vec};
|
||||||
|
|
||||||
|
std::vector<int> cvec{1, 2, 3, 4, 5};
|
||||||
|
std::span csp{cvec};
|
||||||
|
|
||||||
|
for (gsl::index i = 0; i < gsl::narrow_cast<gsl::index>(vec.size()); ++i)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(&gsl::at(sp, i) == &vec[gsl::narrow_cast<size_t>(i)]);
|
||||||
|
EXPECT_TRUE(&gsl::at(csp, i) == &cvec[gsl::narrow_cast<size_t>(i)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
|
std::cerr << "Expected Death. std_span";
|
||||||
|
std::abort();
|
||||||
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
|
EXPECT_DEATH(gsl::at(sp, -1), expected);
|
||||||
|
EXPECT_DEATH(gsl::at(sp, gsl::narrow_cast<gsl::index>(sp.size())), expected);
|
||||||
|
EXPECT_DEATH(gsl::at(csp, -1), expected);
|
||||||
|
EXPECT_DEATH(gsl::at(csp, gsl::narrow_cast<gsl::index>(sp.size())), expected);
|
||||||
|
}
|
||||||
|
#endif // defined(FORCE_STD_SPAN_TESTS) || defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910
|
#if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910
|
||||||
static constexpr bool test_constexpr()
|
static constexpr bool test_constexpr()
|
||||||
{
|
{
|
||||||
@ -119,7 +155,8 @@ static constexpr bool test_constexpr()
|
|||||||
std::array<int, 4> a2 = {1, 2, 3, 4};
|
std::array<int, 4> a2 = {1, 2, 3, 4};
|
||||||
const std::array<int, 4>& c_a2 = a2;
|
const std::array<int, 4>& c_a2 = a2;
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
if (&gsl::at(a1, i) != &a1[i]) return false;
|
if (&gsl::at(a1, i) != &a1[i]) return false;
|
||||||
if (&gsl::at(c_a1, i) != &a1[i]) return false;
|
if (&gsl::at(c_a1, i) != &a1[i]) return false;
|
||||||
// requires C++17:
|
// requires C++17:
|
||||||
|
@ -37,7 +37,9 @@ TEST(byte_tests, construction)
|
|||||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 4);
|
EXPECT_TRUE(static_cast<unsigned char>(b) == 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(es.49)
|
GSL_SUPPRESS(es.49)
|
||||||
|
// clang-format on
|
||||||
{
|
{
|
||||||
const byte b = byte(12);
|
const byte b = byte(12);
|
||||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
|
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
|
||||||
@ -55,7 +57,7 @@ TEST(byte_tests, construction)
|
|||||||
|
|
||||||
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||||
{
|
{
|
||||||
const byte b { 14 };
|
const byte b{14};
|
||||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 14);
|
EXPECT_TRUE(static_cast<unsigned char>(b) == 14);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -122,7 +124,7 @@ TEST(byte_tests, aliasing)
|
|||||||
EXPECT_TRUE(res == i);
|
EXPECT_TRUE(res == i);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
copy(src_span_static, dst_span_static);
|
copy(src_span_static, dst_span_static);
|
||||||
|
11
tests/deathTestCommon.h
Normal file
11
tests/deathTestCommon.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <gsl/assert>
|
||||||
|
|
||||||
|
constexpr char deathstring[] = "Expected Death";
|
||||||
|
constexpr char failed_set_terminate_deathstring[] = ".*";
|
||||||
|
|
||||||
|
// This prevents a failed call to set_terminate from failing the test suite.
|
||||||
|
constexpr const char* GetExpectedDeathString(std::terminate_handler handle)
|
||||||
|
{
|
||||||
|
return handle ? deathstring : failed_set_terminate_deathstring;
|
||||||
|
}
|
@ -14,8 +14,11 @@
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <cstdlib> // for std::exit
|
#include <cstdlib> // for std::exit
|
||||||
#include <gsl/span> // for span
|
#include <gsl/span> // for span
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
int operator_subscript_no_throw() noexcept
|
int operator_subscript_no_throw() noexcept
|
||||||
{
|
{
|
||||||
@ -42,6 +45,10 @@ void setup_termination_handler() noexcept
|
|||||||
|
|
||||||
int main() noexcept
|
int main() noexcept
|
||||||
{
|
{
|
||||||
|
std::cout << "Running main() from " __FILE__ "\n";
|
||||||
|
#if defined(IOS_PROCESS_DELAY_WORKAROUND)
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
#endif
|
||||||
setup_termination_handler();
|
setup_termination_handler();
|
||||||
operator_subscript_no_throw();
|
operator_subscript_no_throw();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -25,13 +25,9 @@
|
|||||||
#include <string> // for basic_string, operator==, string, operator<<
|
#include <string> // for basic_string, operator==, string, operator<<
|
||||||
#include <typeinfo> // for type_info
|
#include <typeinfo> // for type_info
|
||||||
|
|
||||||
|
#include "deathTestCommon.h"
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
static constexpr char deathstring[] = "Expected Death";
|
|
||||||
} //namespace
|
|
||||||
|
|
||||||
struct MyBase
|
struct MyBase
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
@ -64,7 +60,9 @@ struct CustomPtr
|
|||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
return reinterpret_cast<const void*>(lhs.p_) == reinterpret_cast<const void*>(rhs.p_) ? "true"
|
return reinterpret_cast<const void*>(lhs.p_) == reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
@ -72,7 +70,9 @@ std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
|||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
return reinterpret_cast<const void*>(lhs.p_) != reinterpret_cast<const void*>(rhs.p_) ? "true"
|
return reinterpret_cast<const void*>(lhs.p_) != reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
@ -80,7 +80,9 @@ std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
|||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
return reinterpret_cast<const void*>(lhs.p_) < reinterpret_cast<const void*>(rhs.p_) ? "true"
|
return reinterpret_cast<const void*>(lhs.p_) < reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
@ -88,7 +90,9 @@ std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
|||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
return reinterpret_cast<const void*>(lhs.p_) > reinterpret_cast<const void*>(rhs.p_) ? "true"
|
return reinterpret_cast<const void*>(lhs.p_) > reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
@ -96,7 +100,9 @@ std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
|||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
return reinterpret_cast<const void*>(lhs.p_) <= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
return reinterpret_cast<const void*>(lhs.p_) <= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
@ -104,7 +110,9 @@ std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
|||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator>=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator>=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
return reinterpret_cast<const void*>(lhs.p_) >= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
return reinterpret_cast<const void*>(lhs.p_) >= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
@ -118,12 +126,19 @@ struct NonCopyableNonMovable
|
|||||||
NonCopyableNonMovable& operator=(NonCopyableNonMovable&&) = delete;
|
NonCopyableNonMovable& operator=(NonCopyableNonMovable&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
namespace
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
GSL_SUPPRESS(f .4) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
bool helper(not_null<int*> p) { return *p == 12; }
|
bool helper(not_null<int*> p) { return *p == 12; }
|
||||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
// clang-format off
|
||||||
|
GSL_SUPPRESS(f .4) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
bool helper_const(not_null<const int*> p) { return *p == 12; }
|
bool helper_const(not_null<const int*> p) { return *p == 12; }
|
||||||
|
|
||||||
int* return_pointer() { return nullptr; }
|
int* return_pointer() { return nullptr; }
|
||||||
|
} // namespace
|
||||||
|
|
||||||
TEST(notnull_tests, TestNotNullConstructors)
|
TEST(notnull_tests, TestNotNullConstructors)
|
||||||
{
|
{
|
||||||
@ -142,10 +157,12 @@ TEST(notnull_tests, TestNotNullConstructors)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. TestNotNullConstructors";
|
std::cerr << "Expected Death. TestNotNullConstructors";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
{
|
{
|
||||||
// from shared pointer
|
// from shared pointer
|
||||||
int i = 12;
|
int i = 12;
|
||||||
@ -157,7 +174,7 @@ TEST(notnull_tests, TestNotNullConstructors)
|
|||||||
std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
|
std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
|
||||||
|
|
||||||
int* pi = nullptr;
|
int* pi = nullptr;
|
||||||
EXPECT_DEATH((not_null<decltype(pi)>(pi)), deathstring);
|
EXPECT_DEATH((not_null<decltype(pi)>(pi)), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -214,8 +231,8 @@ TEST(notnull_tests, TestNotNullConstructors)
|
|||||||
{
|
{
|
||||||
// from returned pointer
|
// from returned pointer
|
||||||
|
|
||||||
EXPECT_DEATH(helper(return_pointer()), deathstring);
|
EXPECT_DEATH(helper(return_pointer()), expected);
|
||||||
EXPECT_DEATH(helper_const(return_pointer()), deathstring);
|
EXPECT_DEATH(helper_const(return_pointer()), expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,17 +292,18 @@ TEST(notnull_tests, TestNotNullCasting)
|
|||||||
|
|
||||||
TEST(notnull_tests, TestNotNullAssignment)
|
TEST(notnull_tests, TestNotNullAssignment)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. TestNotNullAssignmentd";
|
std::cerr << "Expected Death. TestNotNullAssignmentd";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
int i = 12;
|
int i = 12;
|
||||||
not_null<int*> p(&i);
|
not_null<int*> p(&i);
|
||||||
EXPECT_TRUE(helper(p));
|
EXPECT_TRUE(helper(p));
|
||||||
|
|
||||||
int* q = nullptr;
|
int* q = nullptr;
|
||||||
EXPECT_DEATH(p = not_null<int*>(q), deathstring);
|
EXPECT_DEATH(p = not_null<int*>(q), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(notnull_tests, TestNotNullRawPointerComparison)
|
TEST(notnull_tests, TestNotNullRawPointerComparison)
|
||||||
@ -434,17 +452,18 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
|
|||||||
EXPECT_TRUE(*x == 42);
|
EXPECT_TRUE(*x == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. TestNotNullConstructorTypeDeduction";
|
std::cerr << "Expected Death. TestNotNullConstructorTypeDeduction";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto workaround_macro = []() {
|
auto workaround_macro = []() {
|
||||||
int* p1 = nullptr;
|
int* p1 = nullptr;
|
||||||
const not_null x{p1};
|
const not_null x{p1};
|
||||||
};
|
};
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -452,14 +471,14 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
|
|||||||
const int* p1 = nullptr;
|
const int* p1 = nullptr;
|
||||||
const not_null x{p1};
|
const not_null x{p1};
|
||||||
};
|
};
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int* p = nullptr;
|
int* p = nullptr;
|
||||||
|
|
||||||
EXPECT_DEATH(helper(not_null{p}), deathstring);
|
EXPECT_DEATH(helper(not_null{p}), expected);
|
||||||
EXPECT_DEATH(helper_const(not_null{p}), deathstring);
|
EXPECT_DEATH(helper_const(not_null{p}), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
@ -495,10 +514,11 @@ TEST(notnull_tests, TestMakeNotNull)
|
|||||||
EXPECT_TRUE(*x == 42);
|
EXPECT_TRUE(*x == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. TestMakeNotNull";
|
std::cerr << "Expected Death. TestMakeNotNull";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
{
|
{
|
||||||
const auto workaround_macro = []() {
|
const auto workaround_macro = []() {
|
||||||
@ -506,7 +526,7 @@ TEST(notnull_tests, TestMakeNotNull)
|
|||||||
const auto x = make_not_null(p1);
|
const auto x = make_not_null(p1);
|
||||||
EXPECT_TRUE(*x == 42);
|
EXPECT_TRUE(*x == 42);
|
||||||
};
|
};
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -515,21 +535,21 @@ TEST(notnull_tests, TestMakeNotNull)
|
|||||||
const auto x = make_not_null(p1);
|
const auto x = make_not_null(p1);
|
||||||
EXPECT_TRUE(*x == 42);
|
EXPECT_TRUE(*x == 42);
|
||||||
};
|
};
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int* p = nullptr;
|
int* p = nullptr;
|
||||||
|
|
||||||
EXPECT_DEATH(helper(make_not_null(p)), deathstring);
|
EXPECT_DEATH(helper(make_not_null(p)), expected);
|
||||||
EXPECT_DEATH(helper_const(make_not_null(p)), deathstring);
|
EXPECT_DEATH(helper_const(make_not_null(p)), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
EXPECT_DEATH(make_not_null(nullptr), deathstring);
|
EXPECT_DEATH(make_not_null(nullptr), expected);
|
||||||
EXPECT_DEATH(helper(make_not_null(nullptr)), deathstring);
|
EXPECT_DEATH(helper(make_not_null(nullptr)), expected);
|
||||||
EXPECT_DEATH(helper_const(make_not_null(nullptr)), deathstring);
|
EXPECT_DEATH(helper_const(make_not_null(nullptr)), expected);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute
|
GSL_SUPPRESS(f .23) // NO-FORMAT: attribute
|
||||||
void f(int* i) { *i += 1; }
|
void f(int* i) { *i += 1; }
|
||||||
|
|
||||||
TEST(owner_tests, basic_test)
|
TEST(owner_tests, basic_test)
|
||||||
@ -34,10 +34,10 @@ TEST(owner_tests, basic_test)
|
|||||||
|
|
||||||
TEST(owner_tests, check_pointer_constraint)
|
TEST(owner_tests, check_pointer_constraint)
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
owner<int> integerTest = 10;
|
owner<int> integerTest = 10;
|
||||||
owner<std::shared_ptr<int>> sharedPtrTest(new int(10));
|
owner<std::shared_ptr<int>> sharedPtrTest(new int(10));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -55,14 +55,14 @@ void ArrayConvertibilityCheck()
|
|||||||
EXPECT_TRUE(sp_const_nullptr_1.data() == stl_nullptr.data());
|
EXPECT_TRUE(sp_const_nullptr_1.data() == stl_nullptr.data());
|
||||||
EXPECT_TRUE(sp_const_nullptr_1.size() == 3);
|
EXPECT_TRUE(sp_const_nullptr_1.size() == 3);
|
||||||
|
|
||||||
span<const T* const> sp_const_nullptr_2{std::as_const(stl_nullptr)};
|
gsl::span<const T* const> sp_const_nullptr_2{std::as_const(stl_nullptr)};
|
||||||
EXPECT_TRUE(sp_const_nullptr_2.data() == stl_nullptr.data());
|
EXPECT_TRUE(sp_const_nullptr_2.data() == stl_nullptr.data());
|
||||||
EXPECT_TRUE(sp_const_nullptr_2.size() == 3);
|
EXPECT_TRUE(sp_const_nullptr_2.size() == 3);
|
||||||
|
|
||||||
static_assert(std::is_same<decltype(span{stl_nullptr}), span<T*, 3>>::value,
|
static_assert(std::is_same<decltype(gsl::span{stl_nullptr}), gsl::span<T*, 3>>::value,
|
||||||
"std::is_same< decltype(span{stl_nullptr}), span<T*, 3>>::value");
|
"std::is_same< decltype(span{stl_nullptr}), span<T*, 3>>::value");
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_same<decltype(span{std::as_const(stl_nullptr)}), span<T* const, 3>>::value,
|
std::is_same<decltype(gsl::span{std::as_const(stl_nullptr)}), gsl::span<T* const, 3>>::value,
|
||||||
"std::is_same< decltype(span{std::as_const(stl_nullptr)}), span<T* const, "
|
"std::is_same< decltype(span{std::as_const(stl_nullptr)}), span<T* const, "
|
||||||
"3>>::value");
|
"3>>::value");
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <gsl/span> // for span and span_ext
|
||||||
#include <gsl/util> // for narrow_cast, at
|
#include <gsl/util> // for narrow_cast, at
|
||||||
#include <gsl/span_ext> // for operator==, operator!=, make_span
|
|
||||||
|
|
||||||
#include <array> // for array
|
#include <array> // for array
|
||||||
#include <iostream> // for cerr
|
#include <iostream> // for cerr
|
||||||
@ -26,17 +26,16 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
namespace
|
#include "deathTestCommon.h"
|
||||||
{
|
|
||||||
static constexpr char deathstring[] = "Expected Death";
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TEST(span_ext_test, make_span_from_pointer_length_constructor)
|
TEST(span_ext_test, make_span_from_pointer_length_constructor)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. from_pointer_length_constructor";
|
std::cerr << "Expected Death. from_pointer_length_constructor";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
int arr[4] = {1, 2, 3, 4};
|
int arr[4] = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -49,7 +48,7 @@ TEST(span_ext_test, make_span_from_pointer_length_constructor)
|
|||||||
|
|
||||||
{
|
{
|
||||||
int* p = nullptr;
|
int* p = nullptr;
|
||||||
auto s = make_span(p, narrow_cast<span<int>::size_type>(0));
|
auto s = make_span(p, narrow_cast<gsl::span<int>::size_type>(0));
|
||||||
EXPECT_TRUE(s.size() == 0);
|
EXPECT_TRUE(s.size() == 0);
|
||||||
EXPECT_TRUE(s.data() == nullptr);
|
EXPECT_TRUE(s.data() == nullptr);
|
||||||
}
|
}
|
||||||
@ -57,7 +56,7 @@ TEST(span_ext_test, make_span_from_pointer_length_constructor)
|
|||||||
{
|
{
|
||||||
int* p = nullptr;
|
int* p = nullptr;
|
||||||
auto workaround_macro = [=]() { make_span(p, 2); };
|
auto workaround_macro = [=]() { make_span(p, 2); };
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +87,7 @@ TEST(span_ext_test, make_span_from_pointer_pointer_construction)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_ext_test, make_span_from_array_constructor)
|
TEST(span_ext_test, make_span_from_array_constructor)
|
||||||
{
|
{
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
|
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};
|
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||||
@ -110,10 +109,10 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
EXPECT_TRUE(s.size() == 1);
|
EXPECT_TRUE(s.size() == 1);
|
||||||
EXPECT_TRUE(s.data() == std::addressof(arr3d[0]));
|
EXPECT_TRUE(s.data() == std::addressof(arr3d[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_ext_test, make_span_from_dynamic_array_constructor)
|
TEST(span_ext_test, make_span_from_dynamic_array_constructor)
|
||||||
{
|
{
|
||||||
double(*arr)[3][4] = new double[100][3][4];
|
double(*arr)[3][4] = new double[100][3][4];
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -123,10 +122,10 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete[] arr;
|
delete[] arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_ext_test, make_span_from_std_array_constructor)
|
TEST(span_ext_test, make_span_from_std_array_constructor)
|
||||||
{
|
{
|
||||||
std::array<int, 4> arr = {1, 2, 3, 4};
|
std::array<int, 4> arr = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -137,25 +136,25 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
|
|
||||||
// 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
|
// 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);
|
gsl::span<int> s1 = make_span(arr);
|
||||||
|
|
||||||
static span<int> s2;
|
static gsl::span<int> s2;
|
||||||
s2 = s1;
|
s2 = s1;
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
|
#if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
|
||||||
__GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
|
__GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
|
||||||
// Known to be broken in gcc 6.4 and 6.5 with optimizations
|
// 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
|
// Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116
|
||||||
EXPECT_TRUE(s1.size() == 4);
|
EXPECT_TRUE(s1.size() == 4);
|
||||||
EXPECT_TRUE(s2.size() == 0);
|
EXPECT_TRUE(s2.size() == 0);
|
||||||
#else
|
#else
|
||||||
EXPECT_TRUE(s1.size() == s2.size());
|
EXPECT_TRUE(s1.size() == s2.size());
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(span_ext_test, make_span_from_const_std_array_constructor)
|
TEST(span_ext_test, make_span_from_const_std_array_constructor)
|
||||||
{
|
{
|
||||||
const std::array<int, 4> arr = {1, 2, 3, 4};
|
const std::array<int, 4> arr = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -163,10 +162,10 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
EXPECT_TRUE(s.size() == arr.size());
|
EXPECT_TRUE(s.size() == arr.size());
|
||||||
EXPECT_TRUE(s.data() == arr.data());
|
EXPECT_TRUE(s.data() == arr.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_ext_test, make_span_from_std_array_const_constructor)
|
TEST(span_ext_test, make_span_from_std_array_const_constructor)
|
||||||
{
|
{
|
||||||
std::array<const int, 4> arr = {1, 2, 3, 4};
|
std::array<const int, 4> arr = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -174,10 +173,10 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
EXPECT_TRUE(s.size() == arr.size());
|
EXPECT_TRUE(s.size() == arr.size());
|
||||||
EXPECT_TRUE(s.data() == arr.data());
|
EXPECT_TRUE(s.data() == arr.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_ext_test, make_span_from_container_constructor)
|
TEST(span_ext_test, make_span_from_container_constructor)
|
||||||
{
|
{
|
||||||
std::vector<int> v = {1, 2, 3};
|
std::vector<int> v = {1, 2, 3};
|
||||||
const std::vector<int> cv = v;
|
const std::vector<int> cv = v;
|
||||||
|
|
||||||
@ -190,20 +189,20 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
EXPECT_TRUE(cs.size() == cv.size());
|
EXPECT_TRUE(cs.size() == cv.size());
|
||||||
EXPECT_TRUE(cs.data() == cv.data());
|
EXPECT_TRUE(cs.data() == cv.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, interop_with_gsl_at)
|
TEST(span_test, interop_with_gsl_at)
|
||||||
{
|
{
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
span<int> s{arr};
|
gsl::span<int> s{arr};
|
||||||
EXPECT_TRUE(at(s, 0) == 1);
|
EXPECT_TRUE(at(s, 0) == 1);
|
||||||
EXPECT_TRUE(at(s, 1) == 2);
|
EXPECT_TRUE(at(s, 1) == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_ext_test, iterator_free_functions)
|
TEST(span_ext_test, iterator_free_functions)
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
span<int> s{a};
|
gsl::span<int> s{a};
|
||||||
|
|
||||||
EXPECT_TRUE((std::is_same<decltype(s.begin()), decltype(begin(s))>::value));
|
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(s.end()), decltype(end(s))>::value));
|
||||||
@ -228,22 +227,23 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
|
|
||||||
EXPECT_TRUE(s.rbegin() == crbegin(s));
|
EXPECT_TRUE(s.rbegin() == crbegin(s));
|
||||||
EXPECT_TRUE(s.rend() == crend(s));
|
EXPECT_TRUE(s.rend() == crend(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_ext_test, ssize_free_function)
|
TEST(span_ext_test, ssize_free_function)
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
span<int> s{a};
|
gsl::span<int> s{a};
|
||||||
|
|
||||||
EXPECT_FALSE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value));
|
EXPECT_FALSE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value));
|
||||||
EXPECT_TRUE(s.size() == static_cast<std::size_t>(ssize(s)));
|
EXPECT_TRUE(s.size() == static_cast<std::size_t>(ssize(s)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_ext_test, comparison_operators)
|
#ifndef GSL_KERNEL_MODE
|
||||||
|
TEST(span_ext_test, comparison_operators)
|
||||||
|
{
|
||||||
{
|
{
|
||||||
{
|
gsl::span<int> s1;
|
||||||
span<int> s1;
|
gsl::span<int> s2;
|
||||||
span<int> s2;
|
|
||||||
EXPECT_TRUE(s1 == s2);
|
EXPECT_TRUE(s1 == s2);
|
||||||
EXPECT_FALSE(s1 != s2);
|
EXPECT_FALSE(s1 != s2);
|
||||||
EXPECT_FALSE(s1 < s2);
|
EXPECT_FALSE(s1 < s2);
|
||||||
@ -260,8 +260,8 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
|
|
||||||
{
|
{
|
||||||
int arr[] = {2, 1};
|
int arr[] = {2, 1};
|
||||||
span<int> s1 = arr;
|
gsl::span<int> s1 = arr;
|
||||||
span<int> s2 = arr;
|
gsl::span<int> s2 = arr;
|
||||||
|
|
||||||
EXPECT_TRUE(s1 == s2);
|
EXPECT_TRUE(s1 == s2);
|
||||||
EXPECT_FALSE(s1 != s2);
|
EXPECT_FALSE(s1 != s2);
|
||||||
@ -280,8 +280,8 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
{
|
{
|
||||||
int arr[] = {2, 1}; // bigger
|
int arr[] = {2, 1}; // bigger
|
||||||
|
|
||||||
span<int> s1;
|
gsl::span<int> s1;
|
||||||
span<int> s2 = arr;
|
gsl::span<int> s2 = arr;
|
||||||
|
|
||||||
EXPECT_TRUE(s1 != s2);
|
EXPECT_TRUE(s1 != s2);
|
||||||
EXPECT_TRUE(s2 != s1);
|
EXPECT_TRUE(s2 != s1);
|
||||||
@ -300,8 +300,8 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
{
|
{
|
||||||
int arr1[] = {1, 2};
|
int arr1[] = {1, 2};
|
||||||
int arr2[] = {1, 2};
|
int arr2[] = {1, 2};
|
||||||
span<int> s1 = arr1;
|
gsl::span<int> s1 = arr1;
|
||||||
span<int> s2 = arr2;
|
gsl::span<int> s2 = arr2;
|
||||||
|
|
||||||
EXPECT_TRUE(s1 == s2);
|
EXPECT_TRUE(s1 == s2);
|
||||||
EXPECT_FALSE(s1 != s2);
|
EXPECT_FALSE(s1 != s2);
|
||||||
@ -320,8 +320,8 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
{
|
{
|
||||||
int arr[] = {1, 2, 3};
|
int arr[] = {1, 2, 3};
|
||||||
|
|
||||||
span<int> s1 = {&arr[0], 2}; // shorter
|
gsl::span<int> s1 = {&arr[0], 2}; // shorter
|
||||||
span<int> s2 = arr; // longer
|
gsl::span<int> s2 = arr; // longer
|
||||||
|
|
||||||
EXPECT_TRUE(s1 != s2);
|
EXPECT_TRUE(s1 != s2);
|
||||||
EXPECT_TRUE(s2 != s1);
|
EXPECT_TRUE(s2 != s1);
|
||||||
@ -341,8 +341,8 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
int arr1[] = {1, 2}; // smaller
|
int arr1[] = {1, 2}; // smaller
|
||||||
int arr2[] = {2, 1}; // bigger
|
int arr2[] = {2, 1}; // bigger
|
||||||
|
|
||||||
span<int> s1 = arr1;
|
gsl::span<int> s1 = arr1;
|
||||||
span<int> s2 = arr2;
|
gsl::span<int> s2 = arr2;
|
||||||
|
|
||||||
EXPECT_TRUE(s1 != s2);
|
EXPECT_TRUE(s1 != s2);
|
||||||
EXPECT_TRUE(s2 != s1);
|
EXPECT_TRUE(s2 != s1);
|
||||||
@ -357,4 +357,5 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
|||||||
EXPECT_TRUE(s2 >= s1);
|
EXPECT_TRUE(s2 >= s1);
|
||||||
EXPECT_FALSE(s1 >= s2);
|
EXPECT_FALSE(s1 >= s2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // GSL_KERNEL_MODE
|
||||||
|
@ -17,19 +17,19 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <gsl/byte> // for byte
|
#include <gsl/byte> // for byte
|
||||||
#include <gsl/util> // for narrow_cast, at
|
|
||||||
#include <gsl/span> // for span, span_iterator, operator==, operator!=
|
#include <gsl/span> // for span, span_iterator, operator==, operator!=
|
||||||
|
#include <gsl/util> // for narrow_cast, at
|
||||||
|
|
||||||
#include <array> // for array
|
#include <array> // for array
|
||||||
|
#include <cstddef> // for ptrdiff_t
|
||||||
#include <iostream> // for ptrdiff_t
|
#include <iostream> // for ptrdiff_t
|
||||||
#include <iterator> // for reverse_iterator, operator-, operator==
|
#include <iterator> // for reverse_iterator, operator-, operator==
|
||||||
#include <memory> // for unique_ptr, shared_ptr, make_unique, allo...
|
#include <memory> // for unique_ptr, shared_ptr, make_unique, allo...
|
||||||
#include <regex> // for match_results, sub_match, match_results<>...
|
#include <regex> // for match_results, sub_match, match_results<>...
|
||||||
#include <cstddef> // for ptrdiff_t
|
|
||||||
#include <string> // for string
|
#include <string> // for string
|
||||||
#include <type_traits> // for integral_constant<>::value, is_default_co...
|
#include <type_traits> // for integral_constant<>::value, is_default_co...
|
||||||
#include <vector> // for vector
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector> // for vector
|
||||||
|
|
||||||
// the string_view include and macro are used in the deduction guide verification
|
// the string_view include and macro are used in the deduction guide verification
|
||||||
#if (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L))
|
#if (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L))
|
||||||
@ -40,13 +40,16 @@
|
|||||||
#endif // __has_include(<string_view>)
|
#endif // __has_include(<string_view>)
|
||||||
#endif // __has_include
|
#endif // __has_include
|
||||||
#endif // (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L))
|
#endif // (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L))
|
||||||
|
#if defined(__cplusplus) && __cplusplus >= 202002L
|
||||||
|
#include <span>
|
||||||
|
#endif // __cplusplus >= 202002L
|
||||||
|
|
||||||
|
#include "deathTestCommon.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
static constexpr char deathstring[] = "Expected Death";
|
|
||||||
|
|
||||||
struct BaseClass
|
struct BaseClass
|
||||||
{
|
{
|
||||||
@ -111,10 +114,12 @@ TEST(span_test, size_optimization)
|
|||||||
|
|
||||||
TEST(span_test, from_nullptr_size_constructor)
|
TEST(span_test, from_nullptr_size_constructor)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. from_nullptr_size_constructor";
|
std::cerr << "Expected Death. from_nullptr_size_constructor";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int> s{nullptr, narrow_cast<span<int>::size_type>(0)};
|
span<int> s{nullptr, narrow_cast<span<int>::size_type>(0)};
|
||||||
EXPECT_TRUE(s.size() == 0);
|
EXPECT_TRUE(s.size() == 0);
|
||||||
@ -128,21 +133,21 @@ TEST(span_test, from_nullptr_size_constructor)
|
|||||||
auto workaround_macro = []() {
|
auto workaround_macro = []() {
|
||||||
const span<int, 1> s{nullptr, narrow_cast<span<int>::size_type>(0)};
|
const span<int, 1> s{nullptr, narrow_cast<span<int>::size_type>(0)};
|
||||||
};
|
};
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto workaround_macro = []() { const span<int> s{nullptr, 1}; };
|
auto workaround_macro = []() { const span<int> s{nullptr, 1}; };
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
|
|
||||||
auto const_workaround_macro = []() { const span<const int> s{nullptr, 1}; };
|
auto const_workaround_macro = []() { const span<const int> s{nullptr, 1}; };
|
||||||
EXPECT_DEATH(const_workaround_macro(), deathstring);
|
EXPECT_DEATH(const_workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto workaround_macro = []() { const span<int, 0> s{nullptr, 1}; };
|
auto workaround_macro = []() { const span<int, 0> s{nullptr, 1}; };
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
|
|
||||||
auto const_workaround_macro = []() { const span<const int, 0> s{nullptr, 1}; };
|
auto const_workaround_macro = []() { const span<const int, 0> s{nullptr, 1}; };
|
||||||
EXPECT_DEATH(const_workaround_macro(), deathstring);
|
EXPECT_DEATH(const_workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
span<int*> s{nullptr, narrow_cast<span<int>::size_type>(0)};
|
span<int*> s{nullptr, narrow_cast<span<int>::size_type>(0)};
|
||||||
@ -157,10 +162,12 @@ TEST(span_test, from_nullptr_size_constructor)
|
|||||||
|
|
||||||
TEST(span_test, from_pointer_length_constructor)
|
TEST(span_test, from_pointer_length_constructor)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. from_pointer_length_constructor";
|
std::cerr << "Expected Death. from_pointer_length_constructor";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
int arr[4] = {1, 2, 3, 4};
|
int arr[4] = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -171,8 +178,7 @@ TEST(span_test, from_pointer_length_constructor)
|
|||||||
EXPECT_TRUE(s.size() == narrow_cast<std::size_t>(i));
|
EXPECT_TRUE(s.size() == narrow_cast<std::size_t>(i));
|
||||||
EXPECT_TRUE(s.data() == &arr[0]);
|
EXPECT_TRUE(s.data() == &arr[0]);
|
||||||
EXPECT_TRUE(s.empty() == (i == 0));
|
EXPECT_TRUE(s.empty() == (i == 0));
|
||||||
for (int j = 0; j < i; ++j)
|
for (int j = 0; j < i; ++j) EXPECT_TRUE(arr[j] == s[narrow_cast<std::size_t>(j)]);
|
||||||
EXPECT_TRUE(arr[j] == s[narrow_cast<std::size_t>(j)]);
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
span<int> s = {&arr[i], 4 - narrow_cast<std::size_t>(i)};
|
span<int> s = {&arr[i], 4 - narrow_cast<std::size_t>(i)};
|
||||||
@ -204,7 +210,7 @@ TEST(span_test, from_pointer_length_constructor)
|
|||||||
{
|
{
|
||||||
int* p = nullptr;
|
int* p = nullptr;
|
||||||
auto workaround_macro = [=]() { const span<int> s{p, 2}; };
|
auto workaround_macro = [=]() { const span<int> s{p, 2}; };
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,14 +248,14 @@ TEST(span_test, from_pointer_pointer_construction)
|
|||||||
// this will fail the std::distance() precondition, which asserts on MSVC debug builds
|
// this will fail the std::distance() precondition, which asserts on MSVC debug builds
|
||||||
//{
|
//{
|
||||||
// auto workaround_macro = [&]() { span<int> s{&arr[1], &arr[0]}; };
|
// auto workaround_macro = [&]() { span<int> s{&arr[1], &arr[0]}; };
|
||||||
// EXPECT_DEATH(workaround_macro(), deathstring);
|
// EXPECT_DEATH(workaround_macro(), expected);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// this will fail the std::distance() precondition, which asserts on MSVC debug builds
|
// this will fail the std::distance() precondition, which asserts on MSVC debug builds
|
||||||
//{
|
//{
|
||||||
// int* p = nullptr;
|
// int* p = nullptr;
|
||||||
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
|
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
|
||||||
// EXPECT_DEATH(workaround_macro(), deathstring);
|
// EXPECT_DEATH(workaround_macro(), expected);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -270,12 +276,12 @@ TEST(span_test, from_pointer_pointer_construction)
|
|||||||
//{
|
//{
|
||||||
// int* p = nullptr;
|
// int* p = nullptr;
|
||||||
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
|
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
|
||||||
// EXPECT_DEATH(workaround_macro(), deathstring);
|
// EXPECT_DEATH(workaround_macro(), expected);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, from_array_constructor)
|
TEST(span_test, from_array_constructor)
|
||||||
{
|
{
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -292,7 +298,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
|
|
||||||
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
|
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
span<int, 6> s{arr};
|
span<int, 6> s{arr};
|
||||||
}
|
}
|
||||||
@ -320,7 +326,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
{
|
{
|
||||||
span<int, 6> s{arr2d};
|
span<int, 6> s{arr2d};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const span<int[3]> s{std::addressof(arr2d[0]), 1};
|
const span<int[3]> s{std::addressof(arr2d[0]), 1};
|
||||||
EXPECT_TRUE(s.size() == 1);
|
EXPECT_TRUE(s.size() == 1);
|
||||||
@ -329,7 +335,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
|
|
||||||
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
span<int> s{arr3d};
|
span<int> s{arr3d};
|
||||||
EXPECT_TRUE(s.size() == 12);
|
EXPECT_TRUE(s.size() == 12);
|
||||||
@ -355,7 +361,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(s[0] == 1);
|
EXPECT_TRUE(s[0] == 1);
|
||||||
EXPECT_TRUE(s[5] == 6);
|
EXPECT_TRUE(s[5] == 6);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const span<int[3][2]> s{std::addressof(arr3d[0]), 1};
|
const span<int[3][2]> s{std::addressof(arr3d[0]), 1};
|
||||||
EXPECT_TRUE(s.size() == 1);
|
EXPECT_TRUE(s.size() == 1);
|
||||||
@ -368,10 +374,10 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(s.size() == 5);
|
EXPECT_TRUE(s.size() == 5);
|
||||||
EXPECT_TRUE(s.data() == std::addressof(ao_arr[0]));
|
EXPECT_TRUE(s.data() == std::addressof(ao_arr[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, from_dynamic_array_constructor)
|
TEST(span_test, from_dynamic_array_constructor)
|
||||||
{
|
{
|
||||||
double(*arr)[3][4] = new double[100][3][4];
|
double(*arr)[3][4] = new double[100][3][4];
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -381,10 +387,10 @@ TEST(span_test, from_array_constructor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete[] arr;
|
delete[] arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, from_std_array_constructor)
|
TEST(span_test, from_std_array_constructor)
|
||||||
{
|
{
|
||||||
std::array<int, 4> arr = {1, 2, 3, 4};
|
std::array<int, 4> arr = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -422,7 +428,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(ao_arr.data() == fs.data());
|
EXPECT_TRUE(ao_arr.data() == fs.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
span<int, 2> s{arr};
|
span<int, 2> s{arr};
|
||||||
EXPECT_TRUE(s.size() == 2);
|
EXPECT_TRUE(s.size() == 2);
|
||||||
@ -453,7 +459,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
// try to take a temporary std::array
|
// try to take a temporary std::array
|
||||||
take_a_span(get_an_array());
|
take_a_span(get_an_array());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; };
|
auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; };
|
||||||
@ -461,10 +467,10 @@ TEST(span_test, from_array_constructor)
|
|||||||
// try to take a temporary std::array
|
// try to take a temporary std::array
|
||||||
take_a_span(get_an_array());
|
take_a_span(get_an_array());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, from_const_std_array_constructor)
|
TEST(span_test, from_const_std_array_constructor)
|
||||||
{
|
{
|
||||||
const std::array<int, 4> arr = {1, 2, 3, 4};
|
const std::array<int, 4> arr = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -487,7 +493,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(s.data() == ao_arr.data());
|
EXPECT_TRUE(s.data() == ao_arr.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
span<const int, 2> s{arr};
|
span<const int, 2> s{arr};
|
||||||
EXPECT_TRUE(s.size() == 2);
|
EXPECT_TRUE(s.size() == 2);
|
||||||
@ -503,7 +509,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
{
|
{
|
||||||
span<const int, 5> s{arr};
|
span<const int, 5> s{arr};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
auto get_an_array = []() -> const std::array<int, 4> { return {1, 2, 3, 4}; };
|
auto get_an_array = []() -> const std::array<int, 4> { return {1, 2, 3, 4}; };
|
||||||
@ -511,10 +517,10 @@ TEST(span_test, from_array_constructor)
|
|||||||
// try to take a temporary std::array
|
// try to take a temporary std::array
|
||||||
take_a_span(get_an_array());
|
take_a_span(get_an_array());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, from_std_array_const_constructor)
|
TEST(span_test, from_std_array_const_constructor)
|
||||||
{
|
{
|
||||||
std::array<const int, 4> arr = {1, 2, 3, 4};
|
std::array<const int, 4> arr = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -529,7 +535,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(s.data() == arr.data());
|
EXPECT_TRUE(s.data() == arr.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
span<const int, 2> s{arr};
|
span<const int, 2> s{arr};
|
||||||
EXPECT_TRUE(s.size() == 2);
|
EXPECT_TRUE(s.size() == 2);
|
||||||
@ -549,11 +555,11 @@ TEST(span_test, from_array_constructor)
|
|||||||
{
|
{
|
||||||
span<int, 4> s{arr};
|
span<int, 4> s{arr};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, from_container_constructor)
|
TEST(span_test, from_container_constructor)
|
||||||
{
|
{
|
||||||
std::vector<int> v = {1, 2, 3};
|
std::vector<int> v = {1, 2, 3};
|
||||||
const std::vector<int> cv = v;
|
const std::vector<int> cv = v;
|
||||||
|
|
||||||
@ -571,31 +577,31 @@ TEST(span_test, from_array_constructor)
|
|||||||
const std::string cstr = "hello";
|
const std::string cstr = "hello";
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
span<char> s{str};
|
span<char> s{str};
|
||||||
EXPECT_TRUE(s.size() == str.size());
|
EXPECT_TRUE(s.size() == str.size());
|
||||||
EXPECT_TRUE(s.data() == str.data()));
|
EXPECT_TRUE(s.data() == str.data()));
|
||||||
#endif
|
#endif
|
||||||
span<const char> cs{str};
|
span<const char> cs{str};
|
||||||
EXPECT_TRUE(cs.size() == str.size());
|
EXPECT_TRUE(cs.size() == str.size());
|
||||||
EXPECT_TRUE(cs.data() == str.data());
|
EXPECT_TRUE(cs.data() == str.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
span<char> s{cstr};
|
span<char> s{cstr};
|
||||||
#endif
|
#endif
|
||||||
span<const char> cs{cstr};
|
span<const char> cs{cstr};
|
||||||
EXPECT_TRUE(cs.size() == cstr.size());
|
EXPECT_TRUE(cs.size() == cstr.size());
|
||||||
EXPECT_TRUE(cs.data() == cstr.data());
|
EXPECT_TRUE(cs.data() == cstr.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
auto get_temp_vector = []() -> std::vector<int> { return {}; };
|
auto get_temp_vector = []() -> std::vector<int> { return {}; };
|
||||||
auto use_span = [](span<int> s) { static_cast<void>(s); };
|
auto use_span = [](span<int> s) { static_cast<void>(s); };
|
||||||
use_span(get_temp_vector());
|
use_span(get_temp_vector());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -605,11 +611,11 @@ TEST(span_test, from_array_constructor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
auto get_temp_string = []() -> std::string { return {}; };
|
auto get_temp_string = []() -> std::string { return {}; };
|
||||||
auto use_span = [](span<char> s) { static_cast<void>(s); };
|
auto use_span = [](span<char> s) { static_cast<void>(s); };
|
||||||
use_span(get_temp_string());
|
use_span(get_temp_string());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -619,11 +625,11 @@ TEST(span_test, from_array_constructor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
auto get_temp_vector = []() -> const std::vector<int> { return {}; };
|
auto get_temp_vector = []() -> const std::vector<int> { return {}; };
|
||||||
auto use_span = [](span<const char> s) { static_cast<void>(s); };
|
auto use_span = [](span<const char> s) { static_cast<void>(s); };
|
||||||
use_span(get_temp_vector());
|
use_span(get_temp_vector());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -633,49 +639,49 @@ TEST(span_test, from_array_constructor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
std::map<int, int> m;
|
std::map<int, int> m;
|
||||||
span<int> s{m};
|
span<int> s{m};
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(span_test, from_convertible_span_constructor){{span<DerivedClass> avd;
|
TEST(span_test, from_convertible_span_constructor){{span<DerivedClass> avd;
|
||||||
span<const DerivedClass> avcd = avd;
|
span<const DerivedClass> avcd = avd;
|
||||||
static_cast<void>(avcd);
|
static_cast<void>(avcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
span<DerivedClass> avd;
|
span<DerivedClass> avd;
|
||||||
span<BaseClass> avb = avd;
|
span<BaseClass> avb = avd;
|
||||||
static_cast<void>(avb);
|
static_cast<void>(avb);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
span<int> s;
|
span<int> s;
|
||||||
span<unsigned int> s2 = s;
|
span<unsigned int> s2 = s;
|
||||||
static_cast<void>(s2);
|
static_cast<void>(s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int> s;
|
span<int> s;
|
||||||
span<const unsigned int> s2 = s;
|
span<const unsigned int> s2 = s;
|
||||||
static_cast<void>(s2);
|
static_cast<void>(s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int> s;
|
span<int> s;
|
||||||
span<short> s2 = s;
|
span<short> s2 = s;
|
||||||
static_cast<void>(s2);
|
static_cast<void>(s2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, copy_move_and_assignment)
|
TEST(span_test, copy_move_and_assignment)
|
||||||
{
|
{
|
||||||
span<int> s1;
|
span<int> s1;
|
||||||
EXPECT_TRUE(s1.empty());
|
EXPECT_TRUE(s1.empty());
|
||||||
|
|
||||||
@ -692,19 +698,22 @@ TEST(span_test, from_array_constructor)
|
|||||||
auto use_span = [&](span<const int> s) {
|
auto use_span = [&](span<const int> s) {
|
||||||
EXPECT_TRUE(s.size() == 2);
|
EXPECT_TRUE(s.size() == 2);
|
||||||
EXPECT_TRUE(s.data() == &arr[1]);
|
EXPECT_TRUE(s.data() == &arr[1]);
|
||||||
}; use_span(get_temp_span());
|
};
|
||||||
|
use_span(get_temp_span());
|
||||||
|
|
||||||
s1 = get_temp_span();
|
s1 = get_temp_span();
|
||||||
EXPECT_TRUE(s1.size() == 2);
|
EXPECT_TRUE(s1.size() == 2);
|
||||||
EXPECT_TRUE(s1.data() == &arr[1]);
|
EXPECT_TRUE(s1.data() == &arr[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, first)
|
TEST(span_test, first)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. first";
|
std::cerr << "Expected Death. first";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -727,11 +736,11 @@ TEST(span_test, from_array_constructor)
|
|||||||
|
|
||||||
{
|
{
|
||||||
span<int, 5> av = arr;
|
span<int, 5> av = arr;
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
EXPECT_TRUE(av.first<6>().size() == 6);
|
EXPECT_TRUE(av.first<6>().size() == 6);
|
||||||
EXPECT_TRUE(av.first<-1>().size() == -1);
|
EXPECT_TRUE(av.first<-1>().size() == -1);
|
||||||
#endif
|
#endif
|
||||||
EXPECT_DEATH(av.first(6).size(), deathstring);
|
EXPECT_DEATH(av.first(6).size(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -739,14 +748,16 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(av.first<0>().size() == 0);
|
EXPECT_TRUE(av.first<0>().size() == 0);
|
||||||
EXPECT_TRUE(av.first(0).size() == 0);
|
EXPECT_TRUE(av.first(0).size() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, last)
|
TEST(span_test, last)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. last";
|
std::cerr << "Expected Death. last";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -769,10 +780,10 @@ TEST(span_test, from_array_constructor)
|
|||||||
|
|
||||||
{
|
{
|
||||||
span<int, 5> av = arr;
|
span<int, 5> av = arr;
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
EXPECT_TRUE(av.last<6>().size() == 6);
|
EXPECT_TRUE(av.last<6>().size() == 6);
|
||||||
#endif
|
#endif
|
||||||
EXPECT_DEATH(av.last(6).size(), deathstring);
|
EXPECT_DEATH(av.last(6).size(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -780,14 +791,16 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(av.last<0>().size() == 0);
|
EXPECT_TRUE(av.last<0>().size() == 0);
|
||||||
EXPECT_TRUE(av.last(0).size() == 0);
|
EXPECT_TRUE(av.last(0).size() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, subspan)
|
TEST(span_test, subspan)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. subspan";
|
std::cerr << "Expected Death. subspan";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -811,8 +824,8 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(decltype(av.subspan<0, 5>())::extent == 5);
|
EXPECT_TRUE(decltype(av.subspan<0, 5>())::extent == 5);
|
||||||
EXPECT_TRUE(av.subspan(0, 5).size() == 5);
|
EXPECT_TRUE(av.subspan(0, 5).size() == 5);
|
||||||
|
|
||||||
EXPECT_DEATH(av.subspan(0, 6).size(), deathstring);
|
EXPECT_DEATH(av.subspan(0, 6).size(), expected);
|
||||||
EXPECT_DEATH(av.subspan(1, 5).size(), deathstring);
|
EXPECT_DEATH(av.subspan(1, 5).size(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -821,7 +834,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(decltype(av.subspan<4, 0>())::extent == 0);
|
EXPECT_TRUE(decltype(av.subspan<4, 0>())::extent == 0);
|
||||||
EXPECT_TRUE(av.subspan(4, 0).size() == 0);
|
EXPECT_TRUE(av.subspan(4, 0).size() == 0);
|
||||||
EXPECT_TRUE(av.subspan(5, 0).size() == 0);
|
EXPECT_TRUE(av.subspan(5, 0).size() == 0);
|
||||||
EXPECT_DEATH(av.subspan(6, 0).size(), deathstring);
|
EXPECT_DEATH(av.subspan(6, 0).size(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -835,13 +848,13 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE((av.subspan<0, 0>().size()) == 0);
|
EXPECT_TRUE((av.subspan<0, 0>().size()) == 0);
|
||||||
EXPECT_TRUE(decltype(av.subspan<0, 0>())::extent == 0);
|
EXPECT_TRUE(decltype(av.subspan<0, 0>())::extent == 0);
|
||||||
EXPECT_TRUE(av.subspan(0, 0).size() == 0);
|
EXPECT_TRUE(av.subspan(0, 0).size() == 0);
|
||||||
EXPECT_DEATH((av.subspan<1, 0>().size()), deathstring);
|
EXPECT_DEATH((av.subspan<1, 0>().size()), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int> av;
|
span<int> av;
|
||||||
EXPECT_TRUE(av.subspan(0).size() == 0);
|
EXPECT_TRUE(av.subspan(0).size() == 0);
|
||||||
EXPECT_DEATH(av.subspan(1).size(), deathstring);
|
EXPECT_DEATH(av.subspan(1).size(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -850,7 +863,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(av.subspan(1).size() == 4);
|
EXPECT_TRUE(av.subspan(1).size() == 4);
|
||||||
EXPECT_TRUE(av.subspan(4).size() == 1);
|
EXPECT_TRUE(av.subspan(4).size() == 1);
|
||||||
EXPECT_TRUE(av.subspan(5).size() == 0);
|
EXPECT_TRUE(av.subspan(5).size() == 0);
|
||||||
EXPECT_DEATH(av.subspan(6).size(), deathstring);
|
EXPECT_DEATH(av.subspan(6).size(), expected);
|
||||||
const auto av2 = av.subspan(1);
|
const auto av2 = av.subspan(1);
|
||||||
for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2);
|
for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2);
|
||||||
}
|
}
|
||||||
@ -861,21 +874,21 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(av.subspan(1).size() == 4);
|
EXPECT_TRUE(av.subspan(1).size() == 4);
|
||||||
EXPECT_TRUE(av.subspan(4).size() == 1);
|
EXPECT_TRUE(av.subspan(4).size() == 1);
|
||||||
EXPECT_TRUE(av.subspan(5).size() == 0);
|
EXPECT_TRUE(av.subspan(5).size() == 0);
|
||||||
EXPECT_DEATH(av.subspan(6).size(), deathstring);
|
EXPECT_DEATH(av.subspan(6).size(), expected);
|
||||||
const auto av2 = av.subspan(1);
|
const auto av2 = av.subspan(1);
|
||||||
for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2);
|
for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, iterator_default_init)
|
TEST(span_test, iterator_default_init)
|
||||||
{
|
{
|
||||||
span<int>::iterator it1;
|
span<int>::iterator it1;
|
||||||
span<int>::iterator it2;
|
span<int>::iterator it2;
|
||||||
EXPECT_TRUE(it1 == it2);
|
EXPECT_TRUE(it1 == it2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, iterator_comparisons)
|
TEST(span_test, iterator_comparisons)
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
{
|
{
|
||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
@ -902,14 +915,15 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(s.end() > it2);
|
EXPECT_TRUE(s.end() > it2);
|
||||||
EXPECT_TRUE(s.end() >= it2);
|
EXPECT_TRUE(s.end() >= it2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, incomparable_iterators)
|
TEST(span_test, incomparable_iterators)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. incomparable_iterators";
|
std::cerr << "Expected Death. incomparable_iterators";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
int b[] = {1, 2, 3, 4};
|
int b[] = {1, 2, 3, 4};
|
||||||
@ -917,21 +931,23 @@ TEST(span_test, from_array_constructor)
|
|||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
span<int> s2 = b;
|
span<int> s2 = b;
|
||||||
#if (__cplusplus > 201402L)
|
#if (__cplusplus > 201402L)
|
||||||
EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() == s2.begin()), deathstring);
|
EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() == s2.begin()), expected);
|
||||||
EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() <= s2.begin()), deathstring);
|
EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() <= s2.begin()), expected);
|
||||||
#else
|
#else
|
||||||
EXPECT_DEATH(bool _ = (s.begin() == s2.begin()), deathstring);
|
EXPECT_DEATH(bool _ = (s.begin() == s2.begin()), expected);
|
||||||
EXPECT_DEATH(bool _ = (s.begin() <= s2.begin()), deathstring);
|
EXPECT_DEATH(bool _ = (s.begin() <= s2.begin()), expected);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, begin_end)
|
TEST(span_test, begin_end)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. begin_end";
|
std::cerr << "Expected Death. begin_end";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
@ -956,7 +972,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
|
|
||||||
auto beyond = s.end();
|
auto beyond = s.end();
|
||||||
EXPECT_TRUE(it != beyond);
|
EXPECT_TRUE(it != beyond);
|
||||||
EXPECT_DEATH(*beyond, deathstring);
|
EXPECT_DEATH(*beyond, expected);
|
||||||
|
|
||||||
EXPECT_TRUE(beyond - first == 4);
|
EXPECT_TRUE(beyond - first == 4);
|
||||||
EXPECT_TRUE(first - first == 0);
|
EXPECT_TRUE(first - first == 0);
|
||||||
@ -982,14 +998,16 @@ TEST(span_test, from_array_constructor)
|
|||||||
|
|
||||||
for (const auto& n : s) { EXPECT_TRUE(n == 5); }
|
for (const auto& n : s) { EXPECT_TRUE(n == 5); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, rbegin_rend)
|
TEST(span_test, rbegin_rend)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. rbegin_rend";
|
std::cerr << "Expected Death. rbegin_rend";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
@ -1002,9 +1020,9 @@ TEST(span_test, from_array_constructor)
|
|||||||
auto beyond = s.rend();
|
auto beyond = s.rend();
|
||||||
EXPECT_TRUE(it != beyond);
|
EXPECT_TRUE(it != beyond);
|
||||||
#if (__cplusplus > 201402L)
|
#if (__cplusplus > 201402L)
|
||||||
EXPECT_DEATH([[maybe_unused]] auto _ = *beyond , deathstring);
|
EXPECT_DEATH([[maybe_unused]] auto _ = *beyond, expected);
|
||||||
#else
|
#else
|
||||||
EXPECT_DEATH(auto _ = *beyond , deathstring);
|
EXPECT_DEATH(auto _ = *beyond, expected);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(beyond - first == 4);
|
EXPECT_TRUE(beyond - first == 4);
|
||||||
@ -1031,14 +1049,15 @@ TEST(span_test, from_array_constructor)
|
|||||||
|
|
||||||
for (const auto& n : s) { EXPECT_TRUE(n == 5); }
|
for (const auto& n : s) { EXPECT_TRUE(n == 5); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, as_bytes)
|
TEST(span_test, as_bytes)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. as_bytes";
|
std::cerr << "Expected Death. as_bytes";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
{
|
{
|
||||||
@ -1068,24 +1087,24 @@ TEST(span_test, from_array_constructor)
|
|||||||
|
|
||||||
int b[5] = {1, 2, 3, 4, 5};
|
int b[5] = {1, 2, 3, 4, 5};
|
||||||
{
|
{
|
||||||
span<int> sp(begin(b), static_cast<size_t>(-2));
|
span<int> sp(std::begin(b), static_cast<size_t>(-2));
|
||||||
EXPECT_DEATH((void) sp.size_bytes(), deathstring);
|
EXPECT_DEATH((void) sp.size_bytes(), expected);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(span_test, as_writable_bytes)
|
TEST(span_test, as_writable_bytes)
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
// you should not be able to get writeable bytes for const objects
|
// you should not be able to get writeable bytes for const objects
|
||||||
span<const int> s = a;
|
span<const int> s = a;
|
||||||
EXPECT_TRUE(s.size() == 4);
|
EXPECT_TRUE(s.size() == 4);
|
||||||
span<const byte> bs = as_writable_bytes(s);
|
span<const byte> bs = as_writable_bytes(s);
|
||||||
EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
||||||
EXPECT_TRUE(bs.size() == s.size_bytes());
|
EXPECT_TRUE(bs.size() == s.size_bytes());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1104,14 +1123,16 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
||||||
EXPECT_TRUE(bs.size() == s.size_bytes());
|
EXPECT_TRUE(bs.size() == s.size_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, fixed_size_conversions)
|
TEST(span_test, fixed_size_conversions)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. fixed_size_conversions";
|
std::cerr << "Expected Death. fixed_size_conversions";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
int arr[] = {1, 2, 3, 4};
|
int arr[] = {1, 2, 3, 4};
|
||||||
|
|
||||||
// converting to an span from an equal size array is ok
|
// converting to an span from an equal size array is ok
|
||||||
@ -1125,8 +1146,8 @@ TEST(span_test, from_array_constructor)
|
|||||||
static_cast<void>(s);
|
static_cast<void>(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialization or assignment to static span that REDUCES size is NOT ok
|
// initialization or assignment to static span that REDUCES size is NOT ok
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
span<int, 2> s = arr;
|
span<int, 2> s = arr;
|
||||||
}
|
}
|
||||||
@ -1134,7 +1155,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
span<int, 2> s2 = s4;
|
span<int, 2> s2 = s4;
|
||||||
static_cast<void>(s2);
|
static_cast<void>(s2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// even when done dynamically
|
// even when done dynamically
|
||||||
{
|
{
|
||||||
@ -1146,7 +1167,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
const span<int, 2> s2 = s;
|
const span<int, 2> s2 = s;
|
||||||
static_cast<void>(s2);
|
static_cast<void>(s2);
|
||||||
};
|
};
|
||||||
EXPECT_DEATH(f(), deathstring);
|
EXPECT_DEATH(f(), expected);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1179,7 +1200,7 @@ TEST(span_test, from_array_constructor)
|
|||||||
// initialization or assignment to static span that requires size INCREASE is not ok.
|
// initialization or assignment to static span that requires size INCREASE is not ok.
|
||||||
int arr2[2] = {1, 2};
|
int arr2[2] = {1, 2};
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
span<int, 4> s3 = arr2;
|
span<int, 4> s3 = arr2;
|
||||||
}
|
}
|
||||||
@ -1187,28 +1208,29 @@ TEST(span_test, from_array_constructor)
|
|||||||
span<int, 2> s2 = arr2;
|
span<int, 2> s2 = arr2;
|
||||||
span<int, 4> s4a = s2;
|
span<int, 4> s4a = s2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
auto f = [&]() {
|
auto f = [&]() {
|
||||||
const span<int, 4> _s4{arr2, 2};
|
const span<int, 4> _s4{arr2, 2};
|
||||||
static_cast<void>(_s4);
|
static_cast<void>(_s4);
|
||||||
};
|
};
|
||||||
EXPECT_DEATH(f(), deathstring);
|
EXPECT_DEATH(f(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// This no longer compiles. There is no suitable conversion from dynamic span to a fixed size span.
|
// This no longer compiles. There is no suitable conversion from dynamic span to a fixed size
|
||||||
|
span.
|
||||||
// this should fail - we are trying to assign a small dynamic span to a fixed_size larger one
|
// this should fail - we are trying to assign a small dynamic span to a fixed_size larger one
|
||||||
span<int> av = arr2; auto f = [&]() {
|
span<int> av = arr2; auto f = [&]() {
|
||||||
const span<int, 4> _s4 = av;
|
const span<int, 4> _s4 = av;
|
||||||
static_cast<void>(_s4);
|
static_cast<void>(_s4);
|
||||||
};
|
};
|
||||||
EXPECT_DEATH(f(), deathstring);
|
EXPECT_DEATH(f(), expected);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, interop_with_std_regex)
|
TEST(span_test, interop_with_std_regex)
|
||||||
{
|
{
|
||||||
char lat[] = {'1', '2', '3', '4', '5', '6', 'E', 'F', 'G'};
|
char lat[] = {'1', '2', '3', '4', '5', '6', 'E', 'F', 'G'};
|
||||||
span<char> s = lat;
|
span<char> s = lat;
|
||||||
const auto f_it = s.begin() + 7;
|
const auto f_it = s.begin() + 7;
|
||||||
@ -1228,21 +1250,21 @@ TEST(span_test, from_array_constructor)
|
|||||||
EXPECT_TRUE(match[0].matched);
|
EXPECT_TRUE(match[0].matched);
|
||||||
EXPECT_TRUE(match[0].first == f_it);
|
EXPECT_TRUE(match[0].first == f_it);
|
||||||
EXPECT_TRUE(match[0].second == (f_it + 1));
|
EXPECT_TRUE(match[0].second == (f_it + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, default_constructible)
|
TEST(span_test, default_constructible)
|
||||||
{
|
{
|
||||||
EXPECT_TRUE((std::is_default_constructible<span<int>>::value));
|
EXPECT_TRUE((std::is_default_constructible<span<int>>::value));
|
||||||
EXPECT_TRUE((std::is_default_constructible<span<int, 0>>::value));
|
EXPECT_TRUE((std::is_default_constructible<span<int, 0>>::value));
|
||||||
EXPECT_FALSE((std::is_default_constructible<span<int, 42>>::value));
|
EXPECT_FALSE((std::is_default_constructible<span<int, 42>>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, std_container_ctad)
|
TEST(span_test, std_container_ctad)
|
||||||
{
|
{
|
||||||
#if (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L))
|
#if (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L))
|
||||||
// this test is just to verify that these compile
|
// this test is just to verify that these compile
|
||||||
{
|
{
|
||||||
std::vector<int> v{1,2,3,4};
|
std::vector<int> v{1, 2, 3, 4};
|
||||||
gsl::span sp{v};
|
gsl::span sp{v};
|
||||||
static_assert(std::is_same<decltype(sp), gsl::span<int>>::value);
|
static_assert(std::is_same<decltype(sp), gsl::span<int>>::value);
|
||||||
}
|
}
|
||||||
@ -1259,20 +1281,39 @@ TEST(span_test, from_array_constructor)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_test, front_back)
|
TEST(span_test, front_back)
|
||||||
{
|
{
|
||||||
int arr[5] = {1,2,3,4,5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
span<int> s{arr};
|
span<int> s{arr};
|
||||||
EXPECT_TRUE(s.front() == 1);
|
EXPECT_TRUE(s.front() == 1);
|
||||||
EXPECT_TRUE(s.back() == 5);
|
EXPECT_TRUE(s.back() == 5);
|
||||||
|
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. front_back";
|
std::cerr << "Expected Death. front_back";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
span<int> s2;
|
span<int> s2;
|
||||||
EXPECT_DEATH(s2.front(), deathstring);
|
EXPECT_DEATH(s2.front(), expected);
|
||||||
EXPECT_DEATH(s2.back(), deathstring);
|
EXPECT_DEATH(s2.back(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(FORCE_STD_SPAN_TESTS) || defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
|
||||||
|
TEST(span_test, std_span)
|
||||||
|
{
|
||||||
|
// make sure std::span can be constructed from gsl::span
|
||||||
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
|
gsl::span<int> gsl_span{arr};
|
||||||
|
#if defined(__cpp_lib_ranges) || (defined(_MSVC_STL_VERSION) && defined(__cpp_lib_concepts))
|
||||||
|
EXPECT_TRUE(std::to_address(gsl_span.begin()) == gsl_span.data());
|
||||||
|
EXPECT_TRUE(std::to_address(gsl_span.end()) == gsl_span.data() + gsl_span.size());
|
||||||
|
#endif // __cpp_lib_ranges
|
||||||
|
|
||||||
|
std::span<int> std_span = gsl_span;
|
||||||
|
EXPECT_TRUE(std_span.data() == gsl_span.data());
|
||||||
|
EXPECT_TRUE(std_span.size() == gsl_span.size());
|
||||||
|
}
|
||||||
|
#endif // defined(FORCE_STD_SPAN_TESTS) || defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
|
||||||
|
@ -14,30 +14,40 @@
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
|
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
namespace gsl
|
#include "deathTestCommon.h"
|
||||||
{
|
|
||||||
struct fail_fast;
|
|
||||||
} // namespace gsl
|
|
||||||
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
bool helper(not_null<int*> p) { return *p == 12; }
|
bool helper(not_null<int*> p) { return *p == 12; }
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
bool helper_const(not_null<const int*> p) { return *p == 12; }
|
bool helper_const(not_null<const int*> p) { return *p == 12; }
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
bool strict_helper(strict_not_null<int*> p) { return *p == 12; }
|
bool strict_helper(strict_not_null<int*> p) { return *p == 12; }
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||||
|
// clang-format on
|
||||||
bool strict_helper_const(strict_not_null<const int*> p) { return *p == 12; }
|
bool strict_helper_const(strict_not_null<const int*> p) { return *p == 12; }
|
||||||
|
|
||||||
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
int* return_pointer() { return nullptr; }
|
int* return_pointer() { return nullptr; }
|
||||||
const int* return_pointer_const() { return nullptr; }
|
const int* return_pointer_const() { return nullptr; }
|
||||||
|
#endif
|
||||||
|
} // namespace
|
||||||
|
|
||||||
TEST(strict_notnull_tests, TestStrictNotNull)
|
TEST(strict_notnull_tests, TestStrictNotNull)
|
||||||
{
|
{
|
||||||
@ -123,17 +133,14 @@ TEST(strict_notnull_tests, TestStrictNotNull)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||||
namespace
|
|
||||||
{
|
|
||||||
static constexpr char deathstring[] = "Expected Death";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
|
TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. TestStrictNotNullConstructorTypeDeduction";
|
std::cerr << "Expected Death. TestStrictNotNullConstructorTypeDeduction";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
{
|
{
|
||||||
int i = 42;
|
int i = 42;
|
||||||
@ -161,7 +168,7 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
|
|||||||
int* p1 = nullptr;
|
int* p1 = nullptr;
|
||||||
const strict_not_null x{p1};
|
const strict_not_null x{p1};
|
||||||
};
|
};
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -169,14 +176,14 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
|
|||||||
const int* p1 = nullptr;
|
const int* p1 = nullptr;
|
||||||
const strict_not_null x{p1};
|
const strict_not_null x{p1};
|
||||||
};
|
};
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int* p = nullptr;
|
int* p = nullptr;
|
||||||
|
|
||||||
EXPECT_DEATH(helper(strict_not_null{p}), deathstring);
|
EXPECT_DEATH(helper(strict_not_null{p}), expected);
|
||||||
EXPECT_DEATH(helper_const(strict_not_null{p}), deathstring);
|
EXPECT_DEATH(helper_const(strict_not_null{p}), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
|
@ -28,13 +28,10 @@
|
|||||||
#include <type_traits> // for remove_reference<>::type
|
#include <type_traits> // for remove_reference<>::type
|
||||||
#include <vector> // for vector, allocator
|
#include <vector> // for vector, allocator
|
||||||
|
|
||||||
using namespace std;
|
#include "deathTestCommon.h"
|
||||||
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
static constexpr char deathstring[] = "Expected Death";
|
|
||||||
}
|
|
||||||
// Generic string functions
|
// Generic string functions
|
||||||
|
|
||||||
namespace generic
|
namespace generic
|
||||||
@ -76,8 +73,7 @@ T create()
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void use(basic_string_span<T, gsl::dynamic_extent>)
|
void use(basic_string_span<T, gsl::dynamic_extent>)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
czstring_span<> CreateTempName(string_span<> span)
|
czstring_span<> CreateTempName(string_span<> span)
|
||||||
@ -85,7 +81,8 @@ czstring_span<> CreateTempName(string_span<> span)
|
|||||||
Expects(span.size() > 1);
|
Expects(span.size() > 1);
|
||||||
|
|
||||||
std::size_t last = 0;
|
std::size_t last = 0;
|
||||||
if (span.size() > 4) {
|
if (span.size() > 4)
|
||||||
|
{
|
||||||
span[0] = 't';
|
span[0] = 't';
|
||||||
span[1] = 'm';
|
span[1] = 'm';
|
||||||
span[2] = 'p';
|
span[2] = 'p';
|
||||||
@ -102,7 +99,8 @@ cwzstring_span<> CreateTempNameW(wstring_span<> span)
|
|||||||
Expects(span.size() > 1);
|
Expects(span.size() > 1);
|
||||||
|
|
||||||
std::size_t last = 0;
|
std::size_t last = 0;
|
||||||
if (span.size() > 4) {
|
if (span.size() > 4)
|
||||||
|
{
|
||||||
span[0] = L't';
|
span[0] = L't';
|
||||||
span[1] = L'm';
|
span[1] = L'm';
|
||||||
span[2] = L'p';
|
span[2] = L'p';
|
||||||
@ -119,7 +117,8 @@ cu16zstring_span<> CreateTempNameU16(u16string_span<> span)
|
|||||||
Expects(span.size() > 1);
|
Expects(span.size() > 1);
|
||||||
|
|
||||||
std::size_t last = 0;
|
std::size_t last = 0;
|
||||||
if (span.size() > 4) {
|
if (span.size() > 4)
|
||||||
|
{
|
||||||
span[0] = u't';
|
span[0] = u't';
|
||||||
span[1] = u'm';
|
span[1] = u'm';
|
||||||
span[2] = u'p';
|
span[2] = u'p';
|
||||||
@ -136,7 +135,8 @@ cu32zstring_span<> CreateTempNameU32(u32string_span<> span)
|
|||||||
Expects(span.size() > 1);
|
Expects(span.size() > 1);
|
||||||
|
|
||||||
std::size_t last = 0;
|
std::size_t last = 0;
|
||||||
if (span.size() > 4) {
|
if (span.size() > 4)
|
||||||
|
{
|
||||||
span[0] = U't';
|
span[0] = U't';
|
||||||
span[1] = U'm';
|
span[1] = U'm';
|
||||||
span[2] = U'p';
|
span[2] = U'p';
|
||||||
@ -950,10 +950,11 @@ TEST(string_span_tests, Conversion)
|
|||||||
|
|
||||||
TEST(string_span_tests, zstring)
|
TEST(string_span_tests, zstring)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. zstring";
|
std::cerr << "Expected Death. zstring";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
// create zspan from zero terminated string
|
// create zspan from zero terminated string
|
||||||
{
|
{
|
||||||
@ -973,7 +974,7 @@ TEST(string_span_tests, zstring)
|
|||||||
buf[0] = 'a';
|
buf[0] = 'a';
|
||||||
|
|
||||||
auto workaround_macro = [&]() { const zstring_span<> zspan({buf, 1}); };
|
auto workaround_macro = [&]() { const zstring_span<> zspan({buf, 1}); };
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
// usage scenario: create zero-terminated temp file name and pass to a legacy API
|
// usage scenario: create zero-terminated temp file name and pass to a legacy API
|
||||||
@ -981,8 +982,9 @@ TEST(string_span_tests, zstring)
|
|||||||
char buf[10];
|
char buf[10];
|
||||||
|
|
||||||
auto name = CreateTempName({buf, 10});
|
auto name = CreateTempName({buf, 10});
|
||||||
if (!name.empty()) {
|
if (!name.empty())
|
||||||
czstring<> str = name.assume_z();
|
{
|
||||||
|
czstring str = name.assume_z();
|
||||||
EXPECT_TRUE(generic::strlen(str) == 3);
|
EXPECT_TRUE(generic::strlen(str) == 3);
|
||||||
EXPECT_TRUE(*(str + 3) == '\0');
|
EXPECT_TRUE(*(str + 3) == '\0');
|
||||||
}
|
}
|
||||||
@ -991,10 +993,11 @@ TEST(string_span_tests, zstring)
|
|||||||
|
|
||||||
TEST(string_span_tests, wzstring)
|
TEST(string_span_tests, wzstring)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. wzstring";
|
std::cerr << "Expected Death. wzstring";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
// create zspan from zero terminated string
|
// create zspan from zero terminated string
|
||||||
{
|
{
|
||||||
@ -1014,7 +1017,7 @@ TEST(string_span_tests, wzstring)
|
|||||||
buf[0] = L'a';
|
buf[0] = L'a';
|
||||||
|
|
||||||
const auto workaround_macro = [&]() { const wzstring_span<> zspan({buf, 1}); };
|
const auto workaround_macro = [&]() { const wzstring_span<> zspan({buf, 1}); };
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
// usage scenario: create zero-terminated temp file name and pass to a legacy API
|
// usage scenario: create zero-terminated temp file name and pass to a legacy API
|
||||||
@ -1022,8 +1025,9 @@ TEST(string_span_tests, wzstring)
|
|||||||
wchar_t buf[10];
|
wchar_t buf[10];
|
||||||
|
|
||||||
const auto name = CreateTempNameW({buf, 10});
|
const auto name = CreateTempNameW({buf, 10});
|
||||||
if (!name.empty()) {
|
if (!name.empty())
|
||||||
cwzstring<> str = name.assume_z();
|
{
|
||||||
|
cwzstring str = name.assume_z();
|
||||||
EXPECT_TRUE(generic::strnlen(str, 10) == 3);
|
EXPECT_TRUE(generic::strnlen(str, 10) == 3);
|
||||||
EXPECT_TRUE(*(str + 3) == L'\0');
|
EXPECT_TRUE(*(str + 3) == L'\0');
|
||||||
}
|
}
|
||||||
@ -1032,10 +1036,11 @@ TEST(string_span_tests, wzstring)
|
|||||||
|
|
||||||
TEST(string_span_tests, u16zstring)
|
TEST(string_span_tests, u16zstring)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. u16zstring";
|
std::cerr << "Expected Death. u16zstring";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
// create zspan from zero terminated string
|
// create zspan from zero terminated string
|
||||||
{
|
{
|
||||||
@ -1055,7 +1060,7 @@ TEST(string_span_tests, u16zstring)
|
|||||||
buf[0] = u'a';
|
buf[0] = u'a';
|
||||||
|
|
||||||
const auto workaround_macro = [&]() { const u16zstring_span<> zspan({buf, 1}); };
|
const auto workaround_macro = [&]() { const u16zstring_span<> zspan({buf, 1}); };
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
// usage scenario: create zero-terminated temp file name and pass to a legacy API
|
// usage scenario: create zero-terminated temp file name and pass to a legacy API
|
||||||
@ -1063,8 +1068,9 @@ TEST(string_span_tests, u16zstring)
|
|||||||
char16_t buf[10];
|
char16_t buf[10];
|
||||||
|
|
||||||
const auto name = CreateTempNameU16({buf, 10});
|
const auto name = CreateTempNameU16({buf, 10});
|
||||||
if (!name.empty()) {
|
if (!name.empty())
|
||||||
cu16zstring<> str = name.assume_z();
|
{
|
||||||
|
cu16zstring str = name.assume_z();
|
||||||
EXPECT_TRUE(generic::strnlen(str, 10) == 3);
|
EXPECT_TRUE(generic::strnlen(str, 10) == 3);
|
||||||
EXPECT_TRUE(*(str + 3) == L'\0');
|
EXPECT_TRUE(*(str + 3) == L'\0');
|
||||||
}
|
}
|
||||||
@ -1073,10 +1079,11 @@ TEST(string_span_tests, u16zstring)
|
|||||||
|
|
||||||
TEST(string_span_tests, u32zstring)
|
TEST(string_span_tests, u32zstring)
|
||||||
{
|
{
|
||||||
std::set_terminate([] {
|
const auto terminateHandler = std::set_terminate([] {
|
||||||
std::cerr << "Expected Death. u31zstring";
|
std::cerr << "Expected Death. u31zstring";
|
||||||
std::abort();
|
std::abort();
|
||||||
});
|
});
|
||||||
|
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||||
|
|
||||||
// create zspan from zero terminated string
|
// create zspan from zero terminated string
|
||||||
{
|
{
|
||||||
@ -1096,7 +1103,7 @@ TEST(string_span_tests, u32zstring)
|
|||||||
buf[0] = u'a';
|
buf[0] = u'a';
|
||||||
|
|
||||||
const auto workaround_macro = [&]() { const u32zstring_span<> zspan({buf, 1}); };
|
const auto workaround_macro = [&]() { const u32zstring_span<> zspan({buf, 1}); };
|
||||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
EXPECT_DEATH(workaround_macro(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
// usage scenario: create zero-terminated temp file name and pass to a legacy API
|
// usage scenario: create zero-terminated temp file name and pass to a legacy API
|
||||||
@ -1104,8 +1111,9 @@ TEST(string_span_tests, u32zstring)
|
|||||||
char32_t buf[10];
|
char32_t buf[10];
|
||||||
|
|
||||||
const auto name = CreateTempNameU32({buf, 10});
|
const auto name = CreateTempNameU32({buf, 10});
|
||||||
if (!name.empty()) {
|
if (!name.empty())
|
||||||
cu32zstring<> str = name.assume_z();
|
{
|
||||||
|
cu32zstring str = name.assume_z();
|
||||||
EXPECT_TRUE(generic::strnlen(str, 10) == 3);
|
EXPECT_TRUE(generic::strnlen(str, 10) == 3);
|
||||||
EXPECT_TRUE(*(str + 3) == L'\0');
|
EXPECT_TRUE(*(str + 3) == L'\0');
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,15 @@
|
|||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <gsl/util> // finally, narrow_cast
|
|
||||||
#include <gsl/narrow> // for narrow, narrowing_error
|
|
||||||
#include <algorithm> // for move
|
#include <algorithm> // for move
|
||||||
|
#include <complex>
|
||||||
|
#include <cstddef> // for std::ptrdiff_t
|
||||||
#include <functional> // for reference_wrapper, _Bind_helper<>::type
|
#include <functional> // for reference_wrapper, _Bind_helper<>::type
|
||||||
|
#include <gsl/narrow> // for narrow, narrowing_error
|
||||||
|
#include <gsl/util> // finally, narrow_cast
|
||||||
#include <limits> // for numeric_limits
|
#include <limits> // for numeric_limits
|
||||||
#include <stdint.h> // for uint32_t, int32_t
|
#include <stdint.h> // for uint32_t, int32_t
|
||||||
#include <type_traits> // for is_same
|
#include <type_traits> // for is_same
|
||||||
#include <cstddef> // for std::ptrdiff_t
|
|
||||||
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
@ -32,8 +33,7 @@ namespace
|
|||||||
void f(int& i) { i += 1; }
|
void f(int& i) { i += 1; }
|
||||||
static int j = 0;
|
static int j = 0;
|
||||||
void g() { j += 1; }
|
void g() { j += 1; }
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
TEST(utils_tests, sanity_check_for_gsl_index_typedef)
|
TEST(utils_tests, sanity_check_for_gsl_index_typedef)
|
||||||
{
|
{
|
||||||
@ -123,6 +123,7 @@ TEST(utils_tests, narrow_cast)
|
|||||||
EXPECT_TRUE(uc == 44);
|
EXPECT_TRUE(uc == 44);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GSL_KERNEL_MODE
|
||||||
TEST(utils_tests, narrow)
|
TEST(utils_tests, narrow)
|
||||||
{
|
{
|
||||||
int n = 120;
|
int n = 120;
|
||||||
@ -144,4 +145,11 @@ TEST(utils_tests, narrow)
|
|||||||
|
|
||||||
n = -42;
|
n = -42;
|
||||||
EXPECT_THROW(narrow<unsigned>(n), narrowing_error);
|
EXPECT_THROW(narrow<unsigned>(n), narrowing_error);
|
||||||
|
|
||||||
|
EXPECT_TRUE(
|
||||||
|
narrow<std::complex<float>>(std::complex<double>(4, 2)) == std::complex<float>(4, 2));
|
||||||
|
EXPECT_THROW(narrow<std::complex<float>>(std::complex<double>(4.2)), narrowing_error);
|
||||||
|
|
||||||
|
EXPECT_TRUE(narrow<int>(float(1)) == 1);
|
||||||
}
|
}
|
||||||
|
#endif // GSL_KERNEL_MODE
|
||||||
|
Loading…
Reference in New Issue
Block a user