mirror of
https://github.com/microsoft/GSL.git
synced 2026-08-06 13:44:09 +02:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a353456718 | |||
| 99a29ce797 | |||
| ebf0498363 | |||
| c412deb31e | |||
| bcf008ae55 | |||
| e0880931ae | |||
| c31a9ad5e8 | |||
| da80ce15d8 | |||
| f09b24970d | |||
| 8a4b9ed0bf | |||
| b26f6d5ec7 | |||
| c1cbb41b42 | |||
| ef0ffefe52 | |||
| 176c92e802 | |||
| 84aeb59f26 | |||
| d9fa328f89 | |||
| d0052f6320 | |||
| 3b3478eaf8 | |||
| e427b02c89 | |||
| 25bb4bd948 | |||
| 1c509ad8e1 | |||
| eca0eca6f1 | |||
| a47352cb2a | |||
| d15cb5fdbe | |||
| a6cef6bc6c | |||
| ec6cd75d57 |
@@ -1,9 +1,9 @@
|
||||
name: CI_Android
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
Android:
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
echo "Emulator starting"
|
||||
|
||||
- name: Configure
|
||||
run: cmake -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-bundle/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=16 -DANDROID_ABI=x86_64 -DCMAKE_BUILD_TYPE=Debug ..
|
||||
|
||||
- name: Build
|
||||
run: cmake --build . --parallel
|
||||
@@ -47,4 +47,4 @@ jobs:
|
||||
adb shell find /data/local/tmp/tests -maxdepth 1 -exec chmod +x {} \\\;
|
||||
|
||||
- name: Test
|
||||
run: adb shell find /data/local/tmp/tests -name "*_tests" -maxdepth 1 -exec {} \\\;
|
||||
run: adb shell find /data/local/tmp/tests -name "*_tests" -maxdepth 1 -exec {} \\\;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
name: CI_iOS
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
iOS:
|
||||
@@ -21,14 +21,15 @@ jobs:
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake \
|
||||
-Werror=dev \
|
||||
-GXcode \
|
||||
-DCMAKE_SYSTEM_NAME=iOS \
|
||||
"-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=8 \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=9 \
|
||||
-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
|
||||
"-DMACOSX_BUNDLE_GUI_IDENTIFIER=GSL.\$(EXECUTABLE_NAME)" \
|
||||
-DMACOSX_BUNDLE_BUNDLE_VERSION=3.0.1 \
|
||||
-DMACOSX_BUNDLE_SHORT_VERSION_STRING=3.0.1 \
|
||||
-DMACOSX_BUNDLE_BUNDLE_VERSION=3.1.0 \
|
||||
-DMACOSX_BUNDLE_SHORT_VERSION_STRING=3.1.0 \
|
||||
..
|
||||
|
||||
- name: Build
|
||||
|
||||
-337
@@ -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}
|
||||
+21
-77
@@ -3,12 +3,12 @@ cmake_minimum_required(VERSION 3.1.3...3.16)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
include(guidelineSupportLibrary)
|
||||
|
||||
project(GSL VERSION 3.1.0 LANGUAGES CXX)
|
||||
project(GSL
|
||||
VERSION 4.0.0
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
include(ExternalProject)
|
||||
find_package(Git)
|
||||
|
||||
# Use GNUInstallDirs to provide the right locations on all platforms
|
||||
# Must include after the project call due to GNUInstallDirs requiring a language be enabled (IE. CXX)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Creates a library GSL which is an interface (header files only)
|
||||
@@ -28,6 +28,10 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(GSL_STANDALONE_PROJECT ON)
|
||||
endif()
|
||||
|
||||
### Project options
|
||||
option(GSL_INSTALL "Generate and install GSL target" ${GSL_STANDALONE_PROJECT})
|
||||
option(GSL_TEST "Build and perform GSL tests" ${GSL_STANDALONE_PROJECT})
|
||||
|
||||
# This GSL implementation generally assumes a platform that implements C++14 support.
|
||||
set(gsl_min_cxx_standard "14")
|
||||
|
||||
@@ -37,81 +41,21 @@ else()
|
||||
gsl_client_set_cxx_standard(${gsl_min_cxx_standard})
|
||||
endif()
|
||||
|
||||
# add definitions to the library and targets that consume it
|
||||
target_compile_definitions(GSL INTERFACE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:
|
||||
# remove unnecessary warnings about unchecked iterators
|
||||
_SCL_SECURE_NO_WARNINGS
|
||||
# remove deprecation warnings about std::uncaught_exception() (from catch)
|
||||
_SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING
|
||||
>
|
||||
)
|
||||
# Setup include directory
|
||||
add_subdirectory(include)
|
||||
|
||||
# add include folders to the library and targets that consume it
|
||||
# the SYSTEM keyword suppresses warnings for users of the library
|
||||
if(GSL_STANDALONE_PROJECT)
|
||||
target_include_directories(GSL INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
else()
|
||||
target_include_directories(GSL SYSTEM INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
# Add natvis file
|
||||
gsl_add_native_visualizer_support()
|
||||
|
||||
# Add packaging support
|
||||
gsl_create_packaging_file()
|
||||
|
||||
if (GSL_INSTALL)
|
||||
# Setup install/export logic
|
||||
gsl_install_logic()
|
||||
endif()
|
||||
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.7.8)
|
||||
if (MSVC_IDE)
|
||||
option(GSL_VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE)
|
||||
else()
|
||||
set(GSL_VS_ADD_NATIVE_VISUALIZERS FALSE CACHE INTERNAL "Native visualizers are Visual Studio extension" FORCE)
|
||||
endif()
|
||||
|
||||
# add natvis file to the library so it will automatically be loaded into Visual Studio
|
||||
if(GSL_VS_ADD_NATIVE_VISUALIZERS)
|
||||
target_sources(GSL INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis>
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(TARGETS GSL EXPORT Microsoft.GSLConfig)
|
||||
install(
|
||||
DIRECTORY include/gsl
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
# Make library importable by other projects
|
||||
install(EXPORT Microsoft.GSLConfig NAMESPACE Microsoft.GSL:: DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/Microsoft.GSL)
|
||||
export(TARGETS GSL NAMESPACE Microsoft.GSL:: FILE Microsoft.GSLConfig.cmake)
|
||||
|
||||
# Add find_package() versioning support. The version for
|
||||
# generated Microsoft.GSLConfigVersion.cmake will be used from
|
||||
# last project() command. The version's compatibility is set between all
|
||||
# minor versions (as it was in prev. GSL releases).
|
||||
include(CMakePackageConfigHelpers)
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.14.0")
|
||||
write_basic_package_version_file(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Microsoft.GSLConfigVersion.cmake
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
else()
|
||||
write_basic_package_version_file(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Microsoft.GSLConfigVersion.cmake
|
||||
COMPATIBILITY SameMajorVersion
|
||||
ARCH_INDEPENDENT
|
||||
)
|
||||
endif()
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Microsoft.GSLConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/Microsoft.GSL)
|
||||
|
||||
option(GSL_TEST "Generate tests." ${GSL_STANDALONE_PROJECT})
|
||||
if (GSL_TEST)
|
||||
enable_testing()
|
||||
if(IOS)
|
||||
add_compile_definitions(
|
||||
GTEST_HAS_DEATH_TEST=1
|
||||
)
|
||||
endif()
|
||||
add_subdirectory(tests)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ Please submit a Contributor License Agreement (CLA) before submitting a pull req
|
||||
Your pull request should:
|
||||
|
||||
* Include a description of what your change intends to do
|
||||
* Be a child commit of a reasonably recent commit in the **master** branch
|
||||
* Be a child commit of a reasonably recent commit in the **main** branch
|
||||
* Requests need not be a single commit, but should be a linear sequence of commits (i.e. no merge commits in your PR)
|
||||
* It is desirable, but not necessary, for the tests to pass at each commit. Please see [README.md](./README.md) for instructions to build the test suite.
|
||||
* Have clear commit messages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# GSL: Guidelines Support Library
|
||||
[](https://dev.azure.com/cppstat/GSL/_build/latest?definitionId=1&branchName=master)
|
||||
[](https://dev.azure.com/cppstat/GSL/_build/latest?definitionId=1&branchName=main)
|
||||
|
||||
The Guidelines Support Library (GSL) contains functions and types that are suggested for use by the
|
||||
[C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines) maintained by the [Standard C++ Foundation](https://isocpp.org).
|
||||
@@ -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_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
|
||||
zstring | ☑ | An alias to `basic_zstring` with a char type of char
|
||||
czstring | ☑ | An alias to `basic_zstring` with a char type of const char
|
||||
wzstring | ☑ | An alias to `basic_zstring` with a char type of wchar_t
|
||||
cwzstring | ☑ | An alias to `basic_zstring` with a char type of const wchar_t
|
||||
u16zstring | ☑ | An alias to `basic_zstring` with a char type of char16_t
|
||||
cu16zstring | ☑ | An alias to `basic_zstring` with a char type of const char16_t
|
||||
u32zstring | ☑ | An alias to `basic_zstring` with a char type of char32_t
|
||||
cu32zstring | ☑ | An alias to `basic_zstring` with a char type of const char32_t
|
||||
zstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of char
|
||||
czstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of const char
|
||||
wzstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of 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 dynamic extent and a char type of 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 dynamic extent and a char type of char32_t
|
||||
cu32zstring | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of const char32_t
|
||||
[**2. Owners**][cg-owners] | |
|
||||
unique_ptr | ☑ | an alias to `std::unique_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
|
||||
|
||||
# Quick Start
|
||||
## Supported Compilers
|
||||
The GSL officially supports the current and previous major release of MSVC, GCC, Clang, and XCode's Apple-Clang.
|
||||
See our latest test results for the most up-to-date list of supported configurations.
|
||||
## Supported Compilers / Toolsets
|
||||
The GSL officially supports the latest and previous major versions of VS with MSVC & LLVM, GCC, Clang, and XCode with Apple-Clang.
|
||||
Within these two major versions, we try to target the latest minor updates / revisions (although this may be affected by
|
||||
delays between a toolchain's release and when it becomes widely available for use).
|
||||
Below is a table showing the versions currently being tested.
|
||||
|
||||
Compiler |Toolset Versions Currently Tested
|
||||
:------- |--:
|
||||
XCode |11.4 & 10.3
|
||||
GCC |9 & 8
|
||||
Clang |11 & 10
|
||||
Visual Studio with MSVC | VS2017 (15.9) & VS2019 (16.4)
|
||||
Visual Studio with LLVM | VS2017 (Clang 9) & VS2019 (Clang 10)
|
||||
XCode | 13.2.1 & 12.5.1
|
||||
GCC | 11[^1] & 10[^2]
|
||||
Clang | 12[^2] & 11[^2]
|
||||
Visual Studio with MSVC | VS2022[^3] & VS2019[^4]
|
||||
Visual Studio with LLVM | VS2022[^3] & VS2019[^4]
|
||||
|
||||
|
||||
[^1]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26).
|
||||
[^2]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26). Should be the version specified [here](https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-Readme.md#language-and-runtime).
|
||||
[^3]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26). Should be the version specified [here](https://github.com/actions/virtual-environments/blob/main/images/win/Windows2022-Readme.md#visual-studio-enterprise-2022).
|
||||
[^4]: Precise version may be found in the [latest CI results](https://dev.azure.com/cppstat/GSL/_build?definitionId=1&branchFilter=26). Should be the version specified [here](https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md#visual-studio-enterprise-2019).
|
||||
|
||||
---
|
||||
If you successfully port GSL to another platform, we would love to hear from you!
|
||||
@@ -178,5 +186,36 @@ The library provides a Config file for CMake, once installed it can be found via
|
||||
Which, when successful, will add library target called `Microsoft.GSL::GSL` which you can use via the usual
|
||||
`target_link_libraries` mechanism.
|
||||
|
||||
### FetchContent
|
||||
|
||||
If you are using cmake version 3.11+ you can use the offical FetchContent module.
|
||||
This allows you to easily incorporate GSL into your project.
|
||||
|
||||
```cmake
|
||||
# NOTE: This example uses cmake version 3.14 (FetchContent_MakeAvailable).
|
||||
# Since it streamlines the FetchContent process
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
# In this example we are picking a specific tag.
|
||||
# You can also pick a specific commit, if you need to.
|
||||
FetchContent_Declare(GSL
|
||||
GIT_REPOSITORY "https://github.com/microsoft/GSL"
|
||||
GIT_TAG "v3.1.0"
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(GSL)
|
||||
|
||||
# Now you can link against the GSL interface library
|
||||
add_executable(foobar)
|
||||
|
||||
# Link against the interface library (IE header only library)
|
||||
target_link_libraries(foobar PRIVATE GSL)
|
||||
```
|
||||
|
||||
## Debugging visualization support
|
||||
For Visual Studio users, the file [GSL.natvis](./GSL.natvis) in the root directory of the repository can be added to your project if you would like more helpful visualization of GSL types in the Visual Studio debugger than would be offered by default.
|
||||
|
||||
If you are using cmake this will be done automatically for you.
|
||||
See 'GSL_VS_ADD_NATIVE_VISUALIZERS'
|
||||
|
||||
-114
@@ -1,114 +0,0 @@
|
||||
shallow_clone: true
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
|
||||
image:
|
||||
- Visual Studio 2017
|
||||
- Visual Studio 2019
|
||||
|
||||
environment:
|
||||
NINJA_TAG: v1.8.2
|
||||
NINJA_SHA512: 9B9CE248240665FCD6404B989F3B3C27ED9682838225E6DC9B67B551774F251E4FF8A207504F941E7C811E7A8BE1945E7BCB94472A335EF15E23A0200A32E6D5
|
||||
NINJA_PATH: C:\Tools\ninja\ninja-%NINJA_TAG%
|
||||
VCVAR2017: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat'
|
||||
VCVAR2019: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat'
|
||||
matrix:
|
||||
- GSL_CXX_STANDARD: 14
|
||||
USE_TOOLSET: MSVC
|
||||
USE_GENERATOR: MSBuild
|
||||
- GSL_CXX_STANDARD: 17
|
||||
USE_TOOLSET: MSVC
|
||||
USE_GENERATOR: MSBuild
|
||||
- GSL_CXX_STANDARD: 14
|
||||
USE_TOOLSET: LLVM
|
||||
USE_GENERATOR: Ninja
|
||||
- GSL_CXX_STANDARD: 17
|
||||
USE_TOOLSET: LLVM
|
||||
USE_GENERATOR: Ninja
|
||||
|
||||
cache:
|
||||
- C:\cmake-3.14.4-win32-x86
|
||||
- C:\Tools\ninja
|
||||
|
||||
install:
|
||||
- ps: |
|
||||
if (![IO.File]::Exists("$env:NINJA_PATH\ninja.exe")) {
|
||||
Start-FileDownload `
|
||||
"https://github.com/ninja-build/ninja/releases/download/$env:NINJA_TAG/ninja-win.zip"
|
||||
$hash = (Get-FileHash ninja-win.zip -Algorithm SHA512).Hash
|
||||
if ($env:NINJA_SHA512 -eq $hash) {
|
||||
7z e -y -bso0 ninja-win.zip -o"$env:NINJA_PATH"
|
||||
} else { Write-Warning "Ninja download hash changed!"; Write-Output "$hash" }
|
||||
}
|
||||
if ([IO.File]::Exists("$env:NINJA_PATH\ninja.exe")) {
|
||||
$env:PATH = "$env:NINJA_PATH;$env:PATH"
|
||||
} else { Write-Warning "Failed to find ninja.exe in expected location." }
|
||||
if ($env:USE_TOOLSET -ne "LLVM") {
|
||||
if (![IO.File]::Exists("C:\cmake-3.14.0-win32-x86\bin\cmake.exe")) {
|
||||
Start-FileDownload 'https://cmake.org/files/v3.14/cmake-3.14.4-win32-x86.zip'
|
||||
7z x -y -bso0 cmake-3.14.4-win32-x86.zip -oC:\
|
||||
}
|
||||
$env:PATH="C:\cmake-3.14.4-win32-x86\bin;$env:PATH"
|
||||
}
|
||||
|
||||
before_build:
|
||||
- ps: |
|
||||
if ("$env:USE_GENERATOR" -eq "Ninja") {
|
||||
$GeneratorFlags = '-k 10'
|
||||
$Architecture = $env:PLATFORM
|
||||
if ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2017") {
|
||||
$env:VCVARSALL = "`"$env:VCVAR2017`" $Architecture"
|
||||
} else {
|
||||
$env:VCVARSALL = "`"$env:VCVAR2019`" $Architecture"
|
||||
}
|
||||
$env:CMakeGenFlags = "-G Ninja -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
|
||||
} else {
|
||||
$GeneratorFlags = '/m /v:minimal'
|
||||
if ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2017") {
|
||||
$Generator = 'Visual Studio 15 2017'
|
||||
} else {
|
||||
$Generator = 'Visual Studio 16 2019'
|
||||
}
|
||||
if ("$env:PLATFORM" -eq "x86") {
|
||||
$Architecture = "Win32"
|
||||
} else {
|
||||
$Architecture = "x64"
|
||||
}
|
||||
if ("$env:USE_TOOLSET" -eq "LLVM") {
|
||||
$env:CMakeGenFlags = "-G `"$Generator`" -A $Architecture -T llvm -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
|
||||
} else {
|
||||
$env:CMakeGenFlags = "-G `"$Generator`" -A $Architecture -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
|
||||
}
|
||||
}
|
||||
if ("$env:USE_TOOLSET" -eq "LLVM") {
|
||||
$env:CC = "clang-cl"
|
||||
$env:CXX = "clang-cl"
|
||||
if ("$env:PLATFORM" -eq "x86") {
|
||||
$env:CFLAGS = "-m32";
|
||||
$env:CXXFLAGS = "-m32";
|
||||
} else {
|
||||
$env:CFLAGS = "-m64";
|
||||
$env:CXXFLAGS = "-m64";
|
||||
}
|
||||
}
|
||||
$env:CMakeBuildFlags = "--config $env:CONFIGURATION -- $GeneratorFlags"
|
||||
- mkdir build
|
||||
- cd build
|
||||
- if %USE_GENERATOR%==Ninja (call %VCVARSALL%)
|
||||
- echo %CMakeGenFlags%
|
||||
- cmake .. %CMakeGenFlags%
|
||||
|
||||
build_script:
|
||||
- echo %CMakeBuildFlags%
|
||||
- cmake --build . %CMakeBuildFlags%
|
||||
|
||||
test_script:
|
||||
- ctest -j2
|
||||
|
||||
deploy: off
|
||||
+37
-39
@@ -1,68 +1,66 @@
|
||||
trigger:
|
||||
- master
|
||||
- main
|
||||
|
||||
pr:
|
||||
autoCancel: true
|
||||
|
||||
# GCC
|
||||
stages:
|
||||
- stage: GCC
|
||||
dependsOn: []
|
||||
variables:
|
||||
- name: CC
|
||||
value: gcc
|
||||
- name: CXX
|
||||
value: g++
|
||||
jobs:
|
||||
- template: ./pipelines/jobs.yml
|
||||
parameters:
|
||||
jobName: 'Validate GCC latest'
|
||||
imageName: ubuntu-20.04
|
||||
- template: ./pipelines/jobs.yml
|
||||
parameters:
|
||||
jobName: 'Validate GCC Previous'
|
||||
imageName: ubuntu-18.04
|
||||
compiler: gcc
|
||||
image: ubuntu-20.04
|
||||
compilerVersions: [ 11, 10 ]
|
||||
setupfile: 'setup_gcc.yml'
|
||||
|
||||
# Clang
|
||||
- stage: Clang
|
||||
dependsOn: []
|
||||
variables:
|
||||
- name: CC
|
||||
value: clang
|
||||
- name: CXX
|
||||
value: clang++
|
||||
jobs:
|
||||
- template: ./pipelines/jobs.yml
|
||||
parameters:
|
||||
jobName: 'Validate Clang latest'
|
||||
imageName: ubuntu-20.04
|
||||
- template: ./pipelines/jobs.yml
|
||||
parameters:
|
||||
jobName: 'Validate Clang Previous'
|
||||
imageName: ubuntu-18.04
|
||||
compiler: clang
|
||||
image: ubuntu-20.04
|
||||
compilerVersions: [ 12, 11 ]
|
||||
setupfile: 'setup_clang.yml'
|
||||
|
||||
# MSVC
|
||||
- stage: MSVC
|
||||
- stage: Xcode
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./pipelines/jobs.yml
|
||||
parameters:
|
||||
jobName: 'Validate MSVC latest'
|
||||
imageName: windows-latest
|
||||
- template: ./pipelines/jobs.yml
|
||||
parameters:
|
||||
jobName: 'Validate MSVC Previous'
|
||||
imageName: vs2017-win2016
|
||||
compiler: 'Xcode'
|
||||
image: macOS-11
|
||||
compilerVersions: [ '12.5.1', '13.2.1' ]
|
||||
setupfile: 'setup_apple.yml'
|
||||
|
||||
# Apple-Clang
|
||||
- stage: Apple_Clang
|
||||
- stage: VS_MSVC
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./pipelines/jobs.yml
|
||||
parameters:
|
||||
jobName: 'Validate Apple-Clang latest'
|
||||
imageName: macos-10.15
|
||||
compiler: 'VS2019 (MSVC)'
|
||||
compilerVersions: [ 'default' ]
|
||||
image: windows-2019
|
||||
- template: ./pipelines/jobs.yml
|
||||
parameters:
|
||||
jobName: 'Validate Apple-Clang Previous'
|
||||
imageName: macos-10.14
|
||||
compiler: 'VS2022 (MSVC)'
|
||||
compilerVersions: [ 'default' ]
|
||||
image: windows-2022
|
||||
|
||||
- stage: VS_LLVM
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./pipelines/jobs.yml
|
||||
parameters:
|
||||
compiler: 'VS2019 (LLVM)'
|
||||
compilerVersions: [ 'default' ]
|
||||
image: windows-2019
|
||||
extraCmakeArgs: '-T ClangCL'
|
||||
- template: ./pipelines/jobs.yml
|
||||
parameters:
|
||||
compiler: 'VS2022 (LLVM)'
|
||||
compilerVersions: [ 'default' ]
|
||||
image: windows-2022
|
||||
extraCmakeArgs: '-T ClangCL'
|
||||
|
||||
@@ -4,10 +4,17 @@
|
||||
# for multiple versions of cmake.
|
||||
#
|
||||
# Any functions/macros should have a gsl_* prefix to avoid problems
|
||||
if (DEFINED guideline_support_library_include_guard)
|
||||
return()
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.10 OR CMAKE_VERSION VERSION_EQUAL 3.10)
|
||||
include_guard()
|
||||
else()
|
||||
if (DEFINED guideline_support_library_include_guard)
|
||||
return()
|
||||
endif()
|
||||
set(guideline_support_library_include_guard ON)
|
||||
endif()
|
||||
set(guideline_support_library_include_guard ON)
|
||||
|
||||
# Necessary for 'write_basic_package_version_file'
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
function(gsl_set_default_cxx_standard min_cxx_standard)
|
||||
set(GSL_CXX_STANDARD "${min_cxx_standard}" CACHE STRING "Use c++ standard")
|
||||
@@ -59,3 +66,51 @@ function(gsl_client_set_cxx_standard min_cxx_standard)
|
||||
# Otherwise pick a reasonable default
|
||||
gsl_set_default_cxx_standard(${min_cxx_standard})
|
||||
endfunction()
|
||||
|
||||
# Adding the GSL.natvis files improves the debugging experience for users of this library.
|
||||
function(gsl_add_native_visualizer_support)
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.7.8)
|
||||
if (MSVC_IDE)
|
||||
option(GSL_VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE)
|
||||
else()
|
||||
set(GSL_VS_ADD_NATIVE_VISUALIZERS FALSE CACHE INTERNAL "Native visualizers are Visual Studio extension" FORCE)
|
||||
endif()
|
||||
|
||||
# add natvis file to the library so it will automatically be loaded into Visual Studio
|
||||
if(GSL_VS_ADD_NATIVE_VISUALIZERS)
|
||||
target_sources(GSL INTERFACE $<BUILD_INTERFACE:${GSL_SOURCE_DIR}/GSL.natvis>)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(gsl_install_logic)
|
||||
install(TARGETS GSL EXPORT Microsoft.GSLConfig)
|
||||
install(
|
||||
DIRECTORY include/gsl
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
# Make library importable by other projects
|
||||
install(EXPORT Microsoft.GSLConfig NAMESPACE Microsoft.GSL:: DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/Microsoft.GSL)
|
||||
export(TARGETS GSL NAMESPACE Microsoft.GSL:: FILE Microsoft.GSLConfig.cmake)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Microsoft.GSLConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/Microsoft.GSL)
|
||||
endfunction()
|
||||
|
||||
# Add find_package() versioning support. The version for
|
||||
# generated Microsoft.GSLConfigVersion.cmake will be used from
|
||||
# last project() command. The version's compatibility is set between all
|
||||
# minor versions (as it was in prev. GSL releases).
|
||||
function(gsl_create_packaging_file)
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.14.0")
|
||||
write_basic_package_version_file(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Microsoft.GSLConfigVersion.cmake
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
else()
|
||||
write_basic_package_version_file(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Microsoft.GSLConfigVersion.cmake
|
||||
COMPATIBILITY SameMajorVersion
|
||||
ARCH_INDEPENDENT
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
# Add include folders to the library and targets that consume it
|
||||
# the SYSTEM keyword suppresses warnings for users of the library
|
||||
#
|
||||
# By adding this directory as an include directory the user gets a
|
||||
# namespace effect.
|
||||
#
|
||||
# IE:
|
||||
# #include <gsl/gsl>
|
||||
if(GSL_STANDALONE_PROJECT)
|
||||
target_include_directories(GSL INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
else()
|
||||
target_include_directories(GSL SYSTEM INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
endif()
|
||||
@@ -22,6 +22,7 @@
|
||||
// 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))
|
||||
#define GSL_KERNEL_MODE
|
||||
|
||||
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
|
||||
#include <intrin.h>
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <gsl/assert> // Ensures/Expects
|
||||
#include <gsl/byte> // byte
|
||||
#include <gsl/pointers> // owner, not_null
|
||||
#include <gsl/multi_span> // multi_span, strided_span...
|
||||
#include <gsl/span> // span
|
||||
#include <gsl/string_span> // zstring, string_span, zstring_builder...
|
||||
#include <gsl/util> // finally()/narrow_cast()...
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#pragma message("This header will soon be removed. Use <gsl/algorithm> instead of <gsl/gsl_algorithm>")
|
||||
#pragma message( \
|
||||
"This header will soon be removed. Use <gsl/algorithm> instead of <gsl/gsl_algorithm>")
|
||||
#include <gsl/algorithm>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+25
-3
@@ -26,17 +26,22 @@ struct narrowing_error : public std::exception
|
||||
};
|
||||
|
||||
// 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
|
||||
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
|
||||
// clang-format on
|
||||
constexpr T narrow(U u) noexcept(false)
|
||||
{
|
||||
constexpr const bool is_different_signedness =
|
||||
(std::is_signed<T>::value != std::is_signed<U>::value);
|
||||
|
||||
const T t = narrow_cast<T>(u);
|
||||
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 (static_cast<U>(t) != u || (is_different_signedness && ((t < T{}) != (u < U{}))))
|
||||
{
|
||||
@@ -45,5 +50,22 @@ GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recogn
|
||||
|
||||
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);
|
||||
|
||||
if (static_cast<U>(t) != u)
|
||||
{
|
||||
throw narrowing_error{};
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
} // namespace gsl
|
||||
#endif // GSL_NARROW_H
|
||||
|
||||
+17
-2
@@ -32,6 +32,22 @@
|
||||
namespace gsl
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
template <typename T, typename = void>
|
||||
struct is_comparable_to_nullptr : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
};
|
||||
} // namespace details
|
||||
|
||||
//
|
||||
// GSL.owner: ownership pointers
|
||||
//
|
||||
@@ -68,8 +84,7 @@ template <class T>
|
||||
class not_null
|
||||
{
|
||||
public:
|
||||
static_assert(std::is_convertible<decltype(std::declval<T>() != nullptr), bool>::value,
|
||||
"T cannot be compared to nullptr.");
|
||||
static_assert(details::is_comparable_to_nullptr<T>::value, "T cannot be compared to nullptr.");
|
||||
|
||||
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||
constexpr not_null(U&& u) : ptr_(std::forward<U>(u))
|
||||
|
||||
+5
-10
@@ -21,10 +21,11 @@
|
||||
#include <gsl/byte> // for byte
|
||||
#include <gsl/util> // for narrow_cast
|
||||
|
||||
#include <array> // for array
|
||||
#include <cstddef> // for ptrdiff_t, size_t, nullptr_t
|
||||
#include <iterator> // for reverse_iterator, distance, random_access_...
|
||||
#include <type_traits> // for enable_if_t, declval, is_convertible, inte...
|
||||
#include <array> // for array
|
||||
#include <cstddef> // for ptrdiff_t, size_t, nullptr_t
|
||||
#include <gsl/span_ext> // for span specialization of gsl::at and other span-related extensions
|
||||
#include <iterator> // for reverse_iterator, distance, random_access_...
|
||||
#include <type_traits> // for enable_if_t, declval, is_convertible, inte...
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#pragma warning(push)
|
||||
@@ -60,12 +61,6 @@
|
||||
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
|
||||
namespace details
|
||||
{
|
||||
|
||||
+19
-4
@@ -27,16 +27,29 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <gsl/span> // for span
|
||||
#include <gsl/util> // for narrow_cast, narrow
|
||||
#include <gsl/assert> // GSL_KERNEL_MODE
|
||||
#include <gsl/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>
|
||||
|
||||
#ifndef GSL_KERNEL_MODE
|
||||
#include <algorithm> // for lexicographical_compare
|
||||
#endif // GSL_KERNEL_MODE
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
|
||||
// [span.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;
|
||||
|
||||
// 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
|
||||
template <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent>
|
||||
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);
|
||||
}
|
||||
|
||||
#endif // GSL_KERNEL_MODE
|
||||
|
||||
//
|
||||
// make_span() - Utility functions for creating spans
|
||||
//
|
||||
|
||||
+8
-16
@@ -59,29 +59,21 @@ namespace gsl
|
||||
template <typename CharT, std::size_t Extent = dynamic_extent>
|
||||
using basic_zstring = CharT*;
|
||||
|
||||
template <std::size_t Extent = dynamic_extent>
|
||||
using czstring = basic_zstring<const char, Extent>;
|
||||
using czstring = basic_zstring<const char, dynamic_extent>;
|
||||
|
||||
template <std::size_t Extent = dynamic_extent>
|
||||
using cwzstring = basic_zstring<const wchar_t, Extent>;
|
||||
using cwzstring = basic_zstring<const wchar_t, dynamic_extent>;
|
||||
|
||||
template <std::size_t Extent = dynamic_extent>
|
||||
using cu16zstring = basic_zstring<const char16_t, Extent>;
|
||||
using cu16zstring = basic_zstring<const char16_t, dynamic_extent>;
|
||||
|
||||
template <std::size_t Extent = dynamic_extent>
|
||||
using cu32zstring = basic_zstring<const char32_t, Extent>;
|
||||
using cu32zstring = basic_zstring<const char32_t, dynamic_extent>;
|
||||
|
||||
template <std::size_t Extent = dynamic_extent>
|
||||
using zstring = basic_zstring<char, Extent>;
|
||||
using zstring = basic_zstring<char, dynamic_extent>;
|
||||
|
||||
template <std::size_t Extent = dynamic_extent>
|
||||
using wzstring = basic_zstring<wchar_t, Extent>;
|
||||
using wzstring = basic_zstring<wchar_t, dynamic_extent>;
|
||||
|
||||
template <std::size_t Extent = dynamic_extent>
|
||||
using u16zstring = basic_zstring<char16_t, Extent>;
|
||||
using u16zstring = basic_zstring<char16_t, dynamic_extent>;
|
||||
|
||||
template <std::size_t Extent = dynamic_extent>
|
||||
using u32zstring = basic_zstring<char32_t, Extent>;
|
||||
using u32zstring = basic_zstring<char32_t, dynamic_extent>;
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
+21
-6
@@ -25,6 +25,13 @@
|
||||
#include <type_traits> // for is_signed, integral_constant
|
||||
#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__)
|
||||
|
||||
#pragma warning(push)
|
||||
@@ -92,8 +99,8 @@ finally(F&& f) noexcept
|
||||
template <class T, class U>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
constexpr T narrow_cast(U&& u) noexcept
|
||||
// clang-format on
|
||||
constexpr T narrow_cast(U&& u) noexcept
|
||||
{
|
||||
return static_cast<T>(std::forward<U>(u));
|
||||
}
|
||||
@@ -105,7 +112,7 @@ template <class T, std::size_t N>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.4) // 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)
|
||||
{
|
||||
Expects(i >= 0 && i < narrow_cast<index>(N));
|
||||
@@ -116,7 +123,7 @@ template <class Cont>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.4) // 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()])
|
||||
{
|
||||
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
|
||||
@@ -127,13 +134,21 @@ GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
template <class T>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
constexpr T at(const std::initializer_list<T> cont, const index i)
|
||||
// clang-format on
|
||||
constexpr T at(const std::initializer_list<T> cont, const index i)
|
||||
{
|
||||
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
|
||||
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
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
|
||||
+40
-23
@@ -1,26 +1,43 @@
|
||||
parameters:
|
||||
jobName: ''
|
||||
imageName: ''
|
||||
CXXVersions: [ 14, 17, 20 ]
|
||||
buildTypes: [ 'Debug', 'Release' ]
|
||||
image: ''
|
||||
|
||||
compiler: ''
|
||||
compilerVersions: ["default"] # if default value, simply uses whatever version is on the machine.
|
||||
# the text of this default value doesn't actually matter.
|
||||
setupfile: ''
|
||||
extraCmakeArgs: ''
|
||||
|
||||
jobs:
|
||||
- job:
|
||||
displayName: ${{ parameters.imageName }}
|
||||
pool:
|
||||
vmImage: ${{ parameters.imageName }}
|
||||
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
|
||||
steps:
|
||||
- template: ./steps.yml
|
||||
- ${{ each compilerVersion in parameters.compilerVersions }}:
|
||||
- ${{ each CXXVersion in parameters.CXXVersions }}:
|
||||
- ${{ each buildType in parameters.buildTypes }}:
|
||||
- job:
|
||||
displayName: ${{ format('{0} {1} C++{2} {3}', parameters.compiler, compilerVersion, CXXVersion, buildType) }}
|
||||
pool:
|
||||
vmImage: ${{ parameters.image }}
|
||||
continueOnError: false
|
||||
|
||||
steps:
|
||||
- ${{ if not(eq(parameters.setupfile, '')) }}:
|
||||
- template: ${{ parameters.setupfile }}
|
||||
parameters:
|
||||
version: ${{ compilerVersion }}
|
||||
|
||||
- task: CMake@1
|
||||
name: Configure
|
||||
inputs:
|
||||
workingDirectory: build
|
||||
cmakeArgs: '-DGSL_CXX_STANDARD=${{ CXXVersion }} -DCMAKE_BUILD_TYPE=${{ buildType }} -DCI_TESTING:BOOL=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -Werror=dev ${{ parameters.extraCmakeArgs }} .. '
|
||||
|
||||
- task: CMake@1
|
||||
name: Build
|
||||
inputs:
|
||||
workingDirectory: build
|
||||
cmakeArgs: '--build . '
|
||||
|
||||
- script: ctest . --output-on-failure --no-compress-output
|
||||
name: CTest
|
||||
workingDirectory: build
|
||||
failOnStderr: true
|
||||
|
||||
@@ -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
|
||||
@@ -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 }}
|
||||
@@ -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) .. '
|
||||
|
||||
- task: CMake@1
|
||||
name: Build
|
||||
inputs:
|
||||
workingDirectory: build
|
||||
cmakeArgs: '--build . '
|
||||
|
||||
- script: ctest . --output-on-failure --no-compress-output
|
||||
name: CTest
|
||||
workingDirectory: build
|
||||
failOnStderr: true
|
||||
|
||||
+53
-49
@@ -1,13 +1,27 @@
|
||||
cmake_minimum_required(VERSION 3.0.2)
|
||||
|
||||
project(GSLTests CXX)
|
||||
enable_testing() # again, for support standalone testing
|
||||
|
||||
include(FindPkgConfig)
|
||||
include(ExternalProject)
|
||||
|
||||
# will make visual studio generated project group files
|
||||
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)
|
||||
add_compile_definitions(GTEST_HAS_DEATH_TEST=1 IOS_PROCESS_DELAY_WORKAROUND=1)
|
||||
endif()
|
||||
|
||||
pkg_search_module(GTestMain gtest_main)
|
||||
if (NOT GTestMain_FOUND)
|
||||
# No pre-installed GTest is available, try to download it using Git.
|
||||
find_package(Git REQUIRED QUIET)
|
||||
|
||||
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||
@@ -37,7 +51,14 @@ if (NOT GTestMain_FOUND)
|
||||
)
|
||||
endif()
|
||||
|
||||
if (MSVC AND (GSL_CXX_STANDARD EQUAL 17))
|
||||
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
# CMake has been started independently in this directory with tests. Do
|
||||
# import the globally installed Guidelines Support Library and test it
|
||||
# instead of the current version from the include/ folder.
|
||||
find_package(Microsoft.GSL REQUIRED)
|
||||
endif()
|
||||
|
||||
if (MSVC AND (GSL_CXX_STANDARD GREATER_EQUAL 17))
|
||||
set(GSL_CPLUSPLUS_OPT -Zc:__cplusplus -permissive-)
|
||||
endif()
|
||||
|
||||
@@ -118,6 +139,11 @@ else()
|
||||
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,4.99>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
|
||||
$<$<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>:
|
||||
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,9.1>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,10>>:
|
||||
@@ -147,39 +173,27 @@ target_include_directories(gsl_tests_config SYSTEM INTERFACE
|
||||
googletest/googletest/include
|
||||
)
|
||||
|
||||
set_property(TARGET PROPERTY FOLDER "GSL_tests")
|
||||
|
||||
function(add_gsl_test name)
|
||||
add_executable(${name} ${name}.cpp)
|
||||
target_link_libraries(${name}
|
||||
GSL
|
||||
gsl_tests_config
|
||||
${GTestMain_LIBRARIES}
|
||||
)
|
||||
add_test(
|
||||
${name}
|
||||
${name}
|
||||
)
|
||||
# group all tests under GSL_tests
|
||||
set_property(TARGET ${name} PROPERTY FOLDER "GSL_tests")
|
||||
endfunction()
|
||||
|
||||
add_gsl_test(span_tests)
|
||||
add_gsl_test(span_ext_tests)
|
||||
add_gsl_test(span_compatibility_tests)
|
||||
add_gsl_test(multi_span_tests)
|
||||
add_gsl_test(strided_span_tests)
|
||||
add_gsl_test(string_span_tests)
|
||||
add_gsl_test(at_tests)
|
||||
add_gsl_test(bounds_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)
|
||||
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
|
||||
)
|
||||
|
||||
target_link_libraries(gsl_tests
|
||||
Microsoft.GSL::GSL
|
||||
gsl_tests_config
|
||||
${GTestMain_LIBRARIES}
|
||||
)
|
||||
add_test(gsl_tests gsl_tests)
|
||||
|
||||
# No exception tests
|
||||
|
||||
@@ -254,19 +268,9 @@ else()
|
||||
)
|
||||
endif(MSVC)
|
||||
|
||||
function(add_gsl_test_noexcept name)
|
||||
add_executable(${name} ${name}.cpp)
|
||||
target_link_libraries(${name}
|
||||
GSL
|
||||
gsl_tests_config_noexcept
|
||||
${GTestMain_LIBRARIES}
|
||||
)
|
||||
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)
|
||||
add_executable(gsl_noexcept_tests no_exception_ensure_tests.cpp)
|
||||
target_link_libraries(gsl_noexcept_tests
|
||||
Microsoft.GSL::GSL
|
||||
gsl_tests_config_noexcept
|
||||
)
|
||||
add_test(gsl_noexcept_tests gsl_noexcept_tests)
|
||||
|
||||
@@ -4,7 +4,7 @@ project(googletest-download NONE)
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e
|
||||
GIT_TAG 1b18723e874b256c1e39378c6774a90701d70f7a
|
||||
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
|
||||
CONFIGURE_COMMAND ""
|
||||
|
||||
+12
-15
@@ -14,23 +14,19 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <array> // for array
|
||||
#include <cstddef> // for size_t
|
||||
#include <gsl/algorithm> // for copy
|
||||
#include <gsl/span> // for span
|
||||
#include <array> // for array
|
||||
#include <cstddef> // for size_t
|
||||
#include <gsl/span> // for span
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
}
|
||||
#include "deathTestCommon.h"
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
|
||||
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, 10> dst{};
|
||||
|
||||
const span<int> src_span(src);
|
||||
const span<int, 10> dst_span(dst);
|
||||
const gsl::span<int> src_span(src);
|
||||
const gsl::span<int, 10> dst_span(dst);
|
||||
|
||||
copy(src_span, dst_span);
|
||||
copy(src_span, dst_span.subspan(src_span.size()));
|
||||
@@ -204,10 +200,11 @@ TEST(algorithm_tests, incompatible_type)
|
||||
|
||||
TEST(algorithm_tests, small_destination_span)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. small_destination_span";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
std::array<int, 12> src{1, 2, 3, 4};
|
||||
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, 4> dst_span_static(dst);
|
||||
|
||||
EXPECT_DEATH(copy(src_span_dyn, dst_span_dyn), deathstring);
|
||||
EXPECT_DEATH(copy(src_span_dyn, dst_span_static), deathstring);
|
||||
EXPECT_DEATH(copy(src_span_static, dst_span_dyn), deathstring);
|
||||
EXPECT_DEATH(copy(src_span_dyn, dst_span_dyn), expected);
|
||||
EXPECT_DEATH(copy(src_span_dyn, dst_span_static), expected);
|
||||
EXPECT_DEATH(copy(src_span_static, dst_span_dyn), expected);
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
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 <gtest/gtest.h>
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
|
||||
int f(int i)
|
||||
{
|
||||
@@ -39,23 +39,22 @@ int g(int i)
|
||||
|
||||
TEST(assertion_tests, expects)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. expects";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
EXPECT_TRUE(f(2) == 2);
|
||||
EXPECT_DEATH(f(10), deathstring);
|
||||
EXPECT_DEATH(f(10), GetExpectedDeathString(terminateHandler));
|
||||
}
|
||||
|
||||
|
||||
TEST(assertion_tests, ensures)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. ensures";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
EXPECT_TRUE(g(2) == 3);
|
||||
EXPECT_DEATH(g(9), deathstring);
|
||||
EXPECT_DEATH(g(9), GetExpectedDeathString(terminateHandler));
|
||||
}
|
||||
|
||||
+66
-29
@@ -22,31 +22,33 @@
|
||||
#include <cstddef> // for size_t
|
||||
#include <initializer_list> // for initializer_list
|
||||
#include <vector> // for vector
|
||||
#if defined(__cplusplus) && __cplusplus >= 202002L
|
||||
#include <span>
|
||||
#endif // __cplusplus >= 202002L
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
}
|
||||
#include "deathTestCommon.h"
|
||||
|
||||
TEST(at_tests, static_array)
|
||||
{
|
||||
int a[4] = {1, 2, 3, 4};
|
||||
const int(&c_a)[4] = a;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
EXPECT_TRUE(&gsl::at(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::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, -1), expected);
|
||||
EXPECT_DEATH(gsl::at(a, 4), expected);
|
||||
EXPECT_DEATH(gsl::at(c_a, -1), expected);
|
||||
EXPECT_DEATH(gsl::at(c_a, 4), expected);
|
||||
}
|
||||
|
||||
TEST(at_tests, std_array)
|
||||
@@ -54,20 +56,22 @@ TEST(at_tests, std_array)
|
||||
std::array<int, 4> a = {1, 2, 3, 4};
|
||||
const std::array<int, 4>& c_a = a;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int i = 0; i < 4; ++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)]);
|
||||
}
|
||||
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. std_array";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, -1), expected);
|
||||
EXPECT_DEATH(gsl::at(a, 4), expected);
|
||||
EXPECT_DEATH(gsl::at(c_a, -1), expected);
|
||||
EXPECT_DEATH(gsl::at(c_a, 4), expected);
|
||||
}
|
||||
|
||||
TEST(at_tests, std_vector)
|
||||
@@ -75,42 +79,74 @@ TEST(at_tests, std_vector)
|
||||
std::vector<int> a = {1, 2, 3, 4};
|
||||
const std::vector<int>& c_a = a;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int i = 0; i < 4; ++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)]);
|
||||
}
|
||||
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. std_vector";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, -1), expected);
|
||||
EXPECT_DEATH(gsl::at(a, 4), expected);
|
||||
EXPECT_DEATH(gsl::at(c_a, -1), expected);
|
||||
EXPECT_DEATH(gsl::at(c_a, 4), expected);
|
||||
}
|
||||
|
||||
TEST(at_tests, InitializerList)
|
||||
{
|
||||
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({1, 2, 3, 4}, i) == i + 1);
|
||||
}
|
||||
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. InitializerList";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
EXPECT_DEATH(gsl::at(a, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, -1), deathstring);
|
||||
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, 4), deathstring);
|
||||
EXPECT_DEATH(gsl::at(a, -1), expected);
|
||||
EXPECT_DEATH(gsl::at(a, 4), expected);
|
||||
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, -1), expected);
|
||||
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
|
||||
static constexpr bool test_constexpr()
|
||||
{
|
||||
@@ -119,7 +155,8 @@ static constexpr bool test_constexpr()
|
||||
std::array<int, 4> a2 = {1, 2, 3, 4};
|
||||
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(c_a1, i) != &a1[i]) return false;
|
||||
// requires C++17:
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/multi_span> // for static_bounds, static_bounds_dynamic_range_t
|
||||
|
||||
#include <cstddef> // for ptrdiff_t, size_t
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
void use(std::ptrdiff_t&) {}
|
||||
}
|
||||
|
||||
TEST(bounds_tests, basic_bounds)
|
||||
{
|
||||
for (auto point : static_bounds<dynamic_range, 3, 4>{2}) {
|
||||
for (decltype(point)::size_type j = 0;
|
||||
j < static_cast<decltype(point)::size_type>(decltype(point)::rank); j++)
|
||||
{
|
||||
use(j);
|
||||
use(point[static_cast<std::size_t>(j)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(bounds_tests, bounds_basic)
|
||||
{
|
||||
static_bounds<3, 4, 5> b;
|
||||
const auto a = b.slice();
|
||||
(void) a;
|
||||
static_bounds<4, dynamic_range, 2> x{4};
|
||||
x.slice().slice();
|
||||
}
|
||||
|
||||
TEST(bounds_tests, arrayview_iterator)
|
||||
{
|
||||
static_bounds<4, dynamic_range, 2> bounds{3};
|
||||
|
||||
const auto itr = bounds.begin();
|
||||
(void) itr;
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
multi_span<int, 4, dynamic_range, 2> av(nullptr, bounds);
|
||||
|
||||
auto itr2 = av.cbegin();
|
||||
|
||||
for (auto& v : av) {
|
||||
v = 4;
|
||||
}
|
||||
fill(av.begin(), av.end(), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(bounds_tests, bounds_convertible)
|
||||
{
|
||||
static_bounds<7, 4, 2> b1;
|
||||
static_bounds<7, dynamic_range, 2> b2 = b1;
|
||||
(void) b2;
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
static_bounds<7, dynamic_range, 1> b4 = b2;
|
||||
#endif
|
||||
|
||||
static_bounds<dynamic_range, dynamic_range, dynamic_range> b3 = b1;
|
||||
static_bounds<7, 4, 2> b4 = b3;
|
||||
(void) b4;
|
||||
|
||||
static_bounds<dynamic_range> b5;
|
||||
static_bounds<34> b6;
|
||||
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. bounds_convertible";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
b5 = static_bounds<20>();
|
||||
EXPECT_DEATH(b6 = b5, ".*");
|
||||
b5 = static_bounds<34>();
|
||||
b6 = b5;
|
||||
|
||||
EXPECT_TRUE(b5 == b6);
|
||||
EXPECT_TRUE(b5.size() == b6.size());
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
@@ -37,7 +37,9 @@ TEST(byte_tests, construction)
|
||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 4);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(es.49)
|
||||
// clang-format on
|
||||
{
|
||||
const byte b = byte(12);
|
||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
|
||||
@@ -55,7 +57,7 @@ TEST(byte_tests, construction)
|
||||
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
{
|
||||
const byte b { 14 };
|
||||
const byte b{14};
|
||||
EXPECT_TRUE(static_cast<unsigned char>(b) == 14);
|
||||
}
|
||||
#endif
|
||||
@@ -122,7 +124,7 @@ TEST(byte_tests, aliasing)
|
||||
EXPECT_TRUE(res == i);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,8 +14,11 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <gsl/span> // for span
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
int operator_subscript_no_throw() noexcept
|
||||
{
|
||||
@@ -42,6 +45,10 @@ void setup_termination_handler() 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();
|
||||
operator_subscript_no_throw();
|
||||
return -1;
|
||||
|
||||
+46
-26
@@ -25,13 +25,9 @@
|
||||
#include <string> // for basic_string, operator==, string, operator<<
|
||||
#include <typeinfo> // for type_info
|
||||
|
||||
#include "deathTestCommon.h"
|
||||
using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
} //namespace
|
||||
|
||||
struct MyBase
|
||||
{
|
||||
};
|
||||
@@ -64,7 +60,9 @@ struct CustomPtr
|
||||
template <typename T, typename U>
|
||||
std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
return reinterpret_cast<const void*>(lhs.p_) == reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -72,7 +70,9 @@ std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
return reinterpret_cast<const void*>(lhs.p_) != reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -80,7 +80,9 @@ std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
return reinterpret_cast<const void*>(lhs.p_) < reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -88,7 +90,9 @@ std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
return reinterpret_cast<const void*>(lhs.p_) > reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -96,7 +100,9 @@ std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
return reinterpret_cast<const void*>(lhs.p_) <= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -104,7 +110,9 @@ std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator>=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
return reinterpret_cast<const void*>(lhs.p_) >= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -118,12 +126,19 @@ struct NonCopyableNonMovable
|
||||
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; }
|
||||
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; }
|
||||
|
||||
int* return_pointer() { return nullptr; }
|
||||
} // namespace
|
||||
|
||||
TEST(notnull_tests, TestNotNullConstructors)
|
||||
{
|
||||
@@ -142,10 +157,12 @@ TEST(notnull_tests, TestNotNullConstructors)
|
||||
#endif
|
||||
}
|
||||
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. TestNotNullConstructors";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
{
|
||||
// from shared pointer
|
||||
int i = 12;
|
||||
@@ -157,7 +174,7 @@ TEST(notnull_tests, TestNotNullConstructors)
|
||||
std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
|
||||
|
||||
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
|
||||
|
||||
EXPECT_DEATH(helper(return_pointer()), deathstring);
|
||||
EXPECT_DEATH(helper_const(return_pointer()), deathstring);
|
||||
EXPECT_DEATH(helper(return_pointer()), expected);
|
||||
EXPECT_DEATH(helper_const(return_pointer()), expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,17 +292,18 @@ TEST(notnull_tests, TestNotNullCasting)
|
||||
|
||||
TEST(notnull_tests, TestNotNullAssignment)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. TestNotNullAssignmentd";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
int i = 12;
|
||||
not_null<int*> p(&i);
|
||||
EXPECT_TRUE(helper(p));
|
||||
|
||||
int* q = nullptr;
|
||||
EXPECT_DEATH(p = not_null<int*>(q), deathstring);
|
||||
EXPECT_DEATH(p = not_null<int*>(q), expected);
|
||||
}
|
||||
|
||||
TEST(notnull_tests, TestNotNullRawPointerComparison)
|
||||
@@ -434,17 +452,18 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
|
||||
EXPECT_TRUE(*x == 42);
|
||||
}
|
||||
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. TestNotNullConstructorTypeDeduction";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
{
|
||||
auto workaround_macro = []() {
|
||||
int* p1 = nullptr;
|
||||
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 not_null x{p1};
|
||||
};
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
EXPECT_DEATH(workaround_macro(), expected);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
|
||||
EXPECT_DEATH(helper(not_null{p}), deathstring);
|
||||
EXPECT_DEATH(helper_const(not_null{p}), deathstring);
|
||||
EXPECT_DEATH(helper(not_null{p}), expected);
|
||||
EXPECT_DEATH(helper_const(not_null{p}), expected);
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
@@ -495,10 +514,11 @@ TEST(notnull_tests, TestMakeNotNull)
|
||||
EXPECT_TRUE(*x == 42);
|
||||
}
|
||||
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. TestMakeNotNull";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
{
|
||||
const auto workaround_macro = []() {
|
||||
@@ -506,7 +526,7 @@ TEST(notnull_tests, TestMakeNotNull)
|
||||
const auto x = make_not_null(p1);
|
||||
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);
|
||||
EXPECT_TRUE(*x == 42);
|
||||
};
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
EXPECT_DEATH(workaround_macro(), expected);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
|
||||
EXPECT_DEATH(helper(make_not_null(p)), deathstring);
|
||||
EXPECT_DEATH(helper_const(make_not_null(p)), deathstring);
|
||||
EXPECT_DEATH(helper(make_not_null(p)), expected);
|
||||
EXPECT_DEATH(helper_const(make_not_null(p)), expected);
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
EXPECT_DEATH(make_not_null(nullptr), deathstring);
|
||||
EXPECT_DEATH(helper(make_not_null(nullptr)), deathstring);
|
||||
EXPECT_DEATH(helper_const(make_not_null(nullptr)), deathstring);
|
||||
EXPECT_DEATH(make_not_null(nullptr), expected);
|
||||
EXPECT_DEATH(helper(make_not_null(nullptr)), expected);
|
||||
EXPECT_DEATH(helper_const(make_not_null(nullptr)), expected);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(f .23) // NO-FORMAT: attribute
|
||||
void f(int* i) { *i += 1; }
|
||||
|
||||
TEST(owner_tests, basic_test)
|
||||
@@ -34,10 +34,10 @@ TEST(owner_tests, basic_test)
|
||||
|
||||
TEST(owner_tests, check_pointer_constraint)
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
owner<int> integerTest = 10;
|
||||
owner<std::shared_ptr<int>> sharedPtrTest(new int(10));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/byte> // for byte
|
||||
#include <gsl/span> // for span, span_iterator, operator==, operator!=
|
||||
#include <gsl/span> // for span, span_iterator, operator==, operator!=
|
||||
|
||||
#include <array> // for array
|
||||
#include <cstddef> // for ptrdiff_t
|
||||
@@ -55,14 +55,14 @@ void ArrayConvertibilityCheck()
|
||||
EXPECT_TRUE(sp_const_nullptr_1.data() == stl_nullptr.data());
|
||||
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.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");
|
||||
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, "
|
||||
"3>>::value");
|
||||
}
|
||||
|
||||
+238
-237
@@ -16,27 +16,26 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/span> // for span and span_ext
|
||||
#include <gsl/util> // for narrow_cast, at
|
||||
#include <gsl/span_ext> // for operator==, operator!=, make_span
|
||||
|
||||
#include <array> // for array
|
||||
#include <iostream> // for cerr
|
||||
#include <vector> // for vector
|
||||
#include <array> // for array
|
||||
#include <iostream> // for cerr
|
||||
#include <vector> // for vector
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
} // namespace
|
||||
#include "deathTestCommon.h"
|
||||
|
||||
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::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
int arr[4] = {1, 2, 3, 4};
|
||||
|
||||
{
|
||||
@@ -49,7 +48,7 @@ TEST(span_ext_test, make_span_from_pointer_length_constructor)
|
||||
|
||||
{
|
||||
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.data() == nullptr);
|
||||
}
|
||||
@@ -57,7 +56,7 @@ TEST(span_ext_test, make_span_from_pointer_length_constructor)
|
||||
{
|
||||
int* p = nullptr;
|
||||
auto workaround_macro = [=]() { make_span(p, 2); };
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
EXPECT_DEATH(workaround_macro(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,273 +87,275 @@ TEST(span_ext_test, make_span_from_pointer_pointer_construction)
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_array_constructor)
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
|
||||
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
|
||||
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
|
||||
{
|
||||
const auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == 5);
|
||||
EXPECT_TRUE(s.data() == std::addressof(arr[0]));
|
||||
}
|
||||
{
|
||||
const auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == 5);
|
||||
EXPECT_TRUE(s.data() == std::addressof(arr[0]));
|
||||
}
|
||||
|
||||
{
|
||||
const auto s = make_span(std::addressof(arr2d[0]), 1);
|
||||
EXPECT_TRUE(s.size() == 1);
|
||||
EXPECT_TRUE(s.data() == std::addressof(arr2d[0]));
|
||||
}
|
||||
{
|
||||
const auto s = make_span(std::addressof(arr2d[0]), 1);
|
||||
EXPECT_TRUE(s.size() == 1);
|
||||
EXPECT_TRUE(s.data() == std::addressof(arr2d[0]));
|
||||
}
|
||||
|
||||
{
|
||||
const auto s = make_span(std::addressof(arr3d[0]), 1);
|
||||
EXPECT_TRUE(s.size() == 1);
|
||||
EXPECT_TRUE(s.data() == std::addressof(arr3d[0]));
|
||||
}
|
||||
}
|
||||
{
|
||||
const auto s = make_span(std::addressof(arr3d[0]), 1);
|
||||
EXPECT_TRUE(s.size() == 1);
|
||||
EXPECT_TRUE(s.data() == std::addressof(arr3d[0]));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_dynamic_array_constructor)
|
||||
{
|
||||
double(*arr)[3][4] = new double[100][3][4];
|
||||
TEST(span_ext_test, make_span_from_dynamic_array_constructor)
|
||||
{
|
||||
double(*arr)[3][4] = new double[100][3][4];
|
||||
|
||||
{
|
||||
auto s = make_span(&arr[0][0][0], 10);
|
||||
EXPECT_TRUE(s.size() == 10);
|
||||
EXPECT_TRUE(s.data() == &arr[0][0][0]);
|
||||
}
|
||||
{
|
||||
auto s = make_span(&arr[0][0][0], 10);
|
||||
EXPECT_TRUE(s.size() == 10);
|
||||
EXPECT_TRUE(s.data() == &arr[0][0][0]);
|
||||
}
|
||||
|
||||
delete[] arr;
|
||||
}
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_std_array_constructor)
|
||||
{
|
||||
std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
TEST(span_ext_test, make_span_from_std_array_constructor)
|
||||
{
|
||||
std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
|
||||
{
|
||||
auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == arr.size());
|
||||
EXPECT_TRUE(s.data() == arr.data());
|
||||
}
|
||||
{
|
||||
auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == arr.size());
|
||||
EXPECT_TRUE(s.data() == arr.data());
|
||||
}
|
||||
|
||||
// This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590
|
||||
{
|
||||
span<int> s1 = make_span(arr);
|
||||
// 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
|
||||
{
|
||||
gsl::span<int> s1 = make_span(arr);
|
||||
|
||||
static span<int> s2;
|
||||
s2 = s1;
|
||||
static gsl::span<int> s2;
|
||||
s2 = s1;
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
|
||||
__GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
|
||||
// Known to be broken in gcc 6.4 and 6.5 with optimizations
|
||||
// Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116
|
||||
EXPECT_TRUE(s1.size() == 4);
|
||||
EXPECT_TRUE(s2.size() == 0);
|
||||
#else
|
||||
EXPECT_TRUE(s1.size() == s2.size());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
|
||||
__GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
|
||||
// Known to be broken in gcc 6.4 and 6.5 with optimizations
|
||||
// Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116
|
||||
EXPECT_TRUE(s1.size() == 4);
|
||||
EXPECT_TRUE(s2.size() == 0);
|
||||
#else
|
||||
EXPECT_TRUE(s1.size() == s2.size());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_const_std_array_constructor)
|
||||
{
|
||||
const std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
TEST(span_ext_test, make_span_from_const_std_array_constructor)
|
||||
{
|
||||
const std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
|
||||
{
|
||||
auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == arr.size());
|
||||
EXPECT_TRUE(s.data() == arr.data());
|
||||
}
|
||||
}
|
||||
{
|
||||
auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == arr.size());
|
||||
EXPECT_TRUE(s.data() == arr.data());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_std_array_const_constructor)
|
||||
{
|
||||
std::array<const int, 4> arr = {1, 2, 3, 4};
|
||||
TEST(span_ext_test, make_span_from_std_array_const_constructor)
|
||||
{
|
||||
std::array<const int, 4> arr = {1, 2, 3, 4};
|
||||
|
||||
{
|
||||
auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == arr.size());
|
||||
EXPECT_TRUE(s.data() == arr.data());
|
||||
}
|
||||
}
|
||||
{
|
||||
auto s = make_span(arr);
|
||||
EXPECT_TRUE(s.size() == arr.size());
|
||||
EXPECT_TRUE(s.data() == arr.data());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_ext_test, make_span_from_container_constructor)
|
||||
{
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
const std::vector<int> cv = v;
|
||||
TEST(span_ext_test, make_span_from_container_constructor)
|
||||
{
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
const std::vector<int> cv = v;
|
||||
|
||||
{
|
||||
auto s = make_span(v);
|
||||
EXPECT_TRUE(s.size() == v.size());
|
||||
EXPECT_TRUE(s.data() == v.data());
|
||||
{
|
||||
auto s = make_span(v);
|
||||
EXPECT_TRUE(s.size() == v.size());
|
||||
EXPECT_TRUE(s.data() == v.data());
|
||||
|
||||
auto cs = make_span(cv);
|
||||
EXPECT_TRUE(cs.size() == cv.size());
|
||||
EXPECT_TRUE(cs.data() == cv.data());
|
||||
}
|
||||
}
|
||||
auto cs = make_span(cv);
|
||||
EXPECT_TRUE(cs.size() == cv.size());
|
||||
EXPECT_TRUE(cs.data() == cv.data());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(span_test, interop_with_gsl_at)
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
span<int> s{arr};
|
||||
EXPECT_TRUE(at(s, 0) == 1);
|
||||
EXPECT_TRUE(at(s, 1) == 2);
|
||||
}
|
||||
TEST(span_test, interop_with_gsl_at)
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
gsl::span<int> s{arr};
|
||||
EXPECT_TRUE(at(s, 0) == 1);
|
||||
EXPECT_TRUE(at(s, 1) == 2);
|
||||
}
|
||||
|
||||
TEST(span_ext_test, iterator_free_functions)
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
span<int> s{a};
|
||||
TEST(span_ext_test, iterator_free_functions)
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
gsl::span<int> s{a};
|
||||
|
||||
EXPECT_TRUE((std::is_same<decltype(s.begin()), decltype(begin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(s.end()), decltype(end(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(s.begin()), decltype(begin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(s.end()), decltype(end(s))>::value));
|
||||
|
||||
EXPECT_TRUE((std::is_same<decltype(std::cbegin(s)), decltype(cbegin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(std::cend(s)), decltype(cend(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(std::cbegin(s)), decltype(cbegin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(std::cend(s)), decltype(cend(s))>::value));
|
||||
|
||||
EXPECT_TRUE((std::is_same<decltype(s.rbegin()), decltype(rbegin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(s.rend()), decltype(rend(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(s.rbegin()), decltype(rbegin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(s.rend()), decltype(rend(s))>::value));
|
||||
|
||||
EXPECT_TRUE((std::is_same<decltype(std::crbegin(s)), decltype(crbegin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(std::crend(s)), decltype(crend(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(std::crbegin(s)), decltype(crbegin(s))>::value));
|
||||
EXPECT_TRUE((std::is_same<decltype(std::crend(s)), decltype(crend(s))>::value));
|
||||
|
||||
EXPECT_TRUE(s.begin() == begin(s));
|
||||
EXPECT_TRUE(s.end() == end(s));
|
||||
EXPECT_TRUE(s.begin() == begin(s));
|
||||
EXPECT_TRUE(s.end() == end(s));
|
||||
|
||||
EXPECT_TRUE(s.rbegin() == rbegin(s));
|
||||
EXPECT_TRUE(s.rend() == rend(s));
|
||||
EXPECT_TRUE(s.rbegin() == rbegin(s));
|
||||
EXPECT_TRUE(s.rend() == rend(s));
|
||||
|
||||
EXPECT_TRUE(s.begin() == cbegin(s));
|
||||
EXPECT_TRUE(s.end() == cend(s));
|
||||
EXPECT_TRUE(s.begin() == cbegin(s));
|
||||
EXPECT_TRUE(s.end() == cend(s));
|
||||
|
||||
EXPECT_TRUE(s.rbegin() == crbegin(s));
|
||||
EXPECT_TRUE(s.rend() == crend(s));
|
||||
}
|
||||
EXPECT_TRUE(s.rbegin() == crbegin(s));
|
||||
EXPECT_TRUE(s.rend() == crend(s));
|
||||
}
|
||||
|
||||
TEST(span_ext_test, ssize_free_function)
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
span<int> s{a};
|
||||
TEST(span_ext_test, ssize_free_function)
|
||||
{
|
||||
int a[] = {1, 2, 3, 4};
|
||||
gsl::span<int> s{a};
|
||||
|
||||
EXPECT_FALSE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value));
|
||||
EXPECT_TRUE(s.size() == static_cast<std::size_t>(ssize(s)));
|
||||
}
|
||||
EXPECT_FALSE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value));
|
||||
EXPECT_TRUE(s.size() == static_cast<std::size_t>(ssize(s)));
|
||||
}
|
||||
|
||||
TEST(span_ext_test, comparison_operators)
|
||||
{
|
||||
{
|
||||
span<int> s1;
|
||||
span<int> s2;
|
||||
EXPECT_TRUE(s1 == s2);
|
||||
EXPECT_FALSE(s1 != s2);
|
||||
EXPECT_FALSE(s1 < s2);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s1 >= s2);
|
||||
EXPECT_TRUE(s2 == s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_TRUE(s2 <= s1);
|
||||
EXPECT_FALSE(s2 > s1);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
}
|
||||
#ifndef GSL_KERNEL_MODE
|
||||
TEST(span_ext_test, comparison_operators)
|
||||
{
|
||||
{
|
||||
gsl::span<int> s1;
|
||||
gsl::span<int> s2;
|
||||
EXPECT_TRUE(s1 == s2);
|
||||
EXPECT_FALSE(s1 != s2);
|
||||
EXPECT_FALSE(s1 < s2);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s1 >= s2);
|
||||
EXPECT_TRUE(s2 == s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_TRUE(s2 <= s1);
|
||||
EXPECT_FALSE(s2 > s1);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
}
|
||||
|
||||
{
|
||||
int arr[] = {2, 1};
|
||||
span<int> s1 = arr;
|
||||
span<int> s2 = arr;
|
||||
{
|
||||
int arr[] = {2, 1};
|
||||
gsl::span<int> s1 = arr;
|
||||
gsl::span<int> s2 = arr;
|
||||
|
||||
EXPECT_TRUE(s1 == s2);
|
||||
EXPECT_FALSE(s1 != s2);
|
||||
EXPECT_FALSE(s1 < s2);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s1 >= s2);
|
||||
EXPECT_TRUE(s2 == s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s2 <= s1);
|
||||
EXPECT_FALSE(s2 > s1);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
}
|
||||
EXPECT_TRUE(s1 == s2);
|
||||
EXPECT_FALSE(s1 != s2);
|
||||
EXPECT_FALSE(s1 < s2);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s1 >= s2);
|
||||
EXPECT_TRUE(s2 == s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s2 <= s1);
|
||||
EXPECT_FALSE(s2 > s1);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
}
|
||||
|
||||
{
|
||||
int arr[] = {2, 1}; // bigger
|
||||
{
|
||||
int arr[] = {2, 1}; // bigger
|
||||
|
||||
span<int> s1;
|
||||
span<int> s2 = arr;
|
||||
gsl::span<int> s1;
|
||||
gsl::span<int> s2 = arr;
|
||||
|
||||
EXPECT_TRUE(s1 != s2);
|
||||
EXPECT_TRUE(s2 != s1);
|
||||
EXPECT_FALSE(s1 == s2);
|
||||
EXPECT_FALSE(s2 == s1);
|
||||
EXPECT_TRUE(s1 < s2);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s2 <= s1);
|
||||
EXPECT_TRUE(s2 > s1);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
EXPECT_FALSE(s1 >= s2);
|
||||
}
|
||||
EXPECT_TRUE(s1 != s2);
|
||||
EXPECT_TRUE(s2 != s1);
|
||||
EXPECT_FALSE(s1 == s2);
|
||||
EXPECT_FALSE(s2 == s1);
|
||||
EXPECT_TRUE(s1 < s2);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s2 <= s1);
|
||||
EXPECT_TRUE(s2 > s1);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
EXPECT_FALSE(s1 >= s2);
|
||||
}
|
||||
|
||||
{
|
||||
int arr1[] = {1, 2};
|
||||
int arr2[] = {1, 2};
|
||||
span<int> s1 = arr1;
|
||||
span<int> s2 = arr2;
|
||||
{
|
||||
int arr1[] = {1, 2};
|
||||
int arr2[] = {1, 2};
|
||||
gsl::span<int> s1 = arr1;
|
||||
gsl::span<int> s2 = arr2;
|
||||
|
||||
EXPECT_TRUE(s1 == s2);
|
||||
EXPECT_FALSE(s1 != s2);
|
||||
EXPECT_FALSE(s1 < s2);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s1 >= s2);
|
||||
EXPECT_TRUE(s2 == s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s2 <= s1);
|
||||
EXPECT_FALSE(s2 > s1);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
}
|
||||
EXPECT_TRUE(s1 == s2);
|
||||
EXPECT_FALSE(s1 != s2);
|
||||
EXPECT_FALSE(s1 < s2);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s1 >= s2);
|
||||
EXPECT_TRUE(s2 == s1);
|
||||
EXPECT_FALSE(s2 != s1);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s2 <= s1);
|
||||
EXPECT_FALSE(s2 > s1);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
}
|
||||
|
||||
{
|
||||
int arr[] = {1, 2, 3};
|
||||
{
|
||||
int arr[] = {1, 2, 3};
|
||||
|
||||
span<int> s1 = {&arr[0], 2}; // shorter
|
||||
span<int> s2 = arr; // longer
|
||||
gsl::span<int> s1 = {&arr[0], 2}; // shorter
|
||||
gsl::span<int> s2 = arr; // longer
|
||||
|
||||
EXPECT_TRUE(s1 != s2);
|
||||
EXPECT_TRUE(s2 != s1);
|
||||
EXPECT_FALSE(s1 == s2);
|
||||
EXPECT_FALSE(s2 == s1);
|
||||
EXPECT_TRUE(s1 < s2);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s2 <= s1);
|
||||
EXPECT_TRUE(s2 > s1);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
EXPECT_FALSE(s1 >= s2);
|
||||
}
|
||||
EXPECT_TRUE(s1 != s2);
|
||||
EXPECT_TRUE(s2 != s1);
|
||||
EXPECT_FALSE(s1 == s2);
|
||||
EXPECT_FALSE(s2 == s1);
|
||||
EXPECT_TRUE(s1 < s2);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s2 <= s1);
|
||||
EXPECT_TRUE(s2 > s1);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
EXPECT_FALSE(s1 >= s2);
|
||||
}
|
||||
|
||||
{
|
||||
int arr1[] = {1, 2}; // smaller
|
||||
int arr2[] = {2, 1}; // bigger
|
||||
{
|
||||
int arr1[] = {1, 2}; // smaller
|
||||
int arr2[] = {2, 1}; // bigger
|
||||
|
||||
span<int> s1 = arr1;
|
||||
span<int> s2 = arr2;
|
||||
gsl::span<int> s1 = arr1;
|
||||
gsl::span<int> s2 = arr2;
|
||||
|
||||
EXPECT_TRUE(s1 != s2);
|
||||
EXPECT_TRUE(s2 != s1);
|
||||
EXPECT_FALSE(s1 == s2);
|
||||
EXPECT_FALSE(s2 == s1);
|
||||
EXPECT_TRUE(s1 < s2);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s2 <= s1);
|
||||
EXPECT_TRUE(s2 > s1);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
EXPECT_FALSE(s1 >= s2);
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(s1 != s2);
|
||||
EXPECT_TRUE(s2 != s1);
|
||||
EXPECT_FALSE(s1 == s2);
|
||||
EXPECT_FALSE(s2 == s1);
|
||||
EXPECT_TRUE(s1 < s2);
|
||||
EXPECT_FALSE(s2 < s1);
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_FALSE(s2 <= s1);
|
||||
EXPECT_TRUE(s2 > s1);
|
||||
EXPECT_FALSE(s1 > s2);
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
EXPECT_FALSE(s1 >= s2);
|
||||
}
|
||||
}
|
||||
#endif // GSL_KERNEL_MODE
|
||||
|
||||
+815
-794
File diff suppressed because it is too large
Load Diff
@@ -14,30 +14,40 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
#include "deathTestCommon.h"
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
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; }
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
bool helper_const(not_null<const int*> p) { return *p == 12; }
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
bool strict_helper(strict_not_null<int*> p) { return *p == 12; }
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
bool strict_helper_const(strict_not_null<const int*> p) { return *p == 12; }
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
int* return_pointer() { return nullptr; }
|
||||
const int* return_pointer_const() { return nullptr; }
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
TEST(strict_notnull_tests, TestStrictNotNull)
|
||||
{
|
||||
@@ -123,17 +133,14 @@ TEST(strict_notnull_tests, TestStrictNotNull)
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201703L)
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
}
|
||||
|
||||
TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. TestStrictNotNullConstructorTypeDeduction";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
{
|
||||
int i = 42;
|
||||
@@ -161,7 +168,7 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
|
||||
int* p1 = nullptr;
|
||||
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 strict_not_null x{p1};
|
||||
};
|
||||
EXPECT_DEATH(workaround_macro(), deathstring);
|
||||
EXPECT_DEATH(workaround_macro(), expected);
|
||||
}
|
||||
|
||||
{
|
||||
int* p = nullptr;
|
||||
|
||||
EXPECT_DEATH(helper(strict_not_null{p}), deathstring);
|
||||
EXPECT_DEATH(helper_const(strict_not_null{p}), deathstring);
|
||||
EXPECT_DEATH(helper(strict_not_null{p}), expected);
|
||||
EXPECT_DEATH(helper_const(strict_not_null{p}), expected);
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
|
||||
@@ -1,790 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <gsl/byte> // for byte
|
||||
#include <gsl/util> // for narrow_cast
|
||||
#include <gsl/multi_span> // for strided_span, index, multi_span, strided_...
|
||||
|
||||
#include <iostream> // for size_t
|
||||
#include <iterator> // for begin, end
|
||||
#include <numeric> // for iota
|
||||
#include <type_traits> // for integral_constant<>::value, is_convertible
|
||||
#include <vector> // for vector
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
|
||||
struct BaseClass
|
||||
{
|
||||
};
|
||||
struct DerivedClass : BaseClass
|
||||
{
|
||||
};
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
void iterate_every_other_element(multi_span<int, dynamic_range> av)
|
||||
{
|
||||
// pick every other element
|
||||
|
||||
auto length = av.size() / 2;
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1800
|
||||
auto bounds = strided_bounds<1>({length}, {2});
|
||||
#else
|
||||
auto bounds = strided_bounds<1>(multi_span_index<1>{length}, multi_span_index<1>{2});
|
||||
#endif
|
||||
strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);
|
||||
|
||||
EXPECT_TRUE(strided.size() == length);
|
||||
EXPECT_TRUE(strided.bounds().index_bounds()[0] == length);
|
||||
for (auto i = 0; i < strided.size(); ++i) {
|
||||
EXPECT_TRUE(strided[i] == av[2 * i + 1]);
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
for (auto num : strided) {
|
||||
EXPECT_TRUE(num == av[2 * idx + 1]);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute // TODO: does not work
|
||||
void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
|
||||
{
|
||||
const int expected[6] = {2, 3, 10, 11, 18, 19};
|
||||
auto section = av.section({0, 1, 0}, {3, 1, 2});
|
||||
|
||||
for (auto i = 0; i < section.extent<0>(); ++i) {
|
||||
for (auto j = 0; j < section.extent<1>(); ++j)
|
||||
for (auto k = 0; k < section.extent<2>(); ++k) {
|
||||
auto idx = multi_span_index<3>{i, j, k}; // avoid braces in the EXPECT_TRUE macro
|
||||
EXPECT_TRUE(section[idx] == expected[2 * i + 2 * j + k]);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i = 0; i < section.extent<0>(); ++i) {
|
||||
for (auto j = 0; j < section.extent<1>(); ++j)
|
||||
for (auto k = 0; k < section.extent<2>(); ++k)
|
||||
EXPECT_TRUE(section[i][j][k] == expected[2 * i + 2 * j + k]);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (const auto num : section) {
|
||||
EXPECT_TRUE(num == expected[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, span_section_test)
|
||||
{
|
||||
int a[30][4][5];
|
||||
|
||||
const auto av = as_multi_span(a);
|
||||
const auto sub = av.section({15, 0, 0}, gsl::multi_span_index<3>{2, 2, 2});
|
||||
const auto subsub = sub.section({1, 0, 0}, gsl::multi_span_index<3>{1, 1, 1});
|
||||
(void) subsub;
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, span_section)
|
||||
{
|
||||
std::vector<int> data(5 * 10);
|
||||
std::iota(begin(data), end(data), 0);
|
||||
const multi_span<int, 5, 10> av = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
|
||||
|
||||
const strided_span<int, 2> av_section_1 = av.section({1, 2}, {3, 4});
|
||||
EXPECT_TRUE(!av_section_1.empty());
|
||||
EXPECT_TRUE((av_section_1[{0, 0}] == 12));
|
||||
EXPECT_TRUE((av_section_1[{0, 1}] == 13));
|
||||
EXPECT_TRUE((av_section_1[{1, 0}] == 22));
|
||||
EXPECT_TRUE((av_section_1[{2, 3}] == 35));
|
||||
|
||||
const strided_span<int, 2> av_section_2 = av_section_1.section({1, 2}, {2, 2});
|
||||
EXPECT_TRUE(!av_section_2.empty());
|
||||
EXPECT_TRUE((av_section_2[{0, 0}] == 24));
|
||||
EXPECT_TRUE((av_section_2[{0, 1}] == 25));
|
||||
EXPECT_TRUE((av_section_2[{1, 0}] == 34));
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, strided_span_constructors)
|
||||
{
|
||||
// EXPECT_TRUE stride constructor
|
||||
{
|
||||
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
const int carr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
|
||||
strided_span<int, 1> sav1{arr, {{9}, {1}}}; // T -> T
|
||||
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{9});
|
||||
EXPECT_TRUE(sav1.bounds().stride() == 1);
|
||||
EXPECT_TRUE(sav1[0] == 1);
|
||||
EXPECT_TRUE(sav1[8] == 9);
|
||||
|
||||
strided_span<const int, 1> sav2{carr, {{4}, {2}}}; // const T -> const T
|
||||
EXPECT_TRUE(sav2.bounds().index_bounds() == multi_span_index<1>{4});
|
||||
EXPECT_TRUE(sav2.bounds().strides() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav2[0] == 1);
|
||||
EXPECT_TRUE(sav2[3] == 7);
|
||||
|
||||
strided_span<int, 2> sav3{arr, {{2, 2}, {6, 2}}}; // T -> const T
|
||||
EXPECT_TRUE((sav3.bounds().index_bounds() == multi_span_index<2>{2, 2}));
|
||||
EXPECT_TRUE((sav3.bounds().strides() == multi_span_index<2>{6, 2}));
|
||||
EXPECT_TRUE((sav3[{0, 0}]) == 1);
|
||||
EXPECT_TRUE((sav3[{0, 1}]) == 3);
|
||||
EXPECT_TRUE((sav3[{1, 0}]) == 7);
|
||||
}
|
||||
|
||||
// EXPECT_TRUE multi_span constructor
|
||||
{
|
||||
int arr[] = {1, 2};
|
||||
|
||||
// From non-cv-qualified source
|
||||
{
|
||||
const multi_span<int> src = arr;
|
||||
|
||||
strided_span<int, 1> sav{src, {2, 1}};
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav[1] == 2);
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1800
|
||||
// strided_span<const int, 1> sav_c{ {src}, {2, 1} };
|
||||
strided_span<const int, 1> sav_c{multi_span<const int>{src},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#else
|
||||
strided_span<const int, 1> sav_c{multi_span<const int>{src},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#endif
|
||||
EXPECT_TRUE(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_c.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_c[1] == 2);
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1800
|
||||
strided_span<volatile int, 1> sav_v{src, {2, 1}};
|
||||
#else
|
||||
strided_span<volatile int, 1> sav_v{multi_span<volatile int>{src},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#endif
|
||||
EXPECT_TRUE(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_v.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_v[1] == 2);
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1800
|
||||
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
|
||||
#else
|
||||
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#endif
|
||||
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_cv[1] == 2);
|
||||
}
|
||||
|
||||
// From const-qualified source
|
||||
{
|
||||
const multi_span<const int> src{arr};
|
||||
|
||||
strided_span<const int, 1> sav_c{src, {2, 1}};
|
||||
EXPECT_TRUE(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_c.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_c[1] == 2);
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1800
|
||||
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
|
||||
#else
|
||||
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#endif
|
||||
|
||||
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_cv[1] == 2);
|
||||
}
|
||||
|
||||
// From volatile-qualified source
|
||||
{
|
||||
const multi_span<volatile int> src{arr};
|
||||
|
||||
strided_span<volatile int, 1> sav_v{src, {2, 1}};
|
||||
EXPECT_TRUE(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_v.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_v[1] == 2);
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1800
|
||||
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
|
||||
#else
|
||||
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
|
||||
strided_bounds<1>{2, 1}};
|
||||
#endif
|
||||
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_cv[1] == 2);
|
||||
}
|
||||
|
||||
// From cv-qualified source
|
||||
{
|
||||
const multi_span<const volatile int> src{arr};
|
||||
|
||||
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
|
||||
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav_cv[1] == 2);
|
||||
}
|
||||
}
|
||||
|
||||
// EXPECT_TRUE const-casting constructor
|
||||
{
|
||||
int arr[2] = {4, 5};
|
||||
|
||||
const multi_span<int, 2> av(arr, 2);
|
||||
multi_span<const int, 2> av2{av};
|
||||
EXPECT_TRUE(av2[1] == 5);
|
||||
|
||||
static_assert(
|
||||
std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value,
|
||||
"ctor is not implicit!");
|
||||
|
||||
const strided_span<int, 1> src{arr, {2, 1}};
|
||||
strided_span<const int, 1> sav{src};
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav.bounds().stride() == 1);
|
||||
EXPECT_TRUE(sav[1] == 5);
|
||||
|
||||
static_assert(
|
||||
std::is_convertible<const strided_span<int, 1>, strided_span<const int, 1>>::value,
|
||||
"ctor is not implicit!");
|
||||
}
|
||||
|
||||
// EXPECT_TRUE copy constructor
|
||||
{
|
||||
int arr1[2] = {3, 4};
|
||||
const strided_span<int, 1> src1{arr1, {2, 1}};
|
||||
strided_span<int, 1> sav1{src1};
|
||||
|
||||
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav1.bounds().stride() == 1);
|
||||
EXPECT_TRUE(sav1[0] == 3);
|
||||
|
||||
int arr2[6] = {1, 2, 3, 4, 5, 6};
|
||||
const strided_span<const int, 2> src2{arr2, {{3, 2}, {2, 1}}};
|
||||
strided_span<const int, 2> sav2{src2};
|
||||
EXPECT_TRUE((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
|
||||
EXPECT_TRUE((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
|
||||
EXPECT_TRUE((sav2[{0, 0}]) == 1);
|
||||
EXPECT_TRUE((sav2[{2, 0}]) == 5);
|
||||
}
|
||||
|
||||
// EXPECT_TRUE const-casting assignment operator
|
||||
{
|
||||
int arr1[2] = {1, 2};
|
||||
int arr2[6] = {3, 4, 5, 6, 7, 8};
|
||||
|
||||
const strided_span<int, 1> src{arr1, {{2}, {1}}};
|
||||
strided_span<const int, 1> sav{arr2, {{3}, {2}}};
|
||||
strided_span<const int, 1>& sav_ref = (sav = src);
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav[0] == 1);
|
||||
EXPECT_TRUE(&sav_ref == &sav);
|
||||
}
|
||||
|
||||
// EXPECT_TRUE copy assignment operator
|
||||
{
|
||||
int arr1[2] = {3, 4};
|
||||
int arr1b[1] = {0};
|
||||
const strided_span<int, 1> src1{arr1, {2, 1}};
|
||||
strided_span<int, 1> sav1{arr1b, {1, 1}};
|
||||
strided_span<int, 1>& sav1_ref = (sav1 = src1);
|
||||
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav1.bounds().strides() == multi_span_index<1>{1});
|
||||
EXPECT_TRUE(sav1[0] == 3);
|
||||
EXPECT_TRUE(&sav1_ref == &sav1);
|
||||
|
||||
const int arr2[6] = {1, 2, 3, 4, 5, 6};
|
||||
const int arr2b[1] = {0};
|
||||
const strided_span<const int, 2> src2{arr2, {{3, 2}, {2, 1}}};
|
||||
strided_span<const int, 2> sav2{arr2b, {{1, 1}, {1, 1}}};
|
||||
strided_span<const int, 2>& sav2_ref = (sav2 = src2);
|
||||
EXPECT_TRUE((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
|
||||
EXPECT_TRUE((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
|
||||
EXPECT_TRUE((sav2[{0, 0}] == 1));
|
||||
EXPECT_TRUE((sav2[{2, 0}] == 5));
|
||||
EXPECT_TRUE(&sav2_ref == &sav2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, strided_span_slice)
|
||||
{
|
||||
std::vector<int> data(5 * 10);
|
||||
std::iota(begin(data), end(data), 0);
|
||||
const multi_span<int, 5, 10> src =
|
||||
as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
|
||||
|
||||
const strided_span<int, 2> sav{src, {{5, 10}, {10, 1}}};
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
const strided_span<const int, 2> csav{{src}, {{5, 10}, {10, 1}}};
|
||||
#endif
|
||||
const strided_span<const int, 2> csav{multi_span<const int, 5, 10>{src},
|
||||
{{5, 10}, {10, 1}}};
|
||||
|
||||
strided_span<int, 1> sav_sl = sav[2];
|
||||
EXPECT_TRUE(sav_sl[0] == 20);
|
||||
EXPECT_TRUE(sav_sl[9] == 29);
|
||||
|
||||
strided_span<const int, 1> csav_sl = sav[3];
|
||||
EXPECT_TRUE(csav_sl[0] == 30);
|
||||
EXPECT_TRUE(csav_sl[9] == 39);
|
||||
|
||||
EXPECT_TRUE(sav[4][0] == 40);
|
||||
EXPECT_TRUE(sav[4][9] == 49);
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, strided_span_column_major)
|
||||
{
|
||||
// strided_span may be used to accommodate more peculiar
|
||||
// use cases, such as column-major multidimensional array
|
||||
// (aka. "FORTRAN" layout).
|
||||
|
||||
int cm_array[3 * 5] = {1, 4, 7, 10, 13, 2, 5, 8, 11, 14, 3, 6, 9, 12, 15};
|
||||
strided_span<int, 2> cm_sav{cm_array, {{5, 3}, {1, 5}}};
|
||||
|
||||
// Accessing elements
|
||||
EXPECT_TRUE((cm_sav[{0, 0}] == 1));
|
||||
EXPECT_TRUE((cm_sav[{0, 1}] == 2));
|
||||
EXPECT_TRUE((cm_sav[{1, 0}] == 4));
|
||||
EXPECT_TRUE((cm_sav[{4, 2}] == 15));
|
||||
|
||||
// Slice
|
||||
strided_span<int, 1> cm_sl = cm_sav[3];
|
||||
|
||||
EXPECT_TRUE(cm_sl[0] == 10);
|
||||
EXPECT_TRUE(cm_sl[1] == 11);
|
||||
EXPECT_TRUE(cm_sl[2] == 12);
|
||||
|
||||
// Section
|
||||
strided_span<int, 2> cm_sec = cm_sav.section({2, 1}, {3, 2});
|
||||
|
||||
EXPECT_TRUE((cm_sec.bounds().index_bounds() == multi_span_index<2>{3, 2}));
|
||||
EXPECT_TRUE((cm_sec[{0, 0}] == 8));
|
||||
EXPECT_TRUE((cm_sec[{0, 1}] == 9));
|
||||
EXPECT_TRUE((cm_sec[{1, 0}] == 11));
|
||||
EXPECT_TRUE((cm_sec[{2, 1}] == 15));
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, strided_span_bounds)
|
||||
{
|
||||
int arr[] = {0, 1, 2, 3};
|
||||
multi_span<int> av(arr);
|
||||
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. strided_span_bounds";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
{
|
||||
// incorrect sections
|
||||
|
||||
EXPECT_DEATH(av.section(0, 0)[0], deathstring);
|
||||
EXPECT_DEATH(av.section(1, 0)[0], deathstring);
|
||||
EXPECT_DEATH(av.section(1, 1)[1], deathstring);
|
||||
|
||||
EXPECT_DEATH(av.section(2, 5), deathstring);
|
||||
EXPECT_DEATH(av.section(5, 2), deathstring);
|
||||
EXPECT_DEATH(av.section(5, 0), deathstring);
|
||||
EXPECT_DEATH(av.section(0, 5), deathstring);
|
||||
EXPECT_DEATH(av.section(5, 5), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// zero stride
|
||||
strided_span<int, 1> sav{av, {{4}, {}}};
|
||||
EXPECT_TRUE(sav[0] == 0);
|
||||
EXPECT_TRUE(sav[3] == 0);
|
||||
EXPECT_DEATH(sav[4], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// zero extent
|
||||
strided_span<int, 1> sav{av, {{}, {1}}};
|
||||
EXPECT_DEATH(sav[0], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// zero extent and stride
|
||||
strided_span<int, 1> sav{av, {{}, {}}};
|
||||
EXPECT_DEATH(sav[0], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// strided array ctor with matching strided bounds
|
||||
strided_span<int, 1> sav{arr, {4, 1}};
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{4});
|
||||
EXPECT_TRUE(sav[3] == 3);
|
||||
EXPECT_DEATH(sav[4], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// strided array ctor with smaller strided bounds
|
||||
strided_span<int, 1> sav{arr, {2, 1}};
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav[1] == 1);
|
||||
EXPECT_DEATH(sav[2], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// strided array ctor with fitting irregular bounds
|
||||
strided_span<int, 1> sav{arr, {2, 3}};
|
||||
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
|
||||
EXPECT_TRUE(sav[0] == 0);
|
||||
EXPECT_TRUE(sav[1] == 3);
|
||||
EXPECT_DEATH(sav[2], deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// bounds cross data boundaries - from static arrays
|
||||
EXPECT_DEATH((strided_span<int, 1>{arr, {3, 2}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{arr, {3, 3}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{arr, {4, 5}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{arr, {5, 1}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{arr, {5, 5}}), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// bounds cross data boundaries - from array view
|
||||
EXPECT_DEATH((strided_span<int, 1>{av, {3, 2}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av, {3, 3}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av, {4, 5}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av, {5, 1}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av, {5, 5}}), deathstring);
|
||||
}
|
||||
|
||||
{
|
||||
// bounds cross data boundaries - from dynamic arrays
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {3, 2}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {3, 3}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {4, 5}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {5, 1}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {5, 5}}), deathstring);
|
||||
EXPECT_DEATH((strided_span<int, 1>{av.data(), 2, {2, 2}}), deathstring);
|
||||
}
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
strided_span<int, 1> sav0{av.data(), {3, 2}};
|
||||
strided_span<int, 1> sav1{arr, {1}};
|
||||
strided_span<int, 1> sav2{arr, {1, 1, 1}};
|
||||
strided_span<int, 1> sav3{av, {1}};
|
||||
strided_span<int, 1> sav4{av, {1, 1, 1}};
|
||||
strided_span<int, 2> sav5{av.as_multi_span(dim<2>(), dim<2>()), {1}};
|
||||
strided_span<int, 2> sav6{av.as_multi_span(dim<2>(), dim<2>()), {1, 1, 1}};
|
||||
strided_span<int, 2> sav7{av.as_multi_span(dim<2>(), dim<2>()),
|
||||
{{1, 1}, {1, 1}, {1, 1}}};
|
||||
|
||||
multi_span_index<1> index{0, 1};
|
||||
strided_span<int, 1> sav8{arr, {1, {1, 1}}};
|
||||
strided_span<int, 1> sav9{arr, {{1, 1}, {1, 1}}};
|
||||
strided_span<int, 1> sav10{av, {1, {1, 1}}};
|
||||
strided_span<int, 1> sav11{av, {{1, 1}, {1, 1}}};
|
||||
strided_span<int, 2> sav12{av.as_multi_span(dim<2>(), dim<2>()), {{1}, {1}}};
|
||||
strided_span<int, 2> sav13{av.as_multi_span(dim<2>(), dim<2>()), {{1}, {1, 1, 1}}};
|
||||
strided_span<int, 2> sav14{av.as_multi_span(dim<2>(), dim<2>()), {{1, 1, 1}, {1}}};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, strided_span_type_conversion)
|
||||
{
|
||||
int arr[] = {0, 1, 2, 3};
|
||||
multi_span<int> av(arr);
|
||||
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. strided_span_type_conversion";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
{
|
||||
strided_span<int, 1> sav{av.data(), av.size(), {av.size() / 2, 2}};
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>();
|
||||
#endif
|
||||
}
|
||||
{
|
||||
strided_span<int, 1> sav{av, {av.size() / 2, 2}};
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>();
|
||||
#endif
|
||||
}
|
||||
|
||||
multi_span<const byte, dynamic_range> bytes = as_bytes(av);
|
||||
|
||||
// retype strided array with regular strides - from raw data
|
||||
{
|
||||
strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}};
|
||||
strided_span<const byte, 2> sav2{bytes.data(), bytes.size(), bounds};
|
||||
strided_span<const int, 2> sav3 = sav2.as_strided_span<const int>();
|
||||
EXPECT_TRUE(sav3[0][0] == 0);
|
||||
EXPECT_TRUE(sav3[1][0] == 2);
|
||||
EXPECT_DEATH(sav3[1][1], deathstring);
|
||||
EXPECT_DEATH(sav3[0][1], deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with regular strides - from multi_span
|
||||
{
|
||||
strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}};
|
||||
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||
strided_span<int, 2> sav3 = sav2.as_strided_span<int>();
|
||||
EXPECT_TRUE(sav3[0][0] == 0);
|
||||
EXPECT_TRUE(sav3[1][0] == 2);
|
||||
EXPECT_DEATH(sav3[1][1], deathstring);
|
||||
EXPECT_DEATH(sav3[0][1], deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with not enough elements - last dimension of the array is too small
|
||||
{
|
||||
strided_bounds<2> bounds{{4, 2}, {4, 1}};
|
||||
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with not enough elements - strides are too small
|
||||
{
|
||||
strided_bounds<2> bounds{{4, 2}, {2, 1}};
|
||||
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with not enough elements - last dimension does not divide by the new
|
||||
// typesize
|
||||
{
|
||||
strided_bounds<2> bounds{{2, 6}, {4, 1}};
|
||||
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with not enough elements - strides does not divide by the new
|
||||
// typesize
|
||||
{
|
||||
strided_bounds<2> bounds{{2, 1}, {6, 1}};
|
||||
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with irregular strides - from raw data
|
||||
{
|
||||
strided_bounds<1> bounds{bytes.size() / 2, 2};
|
||||
strided_span<const byte, 1> sav2{bytes.data(), bytes.size(), bounds};
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
|
||||
// retype strided array with irregular strides - from multi_span
|
||||
{
|
||||
strided_bounds<1> bounds{bytes.size() / 2, 2};
|
||||
strided_span<const byte, 1> sav2{bytes, bounds};
|
||||
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, empty_strided_spans)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. empty_strided_spans";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
{
|
||||
multi_span<int, 0> empty_av(nullptr);
|
||||
strided_span<int, 1> empty_sav{empty_av, {0, 1}};
|
||||
|
||||
EXPECT_TRUE(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
|
||||
EXPECT_TRUE(empty_sav.empty());
|
||||
EXPECT_DEATH(empty_sav[0], deathstring);
|
||||
EXPECT_DEATH(empty_sav.begin()[0], deathstring);
|
||||
EXPECT_DEATH(empty_sav.cbegin()[0], deathstring);
|
||||
|
||||
for (const auto& v : empty_sav) {
|
||||
(void) v;
|
||||
EXPECT_TRUE(false);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
strided_span<int, 1> empty_sav{nullptr, 0, {0, 1}};
|
||||
|
||||
EXPECT_TRUE(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
|
||||
EXPECT_DEATH(empty_sav[0], deathstring);
|
||||
EXPECT_DEATH(empty_sav.begin()[0], deathstring);
|
||||
EXPECT_DEATH(empty_sav.cbegin()[0], deathstring);
|
||||
|
||||
for (const auto& v : empty_sav) {
|
||||
(void) v;
|
||||
EXPECT_TRUE(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, strided_span_section_iteration)
|
||||
{
|
||||
int arr[8] = {4, 0, 5, 1, 6, 2, 7, 3};
|
||||
|
||||
// static bounds
|
||||
{
|
||||
multi_span<int, 8> av(arr, 8);
|
||||
iterate_every_other_element(av);
|
||||
}
|
||||
|
||||
// dynamic bounds
|
||||
{
|
||||
multi_span<int, dynamic_range> av(arr, 8);
|
||||
iterate_every_other_element(av);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, dynamic_strided_span_section_iteration)
|
||||
{
|
||||
auto arr = new int[8];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
arr[2 * i] = 4 + i;
|
||||
arr[2 * i + 1] = i;
|
||||
}
|
||||
|
||||
auto av = as_multi_span(arr, 8);
|
||||
iterate_every_other_element(av);
|
||||
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, strided_span_section_iteration_3d)
|
||||
{
|
||||
int arr[3][4][2]{};
|
||||
for (auto i = 0; i < 3; ++i) {
|
||||
for (auto j = 0; j < 4; ++j)
|
||||
for (auto k = 0; k < 2; ++k) arr[i][j][k] = 8 * i + 2 * j + k;
|
||||
}
|
||||
|
||||
{
|
||||
multi_span<int, 3, 4, 2> av = arr;
|
||||
iterate_second_slice(av);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, dynamic_strided_span_section_iteration_3d)
|
||||
{
|
||||
const auto height = 12, width = 2;
|
||||
const auto size = height * width;
|
||||
|
||||
auto arr = new int[static_cast<std::size_t>(size)];
|
||||
for (auto i = 0; i < size; ++i) {
|
||||
arr[i] = i;
|
||||
}
|
||||
|
||||
{
|
||||
auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim<2>());
|
||||
iterate_second_slice(av);
|
||||
}
|
||||
|
||||
{
|
||||
auto av = as_multi_span(as_multi_span(arr, 24), dim(3), dim<4>(), dim<2>());
|
||||
iterate_second_slice(av);
|
||||
}
|
||||
|
||||
{
|
||||
auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim(4), dim<2>());
|
||||
iterate_second_slice(av);
|
||||
}
|
||||
|
||||
{
|
||||
auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim(2));
|
||||
iterate_second_slice(av);
|
||||
}
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
TEST(strided_span_tests, strided_span_conversion)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
std::cerr << "Expected Death. strided_span_conversion";
|
||||
std::abort();
|
||||
});
|
||||
|
||||
// get an multi_span of 'c' values from the list of X's
|
||||
|
||||
struct X
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
};
|
||||
|
||||
X arr[4] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}};
|
||||
|
||||
int s = sizeof(int) / sizeof(byte);
|
||||
auto d2 = 3 * s;
|
||||
auto d1 = narrow_cast<int>(sizeof(int)) * 12 / d2;
|
||||
|
||||
// convert to 4x12 array of bytes
|
||||
auto av = as_multi_span(as_bytes(as_multi_span(&arr[0], 4)), dim(d1), dim(d2));
|
||||
|
||||
EXPECT_TRUE(av.bounds().index_bounds()[0] == 4);
|
||||
EXPECT_TRUE(av.bounds().index_bounds()[1] == 12);
|
||||
|
||||
// get the last 4 columns
|
||||
auto section = av.section({0, 2 * s}, {4, s}); // { { arr[0].c[0], arr[0].c[1], arr[0].c[2],
|
||||
// arr[0].c[3] } , { arr[1].c[0], ... } , ...
|
||||
// }
|
||||
|
||||
// convert to array 4x1 array of integers
|
||||
auto cs = section.as_strided_span<int>(); // { { arr[0].c }, {arr[1].c } , ... }
|
||||
|
||||
EXPECT_TRUE(cs.bounds().index_bounds()[0] == 4);
|
||||
EXPECT_TRUE(cs.bounds().index_bounds()[1] == 1);
|
||||
|
||||
// transpose to 1x4 array
|
||||
strided_bounds<2> reverse_bounds{
|
||||
{cs.bounds().index_bounds()[1], cs.bounds().index_bounds()[0]},
|
||||
{cs.bounds().strides()[1], cs.bounds().strides()[0]}};
|
||||
|
||||
strided_span<int, 2> transposed{cs.data(), cs.bounds().total_size(), reverse_bounds};
|
||||
|
||||
// slice to get a one-dimensional array of c's
|
||||
strided_span<int, 1> result = transposed[0];
|
||||
|
||||
EXPECT_TRUE(result.bounds().index_bounds()[0] == 4);
|
||||
EXPECT_DEATH(result.bounds().index_bounds()[1], deathstring);
|
||||
|
||||
int i = 0;
|
||||
for (auto& num : result) {
|
||||
EXPECT_TRUE(num == arr[i].c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
+36
-28
@@ -16,7 +16,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/assert> // for Expects, fail_fast (ptr only)
|
||||
#include <gsl/assert> // for Expects, fail_fast (ptr only)
|
||||
#include <gsl/pointers> // for owner
|
||||
#include <gsl/span> // for span, dynamic_extent
|
||||
#include <gsl/string_span> // for basic_string_span, operator==, ensure_z
|
||||
@@ -28,13 +28,10 @@
|
||||
#include <type_traits> // for remove_reference<>::type
|
||||
#include <vector> // for vector, allocator
|
||||
|
||||
using namespace std;
|
||||
#include "deathTestCommon.h"
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr char deathstring[] = "Expected Death";
|
||||
}
|
||||
// Generic string functions
|
||||
|
||||
namespace generic
|
||||
@@ -76,8 +73,7 @@ T create()
|
||||
|
||||
template <class T>
|
||||
void use(basic_string_span<T, gsl::dynamic_extent>)
|
||||
{
|
||||
}
|
||||
{}
|
||||
#endif
|
||||
|
||||
czstring_span<> CreateTempName(string_span<> span)
|
||||
@@ -85,7 +81,8 @@ czstring_span<> CreateTempName(string_span<> span)
|
||||
Expects(span.size() > 1);
|
||||
|
||||
std::size_t last = 0;
|
||||
if (span.size() > 4) {
|
||||
if (span.size() > 4)
|
||||
{
|
||||
span[0] = 't';
|
||||
span[1] = 'm';
|
||||
span[2] = 'p';
|
||||
@@ -102,7 +99,8 @@ cwzstring_span<> CreateTempNameW(wstring_span<> span)
|
||||
Expects(span.size() > 1);
|
||||
|
||||
std::size_t last = 0;
|
||||
if (span.size() > 4) {
|
||||
if (span.size() > 4)
|
||||
{
|
||||
span[0] = L't';
|
||||
span[1] = L'm';
|
||||
span[2] = L'p';
|
||||
@@ -119,7 +117,8 @@ cu16zstring_span<> CreateTempNameU16(u16string_span<> span)
|
||||
Expects(span.size() > 1);
|
||||
|
||||
std::size_t last = 0;
|
||||
if (span.size() > 4) {
|
||||
if (span.size() > 4)
|
||||
{
|
||||
span[0] = u't';
|
||||
span[1] = u'm';
|
||||
span[2] = u'p';
|
||||
@@ -136,7 +135,8 @@ cu32zstring_span<> CreateTempNameU32(u32string_span<> span)
|
||||
Expects(span.size() > 1);
|
||||
|
||||
std::size_t last = 0;
|
||||
if (span.size() > 4) {
|
||||
if (span.size() > 4)
|
||||
{
|
||||
span[0] = U't';
|
||||
span[1] = U'm';
|
||||
span[2] = U'p';
|
||||
@@ -950,10 +950,11 @@ TEST(string_span_tests, Conversion)
|
||||
|
||||
TEST(string_span_tests, zstring)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. zstring";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
// create zspan from zero terminated string
|
||||
{
|
||||
@@ -973,7 +974,7 @@ TEST(string_span_tests, zstring)
|
||||
buf[0] = 'a';
|
||||
|
||||
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
|
||||
@@ -981,8 +982,9 @@ TEST(string_span_tests, zstring)
|
||||
char buf[10];
|
||||
|
||||
auto name = CreateTempName({buf, 10});
|
||||
if (!name.empty()) {
|
||||
czstring<> str = name.assume_z();
|
||||
if (!name.empty())
|
||||
{
|
||||
czstring str = name.assume_z();
|
||||
EXPECT_TRUE(generic::strlen(str) == 3);
|
||||
EXPECT_TRUE(*(str + 3) == '\0');
|
||||
}
|
||||
@@ -991,10 +993,11 @@ TEST(string_span_tests, zstring)
|
||||
|
||||
TEST(string_span_tests, wzstring)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. wzstring";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
// create zspan from zero terminated string
|
||||
{
|
||||
@@ -1014,7 +1017,7 @@ TEST(string_span_tests, wzstring)
|
||||
buf[0] = L'a';
|
||||
|
||||
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
|
||||
@@ -1022,8 +1025,9 @@ TEST(string_span_tests, wzstring)
|
||||
wchar_t buf[10];
|
||||
|
||||
const auto name = CreateTempNameW({buf, 10});
|
||||
if (!name.empty()) {
|
||||
cwzstring<> str = name.assume_z();
|
||||
if (!name.empty())
|
||||
{
|
||||
cwzstring str = name.assume_z();
|
||||
EXPECT_TRUE(generic::strnlen(str, 10) == 3);
|
||||
EXPECT_TRUE(*(str + 3) == L'\0');
|
||||
}
|
||||
@@ -1032,10 +1036,11 @@ TEST(string_span_tests, wzstring)
|
||||
|
||||
TEST(string_span_tests, u16zstring)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. u16zstring";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
// create zspan from zero terminated string
|
||||
{
|
||||
@@ -1055,7 +1060,7 @@ TEST(string_span_tests, u16zstring)
|
||||
buf[0] = u'a';
|
||||
|
||||
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
|
||||
@@ -1063,8 +1068,9 @@ TEST(string_span_tests, u16zstring)
|
||||
char16_t buf[10];
|
||||
|
||||
const auto name = CreateTempNameU16({buf, 10});
|
||||
if (!name.empty()) {
|
||||
cu16zstring<> str = name.assume_z();
|
||||
if (!name.empty())
|
||||
{
|
||||
cu16zstring str = name.assume_z();
|
||||
EXPECT_TRUE(generic::strnlen(str, 10) == 3);
|
||||
EXPECT_TRUE(*(str + 3) == L'\0');
|
||||
}
|
||||
@@ -1073,10 +1079,11 @@ TEST(string_span_tests, u16zstring)
|
||||
|
||||
TEST(string_span_tests, u32zstring)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
const auto terminateHandler = std::set_terminate([] {
|
||||
std::cerr << "Expected Death. u31zstring";
|
||||
std::abort();
|
||||
});
|
||||
const auto expected = GetExpectedDeathString(terminateHandler);
|
||||
|
||||
// create zspan from zero terminated string
|
||||
{
|
||||
@@ -1096,7 +1103,7 @@ TEST(string_span_tests, u32zstring)
|
||||
buf[0] = u'a';
|
||||
|
||||
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
|
||||
@@ -1104,8 +1111,9 @@ TEST(string_span_tests, u32zstring)
|
||||
char32_t buf[10];
|
||||
|
||||
const auto name = CreateTempNameU32({buf, 10});
|
||||
if (!name.empty()) {
|
||||
cu32zstring<> str = name.assume_z();
|
||||
if (!name.empty())
|
||||
{
|
||||
cu32zstring str = name.assume_z();
|
||||
EXPECT_TRUE(generic::strnlen(str, 10) == 3);
|
||||
EXPECT_TRUE(*(str + 3) == L'\0');
|
||||
}
|
||||
|
||||
+11
-5
@@ -16,14 +16,15 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/util> // finally, narrow_cast
|
||||
#include <gsl/narrow> // for narrow, narrowing_error
|
||||
#include <algorithm> // for move
|
||||
#include <complex>
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
#include <functional> // for reference_wrapper, _Bind_helper<>::type
|
||||
#include <gsl/narrow> // for narrow, narrowing_error
|
||||
#include <gsl/util> // finally, narrow_cast
|
||||
#include <limits> // for numeric_limits
|
||||
#include <stdint.h> // for uint32_t, int32_t
|
||||
#include <type_traits> // for is_same
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
@@ -32,8 +33,7 @@ namespace
|
||||
void f(int& i) { i += 1; }
|
||||
static int j = 0;
|
||||
void g() { j += 1; }
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(utils_tests, sanity_check_for_gsl_index_typedef)
|
||||
{
|
||||
@@ -123,6 +123,7 @@ TEST(utils_tests, narrow_cast)
|
||||
EXPECT_TRUE(uc == 44);
|
||||
}
|
||||
|
||||
#ifndef GSL_KERNEL_MODE
|
||||
TEST(utils_tests, narrow)
|
||||
{
|
||||
int n = 120;
|
||||
@@ -144,4 +145,9 @@ TEST(utils_tests, narrow)
|
||||
|
||||
n = -42;
|
||||
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);
|
||||
}
|
||||
#endif // GSL_KERNEL_MODE
|
||||
|
||||
Reference in New Issue
Block a user