aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2019-02-06 13:02:38 -0800
committerandroid-build-merger <android-build-merger@google.com>2019-02-06 13:02:38 -0800
commitecd85103911a15415740383b35aa0155dde9cea0 (patch)
tree051e6a6105b6a9e535a4373f30b8e3736310b78e
parent698e6f69e425d8419d04bcea32cc77854f29a867 (diff)
parent74a0cce77f0599a2efb0c6409d420e9ffc171821 (diff)
downloadMicrosoft-GSL-ecd85103911a15415740383b35aa0155dde9cea0.tar.gz
Upgrade Microsoft-GSL to 7d78b743e43ecba06ca47426d03d9d16076dec16
am: 74a0cce77f Change-Id: Ifcdc23f95b943536b5fd6496ddd9111f0e6ff324
-rw-r--r--.travis.yml22
-rw-r--r--CMakeLists.txt22
-rw-r--r--METADATA8
-rw-r--r--README.md11
-rw-r--r--appveyor.yml94
-rw-r--r--include/gsl/gsl_assert26
-rw-r--r--include/gsl/gsl_byte12
-rw-r--r--include/gsl/gsl_util13
-rw-r--r--include/gsl/multi_span74
-rw-r--r--include/gsl/pointers108
-rw-r--r--include/gsl/span42
-rw-r--r--include/gsl/string_span4
-rw-r--r--samples/gsl_transition130
-rw-r--r--tests/CMakeLists.txt94
-rw-r--r--tests/multi_span_tests.cpp2
-rw-r--r--tests/no_exception_ensure_tests.cpp15
-rw-r--r--tests/no_exception_throw_tests.cpp12
-rw-r--r--tests/notnull_tests.cpp126
-rw-r--r--tests/sloppy_notnull_tests.cpp124
-rw-r--r--tests/span_tests.cpp25
-rw-r--r--tests/strict_notnull_tests.cpp193
-rw-r--r--tests/strided_span_tests.cpp12
-rw-r--r--tests/test.cpp3
-rw-r--r--tests/utils_tests.cpp6
24 files changed, 724 insertions, 454 deletions
diff --git a/.travis.yml b/.travis.yml
index d583eb9..f3dbaab 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -163,6 +163,28 @@ matrix:
- env: COMPILER=clang++-6.0 BUILD_TYPE=Release GSL_CXX_STANDARD=17
addons: *clang60
+ # Clang 7.0
+ - env: COMPILER=clang++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
+ addons: &clang70
+ apt:
+ packages:
+ - clang-7
+ - g++-7
+ sources:
+ - ubuntu-toolchain-r-test
+ - llvm-toolchain-trusty-7
+
+
+ - env: COMPILER=clang++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=14
+ addons: *clang70
+
+ # Clang 7.0 c++17
+ - env: COMPILER=clang++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
+ addons: *clang70
+
+ - env: COMPILER=clang++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=17
+ addons: *clang70
+
##########################################################################
# GCC on Linux
##########################################################################
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b0de85d..0348f79 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -51,13 +51,23 @@ target_compile_definitions(GSL INTERFACE
)
# add include folders to the library and targets that consume it
-target_include_directories(GSL INTERFACE
- $<BUILD_INTERFACE:
- ${CMAKE_CURRENT_SOURCE_DIR}/include
- >
-)
+# the SYSTEM keyword suppresses warnings for users of the library
+if(GSL_STANDALONE_PROJECT)
+ target_include_directories(GSL INTERFACE
+ $<BUILD_INTERFACE:
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ >
+ )
+else()
+ target_include_directories(GSL SYSTEM INTERFACE
+ $<BUILD_INTERFACE:
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ >
+ )
+endif()
+
-if ((CMAKE_VERSION GREATER 3.7.9) OR (CMAKE_VERSION EQUAL 3.7.9))
+if (CMAKE_VERSION VERSION_GREATER 3.7.8)
if (MSVC_IDE)
option(VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE)
else()
diff --git a/METADATA b/METADATA
index 15717fb..c1ce0f4 100644
--- a/METADATA
+++ b/METADATA
@@ -5,10 +5,10 @@ third_party {
type: GIT
value: "https://github.com/Microsoft/GSL"
}
- version: "1995e86d1ad70519465374fb4876c6ef7c9f8c61"
+ version: "7d78b743e43ecba06ca47426d03d9d16076dec16"
last_upgrade_date {
- year: 2018
- month: 8
- day: 30
+ year: 2019
+ month: 2
+ day: 1
}
}
diff --git a/README.md b/README.md
index 9fea9ae..183553f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-# GSL: Guideline Support Library [![Build Status](https://travis-ci.org/Microsoft/GSL.svg?branch=master)](https://travis-ci.org/Microsoft/GSL) [![Build status](https://ci.appveyor.com/api/projects/status/github/Microsoft/GSL?svg=true)](https://ci.appveyor.com/project/neilmacintosh/GSL)
+# GSL: Guidelines Support Library [![Build Status](https://travis-ci.org/Microsoft/GSL.svg?branch=master)](https://travis-ci.org/Microsoft/GSL) [![Build status](https://ci.appveyor.com/api/projects/status/github/Microsoft/GSL?svg=true)](https://ci.appveyor.com/project/neilmacintosh/GSL)
-The Guideline Support Library (GSL) contains functions and types that are suggested for use by the
+The Guidelines Support Library (GSL) contains functions and types that are suggested for use by the
[C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines) maintained by the [Standard C++ Foundation](https://isocpp.org).
This repo contains Microsoft's implementation of GSL.
@@ -27,9 +27,14 @@ The test suite that exercises GSL has been built and passes successfully on the
* Windows using Visual Studio 2015
* Windows using Visual Studio 2017
* Windows using Clang/LLVM 3.6
+* Windows using Clang/LLVM 7.0.0
* Windows using GCC 5.1
* Windows using Intel C++ Compiler 18.0
-* GNU/Linux using Clang/LLVM 3.6
+* GNU/Linux using Clang/LLVM 3.6-3.9
+* GNU/Linux using Clang/LLVM 4.0
+* GNU/Linux using Clang/LLVM 5.0
+* GNU/Linux using Clang/LLVM 6.0
+* GNU/Linux using Clang/LLVM 7.0
* GNU/Linux using GCC 5.1
* OS X Yosemite using Xcode with Apple Clang 7.0.0.7000072
* OS X Yosemite using GCC-5.2.0
diff --git a/appveyor.yml b/appveyor.yml
index 2fc8a16..c3e3c87 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -13,44 +13,108 @@ image:
- Visual Studio 2017
environment:
+ NINJA_TAG: v1.8.2
+ NINJA_SHA512: 9B9CE248240665FCD6404B989F3B3C27ED9682838225E6DC9B67B551774F251E4FF8A207504F941E7C811E7A8BE1945E7BCB94472A335EF15E23A0200A32E6D5
+ NINJA_PATH: C:\Tools\ninja\ninja-%NINJA_TAG%
+ VCVAR2015: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat'
+ VCVAR2017: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat'
matrix:
- GSL_CXX_STANDARD: 14
+ USE_TOOLSET: MSVC
+ USE_GENERATOR: MSBuild
- GSL_CXX_STANDARD: 17
+ USE_TOOLSET: MSVC
+ USE_GENERATOR: MSBuild
+ - GSL_CXX_STANDARD: 14
+ USE_TOOLSET: LLVM
+ USE_GENERATOR: Ninja
+ - GSL_CXX_STANDARD: 17
+ USE_TOOLSET: LLVM
+ USE_GENERATOR: Ninja
matrix:
exclude:
- image: Visual Studio 2015
GSL_CXX_STANDARD: 17
+ - image: Visual Studio 2015
+ USE_TOOLSET: LLVM
+ USE_GENERATOR: MSBuild
cache:
- C:\cmake-3.8.0-win32-x86
+ - C:\Tools\ninja
install:
- ps: |
- if (![IO.File]::Exists("C:\cmake-3.8.0-win32-x86\bin\cmake.exe")) {
- Start-FileDownload 'https://cmake.org/files/v3.8/cmake-3.8.0-win32-x86.zip'
- 7z x -y cmake-3.8.0-win32-x86.zip -oC:\
+ if (![IO.File]::Exists("$env:NINJA_PATH\ninja.exe")) {
+ Start-FileDownload `
+ "https://github.com/ninja-build/ninja/releases/download/$env:NINJA_TAG/ninja-win.zip"
+ $hash = (Get-FileHash ninja-win.zip -Algorithm SHA512).Hash
+ if ($env:NINJA_SHA512 -eq $hash) {
+ 7z e -y -bso0 ninja-win.zip -o"$env:NINJA_PATH"
+ } else { Write-Warning "Ninja download hash changed!"; Write-Output "$hash" }
+ }
+ if ([IO.File]::Exists("$env:NINJA_PATH\ninja.exe")) {
+ $env:PATH = "$env:NINJA_PATH;$env:PATH"
+ } else { Write-Warning "Failed to find ninja.exe in expected location." }
+ if ($env:USE_TOOLSET -ne "LLVM") {
+ if (![IO.File]::Exists("C:\cmake-3.8.0-win32-x86\bin\cmake.exe")) {
+ Start-FileDownload 'https://cmake.org/files/v3.8/cmake-3.8.0-win32-x86.zip'
+ 7z x -y -bso0 cmake-3.8.0-win32-x86.zip -oC:\
+ }
+ $env:PATH="C:\cmake-3.8.0-win32-x86\bin;$env:PATH"
}
- $env:PATH="C:\cmake-3.8.0-win32-x86\bin;$env:PATH"
before_build:
- ps: |
- mkdir build
- cd build
-
- if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2015") {
- $env:generator="Visual Studio 14 2015"
+ if ("$env:USE_GENERATOR" -eq "Ninja") {
+ $GeneratorFlags = '-k 10'
+ $Architecture = $env:PLATFORM
+ if ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2015") {
+ $env:VCVARSALL = "`"$env:VCVAR2015`" $Architecture"
+ } else {
+ $env:VCVARSALL = "`"$env:VCVAR2017`" $Architecture"
+ }
+ $env:CMakeGenFlags = "-G Ninja -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
} else {
- $env:generator="Visual Studio 15 2017"
+ $GeneratorFlags = '/m /v:minimal'
+ if ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2015") {
+ $Generator = 'Visual Studio 14 2015'
+ } else {
+ $Generator = 'Visual Studio 15 2017'
+ }
+ if ("$env:PLATFORM" -eq "x86") {
+ $Architecture = "Win32"
+ } else {
+ $Architecture = "x64"
+ }
+ if ("$env:USE_TOOLSET" -eq "LLVM") {
+ $env:CMakeGenFlags = "-G `"$Generator`" -A $Architecture -T llvm -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
+ } else {
+ $env:CMakeGenFlags = "-G `"$Generator`" -A $Architecture -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
+ }
}
- if ($env:PLATFORM -eq "x64") {
- $env:generator="$env:generator Win64"
+ if ("$env:USE_TOOLSET" -eq "LLVM") {
+ $env:CC = "clang-cl"
+ $env:CXX = "clang-cl"
+ if ("$env:PLATFORM" -eq "x86") {
+ $env:CFLAGS = "-m32";
+ $env:CXXFLAGS = "-m32";
+ } else {
+ $env:CFLAGS = "-m64";
+ $env:CXXFLAGS = "-m64";
+ }
}
- echo generator="$env:generator"
- cmake .. -G "$env:generator" -DGSL_CXX_STANDARD="$env:GSL_CXX_STANDARD"
+ $env:CMakeBuildFlags = "--config $env:CONFIGURATION -- $GeneratorFlags"
+ - mkdir build
+ - cd build
+ - if %USE_GENERATOR%==Ninja (call %VCVARSALL%)
+ - echo %CMakeGenFlags%
+ - cmake .. %CMakeGenFlags%
build_script:
- - cmake --build . --config %CONFIGURATION% -- /m /v:minimal
+ - echo %CMakeBuildFlags%
+ - cmake --build . %CMakeBuildFlags%
test_script:
- ctest -j2
diff --git a/include/gsl/gsl_assert b/include/gsl/gsl_assert
index 3c952e6..c704633 100644
--- a/include/gsl/gsl_assert
+++ b/include/gsl/gsl_assert
@@ -22,17 +22,17 @@
//
// make suppress attributes parse for some compilers
-// Hopefully temporary until suppresion standardization occurs
+// Hopefully temporary until suppression standardization occurs
//
-#if defined (_MSC_VER)
-#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
-#else
#if defined(__clang__)
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]]
#else
+#if defined(_MSC_VER)
+#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
+#else
#define GSL_SUPPRESS(x)
-#endif // __clang__
#endif // _MSC_VER
+#endif // __clang__
//
// Temporary until MSVC STL supports no-exceptions mode.
@@ -42,6 +42,12 @@
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
#include <intrin.h>
#define RANGE_CHECKS_FAILURE 0
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winvalid-noreturn"
+#endif
+
#endif
//
@@ -98,7 +104,7 @@ namespace details
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
typedef void (__cdecl *terminate_handler)();
-
+
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute
[[noreturn]] inline void __cdecl default_terminate_handler()
{
@@ -138,7 +144,7 @@ namespace details
throw std::forward<Exception>(exception);
}
-#endif
+#endif // GSL_TERMINATE_ON_CONTRACT_VIOLATION
} // namespace details
} // namespace gsl
@@ -159,9 +165,13 @@ namespace details
#define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond)
-#endif
+#endif // GSL_THROW_ON_CONTRACT_VIOLATION
#define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond)
#define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond)
+#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) && defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
#endif // GSL_CONTRACTS_H
diff --git a/include/gsl/gsl_byte b/include/gsl/gsl_byte
index bc18886..861446d 100644
--- a/include/gsl/gsl_byte
+++ b/include/gsl/gsl_byte
@@ -19,17 +19,17 @@
//
// make suppress attributes work for some compilers
-// Hopefully temporary until suppresion standardization occurs
+// Hopefully temporary until suppression standardization occurs
//
-#if defined(_MSC_VER)
-#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
-#else
#if defined(__clang__)
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]]
#else
+#if defined(_MSC_VER)
+#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
+#else
#define GSL_SUPPRESS(x)
-#endif // __clang__
#endif // _MSC_VER
+#endif // __clang__
#include <type_traits>
@@ -79,7 +79,7 @@
#endif // _MSC_VER
// Use __may_alias__ attribute on gcc and clang
-#if defined __clang__ || (__GNUC__ > 5)
+#if defined __clang__ || (defined(__GNUC__) && __GNUC__ > 5)
#define byte_may_alias __attribute__((__may_alias__))
#else // defined __clang__ || defined __GNUC__
#define byte_may_alias
diff --git a/include/gsl/gsl_util b/include/gsl/gsl_util
index 542bbaa..4addde6 100644
--- a/include/gsl/gsl_util
+++ b/include/gsl/gsl_util
@@ -26,7 +26,7 @@
#include <type_traits> // for is_signed, integral_constant
#include <utility> // for forward
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
@@ -37,6 +37,12 @@
#endif // _MSC_VER < 1910
#endif // _MSC_VER
+#if (defined(_MSC_VER) && _MSC_VER < 1910) || (!defined(__clang__) && defined(__GNUC__) && __GUNC__ < 6)
+#define GSL_CONSTEXPR_NARROW 0
+#else
+#define GSL_CONSTEXPR_NARROW 1
+#endif
+
namespace gsl
{
//
@@ -111,6 +117,9 @@ namespace details
template <class T, class U>
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
+#if GSL_CONSTEXPR_NARROW
+constexpr
+#endif
T narrow(U u) noexcept(false)
{
T t = narrow_cast<T>(u);
@@ -152,7 +161,7 @@ constexpr T at(const std::initializer_list<T> cont, const index i)
} // namespace gsl
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER < 1910
#undef constexpr
#pragma pop_macro("constexpr")
diff --git a/include/gsl/multi_span b/include/gsl/multi_span
index c8f4aae..f1a909e 100644
--- a/include/gsl/multi_span
+++ b/include/gsl/multi_span
@@ -37,7 +37,7 @@
#include <type_traits> // for enable_if_t, remove_cv_t, is_same, is_co...
#include <utility>
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__clang__)
// turn off some warnings that are noisy about our Expects statements
#pragma warning(push)
@@ -62,7 +62,7 @@
// compiletime, so the compiler wouldn't have to warn indiscriminently, but
// could check if the source value actually doesn't fit into the target type
// and only warn in those cases.
-#if __GNUC__ > 6
+#if defined(__GNUC__) && __GNUC__ > 6
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
@@ -315,33 +315,33 @@ namespace details
// TODO : following signature is for work around VS bug
template <typename OtherRange>
- BoundsRanges(const OtherRange&, bool /* firstLevel */)
+ constexpr BoundsRanges(const OtherRange&, bool /* firstLevel */)
{}
- BoundsRanges(const std::ptrdiff_t* const) {}
- BoundsRanges() noexcept = default;
+ constexpr BoundsRanges(const std::ptrdiff_t* const) {}
+ constexpr BoundsRanges() noexcept = default;
template <typename T, std::size_t Dim>
- void serialize(T&) const
+ constexpr void serialize(T&) const
{}
template <typename T, std::size_t Dim>
- size_type linearize(const T&) const
+ constexpr size_type linearize(const T&) const
{
return 0;
}
template <typename T, std::size_t Dim>
- size_type contains(const T&) const
+ constexpr size_type contains(const T&) const
{
return -1;
}
- size_type elementNum(std::size_t) const noexcept { return 0; }
+ constexpr size_type elementNum(std::size_t) const noexcept { return 0; }
- size_type totalSize() const noexcept { return TotalSize; }
+ constexpr size_type totalSize() const noexcept { return TotalSize; }
- bool operator==(const BoundsRanges&) const noexcept { return true; }
+ constexpr bool operator==(const BoundsRanges&) const noexcept { return true; }
};
template <std::ptrdiff_t... RestRanges>
@@ -360,23 +360,23 @@ namespace details
public:
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute // this pointer type is cannot be assigned nullptr - issue in not_null
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
- BoundsRanges(const std::ptrdiff_t* const arr)
+ constexpr BoundsRanges(const std::ptrdiff_t* const arr)
: Base(arr + 1), m_bound(*arr * this->Base::totalSize())
{
Expects(0 <= *arr);
}
- BoundsRanges() noexcept : m_bound(0) {}
+ constexpr BoundsRanges() noexcept : m_bound(0) {}
template <std::ptrdiff_t OtherRange, std::ptrdiff_t... RestOtherRanges>
- BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
+ constexpr BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
bool /* firstLevel */ = true)
: Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false)
, m_bound(other.totalSize())
{}
template <typename T, std::size_t Dim = 0>
- void serialize(T& arr) const
+ constexpr void serialize(T& arr) const
{
arr[Dim] = elementNum();
this->Base::template serialize<T, Dim + 1>(arr);
@@ -384,7 +384,7 @@ namespace details
template <typename T, std::size_t Dim = 0>
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
- size_type linearize(const T& arr) const
+ constexpr size_type linearize(const T& arr) const
{
const size_type index = this->Base::totalSize() * arr[Dim];
Expects(index < m_bound);
@@ -392,7 +392,7 @@ namespace details
}
template <typename T, std::size_t Dim = 0>
- size_type contains(const T& arr) const
+ constexpr size_type contains(const T& arr) const
{
const ptrdiff_t last = this->Base::template contains<T, Dim + 1>(arr);
if (last == -1) return -1;
@@ -401,18 +401,19 @@ namespace details
}
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
- size_type totalSize() const noexcept
+ constexpr size_type totalSize() const noexcept
{
return m_bound;
}
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
- size_type elementNum() const noexcept
+ constexpr size_type elementNum() const noexcept
{
return totalSize() / this->Base::totalSize();
}
- size_type elementNum(std::size_t dim) const noexcept
+ GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
+ constexpr size_type elementNum(std::size_t dim) const noexcept
{
if (dim > 0)
return this->Base::elementNum(dim - 1);
@@ -420,7 +421,7 @@ namespace details
return elementNum();
}
- bool operator==(const BoundsRanges& rhs) const noexcept
+ constexpr bool operator==(const BoundsRanges& rhs) const noexcept
{
return m_bound == rhs.m_bound &&
static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
@@ -438,11 +439,11 @@ namespace details
static const size_type TotalSize =
Base::TotalSize == dynamic_range ? dynamic_range : CurrentRange * Base::TotalSize;
- BoundsRanges(const std::ptrdiff_t* const arr) : Base(arr) {}
- BoundsRanges() = default;
+ constexpr BoundsRanges(const std::ptrdiff_t* const arr) : Base(arr) {}
+ constexpr BoundsRanges() = default;
template <std::ptrdiff_t OtherRange, std::ptrdiff_t... RestOtherRanges>
- BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
+ constexpr BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
bool firstLevel = true)
: Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false)
{
@@ -451,25 +452,25 @@ namespace details
}
template <typename T, std::size_t Dim = 0>
- void serialize(T& arr) const
+ constexpr void serialize(T& arr) const
{
arr[Dim] = elementNum();
this->Base::template serialize<T, Dim + 1>(arr);
}
template <typename T, std::size_t Dim = 0>
- size_type linearize(const T& arr) const
+ constexpr size_type linearize(const T& arr) const
{
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
Expects(arr[Dim] >= 0 && arr[Dim] < CurrentRange); // Index is out of range
-
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
- return this->Base::totalSize() * arr[Dim] +
+ const ptrdiff_t d = arr[Dim];
+ return this->Base::totalSize() * d +
this->Base::template linearize<T, Dim + 1>(arr);
}
template <typename T, std::size_t Dim = 0>
- size_type contains(const T& arr) const
+ constexpr size_type contains(const T& arr) const
{
if (arr[Dim] >= CurrentRange) return -1;
const size_type last = this->Base::template contains<T, Dim + 1>(arr);
@@ -478,19 +479,19 @@ namespace details
}
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
- size_type totalSize() const noexcept
+ constexpr size_type totalSize() const noexcept
{
return CurrentRange * this->Base::totalSize();
}
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
- size_type elementNum() const noexcept
+ constexpr size_type elementNum() const noexcept
{
return CurrentRange;
}
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
- size_type elementNum(std::size_t dim) const noexcept
+ constexpr size_type elementNum(std::size_t dim) const noexcept
{
if (dim > 0)
return this->Base::elementNum(dim - 1);
@@ -498,7 +499,7 @@ namespace details
return elementNum();
}
- bool operator==(const BoundsRanges& rhs) const noexcept
+ constexpr bool operator==(const BoundsRanges& rhs) const noexcept
{
return static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
}
@@ -595,7 +596,6 @@ public:
using sliced_type = static_bounds<RestRanges...>;
using mapping_type = contiguous_mapping_tag;
- constexpr static_bounds(const static_bounds&) noexcept = default;
constexpr static_bounds() /*noexcept*/ = default;
template <typename SourceType, typename TargetType, std::size_t Rank>
@@ -1886,6 +1886,8 @@ public:
auto d = narrow_cast<size_type>(sizeof(OtherValueType) / sizeof(value_type));
const size_type size = this->bounds().total_size() / d;
+
+ GSL_SUPPRESS(type.3) // NO-FORMAT: attribute
return {const_cast<OtherValueType*>(reinterpret_cast<const OtherValueType*>(this->data())),
size,
bounds_type{resize_extent(this->bounds().index_bounds(), d),
@@ -2273,7 +2275,7 @@ general_span_iterator<Span> operator+(typename general_span_iterator<Span>::diff
} // namespace gsl
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER < 1910
#undef constexpr
@@ -2284,7 +2286,7 @@ general_span_iterator<Span> operator+(typename general_span_iterator<Span>::diff
#endif // _MSC_VER
-#if __GNUC__ > 6
+#if defined(__GNUC__) && __GNUC__ > 6
#pragma GCC diagnostic pop
#endif // __GNUC__ > 6
diff --git a/include/gsl/pointers b/include/gsl/pointers
index a338856..0f2987a 100644
--- a/include/gsl/pointers
+++ b/include/gsl/pointers
@@ -25,7 +25,7 @@
#include <system_error> // for hash
#include <type_traits> // for enable_if_t, is_convertible, is_assignable
-#if defined(_MSC_VER) && _MSC_VER < 1910
+#if defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__)
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
@@ -72,13 +72,13 @@ public:
static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
- constexpr explicit not_null(U&& u) : ptr_(std::forward<U>(u))
+ constexpr not_null(U&& u) : ptr_(std::forward<U>(u))
{
Expects(ptr_ != nullptr);
}
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
- constexpr explicit not_null(T u) : ptr_(u)
+ constexpr not_null(T u) : ptr_(u)
{
Expects(ptr_ != nullptr);
}
@@ -121,7 +121,7 @@ private:
template <class T>
auto make_not_null(T&& t) {
- return gsl::not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)};
+ return not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)};
}
template <class T>
@@ -189,10 +189,106 @@ struct hash<gsl::not_null<T>>
} // namespace std
-#if defined(_MSC_VER) && _MSC_VER < 1910
+namespace gsl
+{
+
+//
+// strict_not_null
+//
+// Restricts a pointer or smart pointer to only hold non-null values,
+//
+// - provides a strict (i.e. explicit contructor from T) wrapper of not_null
+// - to be used for new code that wishes the design to be cleaner and make not_null
+// checks intentional, or in old code that would like to make the transition.
+//
+// To make the transition from not_null, incrementally replace not_null
+// by strict_not_null and fix compilation errors
+//
+// Expect to
+// - remove all unneded conversions from raw pointer to not_null and back
+// - make API clear by specifyning not_null in parameters where needed
+// - remove unnesessary asserts
+//
+template <class T>
+class strict_not_null: public not_null<T>
+{
+public:
+
+ template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
+ constexpr explicit strict_not_null(U&& u) :
+ not_null<T>(std::forward<U>(u))
+ {}
+
+ template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
+ constexpr explicit strict_not_null(T u) :
+ not_null<T>(u)
+ {}
+
+ template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
+ constexpr strict_not_null(const not_null<U>& other) :
+ not_null<T>(other)
+ {}
+
+ template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
+ constexpr strict_not_null(const strict_not_null<U>& other) :
+ not_null<T>(other)
+ {}
+
+ strict_not_null(strict_not_null&& other) = default;
+ strict_not_null(const strict_not_null& other) = default;
+ strict_not_null& operator=(const strict_not_null& other) = default;
+ strict_not_null& operator=(const not_null<T>& other)
+ {
+ not_null<T>::operator=(other);
+ return *this;
+ }
+
+ // prevents compilation when someone attempts to assign a null pointer constant
+ strict_not_null(std::nullptr_t) = delete;
+ strict_not_null& operator=(std::nullptr_t) = delete;
+
+ // unwanted operators...pointers only point to single objects!
+ strict_not_null& operator++() = delete;
+ strict_not_null& operator--() = delete;
+ strict_not_null operator++(int) = delete;
+ strict_not_null operator--(int) = delete;
+ strict_not_null& operator+=(std::ptrdiff_t) = delete;
+ strict_not_null& operator-=(std::ptrdiff_t) = delete;
+ void operator[](std::ptrdiff_t) const = delete;
+};
+
+// more unwanted operators
+template <class T, class U>
+std::ptrdiff_t operator-(const strict_not_null<T>&, const strict_not_null<U>&) = delete;
+template <class T>
+strict_not_null<T> operator-(const strict_not_null<T>&, std::ptrdiff_t) = delete;
+template <class T>
+strict_not_null<T> operator+(const strict_not_null<T>&, std::ptrdiff_t) = delete;
+template <class T>
+strict_not_null<T> operator+(std::ptrdiff_t, const strict_not_null<T>&) = delete;
+
+template <class T>
+auto make_strict_not_null(T&& t) {
+ return strict_not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)};
+}
+
+} // namespace gsl
+
+namespace std
+{
+template <class T>
+struct hash<gsl::strict_not_null<T>>
+{
+ std::size_t operator()(const gsl::strict_not_null<T>& value) const { return hash<T>{}(value); }
+};
+
+} // namespace std
+
+#if defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__)
+
#undef constexpr
#pragma pop_macro("constexpr")
-#endif // defined(_MSC_VER) && _MSC_VER < 1910
+#endif // defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__)
#endif // GSL_POINTERS_H
diff --git a/include/gsl/span b/include/gsl/span
index 8cb3dbe..b4da532 100644
--- a/include/gsl/span
+++ b/include/gsl/span
@@ -31,7 +31,7 @@
#include <utility>
#include <memory> // for std::addressof
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
// turn off some warnings that are noisy about our Expects statements
@@ -61,7 +61,7 @@
// compiletime, so the compiler wouldn't have to warn indiscriminently, but
// could check if the source value actually doesn't fit into the target type
// and only warn in those cases.
-#if __GNUC__ > 6
+#if defined(__GNUC__) && __GNUC__ > 6
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
@@ -394,17 +394,27 @@ public:
: storage_(KnownNotNull{std::addressof(arr[0])}, details::extent_type<N>())
{}
- template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
- // GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
- constexpr span(std::array<ArrayElementType, N>& arr) noexcept
- : storage_(arr.data(), details::extent_type<N>())
- {}
+ template <std::size_t N, class = std::enable_if_t<(N > 0)>>
+ constexpr span(std::array<std::remove_const_t<element_type>, N>& arr) noexcept
+ : storage_(KnownNotNull{arr.data()}, details::extent_type<N>())
+ {
+ }
- template <std::size_t N>
- // GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
+ constexpr span(std::array<std::remove_const_t<element_type>, 0>&) noexcept
+ : storage_(static_cast<pointer>(nullptr), details::extent_type<0>())
+ {
+ }
+
+ template <std::size_t N, class = std::enable_if_t<(N > 0)>>
constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) noexcept
- : storage_(arr.data(), details::extent_type<N>())
- {}
+ : storage_(KnownNotNull{arr.data()}, details::extent_type<N>())
+ {
+ }
+
+ constexpr span(const std::array<std::remove_const_t<element_type>, 0>&) noexcept
+ : storage_(static_cast<pointer>(nullptr), details::extent_type<0>())
+ {
+ }
// NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
// on Container to be a contiguous sequence container.
@@ -534,7 +544,7 @@ public:
#endif // _MSC_VER
private:
- static bool CheckRange(index_type idx, index_type size)
+ static constexpr bool CheckRange(index_type idx, index_type size) noexcept
{
// Optimization:
//
@@ -546,7 +556,11 @@ private:
// wrap around to a value always greater than size when casted.
// check if we have enough space to wrap around
+#if defined(__cpp_if_constexpr)
+ if constexpr (sizeof(index_type) <= sizeof(size_t))
+#else
if (sizeof(index_type) <= sizeof(size_t))
+#endif
{
return narrow_cast<size_t>(idx) < narrow_cast<size_t>(size);
}
@@ -762,7 +776,7 @@ constexpr ElementType& at(span<ElementType, Extent> s, index i)
} // namespace gsl
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER < 1910
#undef constexpr
#pragma pop_macro("constexpr")
@@ -772,7 +786,7 @@ constexpr ElementType& at(span<ElementType, Extent> s, index i)
#pragma warning(pop)
#endif // _MSC_VER
-#if __GNUC__ > 6
+#if defined(__GNUC__) && __GNUC__ > 6
#pragma GCC diagnostic pop
#endif // __GNUC__ > 6
diff --git a/include/gsl/string_span b/include/gsl/string_span
index d298039..b5dfd18 100644
--- a/include/gsl/string_span
+++ b/include/gsl/string_span
@@ -30,7 +30,7 @@
#include <string> // for basic_string, allocator, char_traits
#include <type_traits> // for declval, is_convertible, enable_if_t, add_...
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool.
@@ -706,7 +706,7 @@ bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other)
#endif
} // namespace gsl
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(pop)
#if _MSC_VER < 1910
diff --git a/samples/gsl_transition b/samples/gsl_transition
deleted file mode 100644
index 3f5bf6c..0000000
--- a/samples/gsl_transition
+++ /dev/null
@@ -1,130 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
-//
-// This code is licensed under the MIT License (MIT).
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef GSL_TRANSITION_H
-#define GSL_TRANSITION_H
-
-#include <gsl/gsl_assert> // for Ensures, Expects
-#include <gsl/pointers> // for gsl::not_null
-
-#if defined(_MSC_VER) && _MSC_VER < 1910
-#pragma push_macro("constexpr")
-#define constexpr /*constexpr*/
-
-#endif // defined(_MSC_VER) && _MSC_VER < 1910
-
-namespace gsl_helpers
-{
-//
-// sloppy_not_null
-//
-// Restricts a pointer or smart pointer to only hold non-null values,
-//
-// - provides a sloppy (i.e. no explicit contructor from T) wrapper of gsl::not_null
-// - is temporary, only to be used to incrementally transition of code
-// using older version of gsl::not_null to the new one that made the constructor explicit
-//
-// To make the transition:
-//
-// - replace all occurences of gsl::not_null in your code by sloppy_not_null
-// variant: rename gsl::not_null by NotNull by including the following in your code,
-// foe example, in a common include file:
-//
-// template<typename T>
-// using NotNull = gsl::not_null<T>;
-//
-// compile using old version of GSL
-// change GSL version and replace gsl::not_null by gsl_helpers::sloppy_not_null
-// in the added code lines above
-//
-// - compile - compilation should be successful
-// - replace some sloppy_not_nulls by gsl::not_null, fix compilation erros,
-// redesign as needed, compile and test
-// - repeat until no sloppy_not_nulls remain
-//
-template <class T>
-class sloppy_not_null: public gsl::not_null<T>
-{
-public:
-
- template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
- constexpr sloppy_not_null(U&& u) :
- gsl::not_null<T>(std::forward<U>(u))
- {}
-
- template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
- constexpr sloppy_not_null(T u) :
- gsl::not_null<T>(u)
- {}
-
- template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
- constexpr sloppy_not_null(const gsl::not_null<U>& other) :
- gsl::not_null<T>(other)
- {}
-
- sloppy_not_null(sloppy_not_null&& other) = default;
- sloppy_not_null(const sloppy_not_null& other) = default;
- sloppy_not_null& operator=(const sloppy_not_null& other) = default;
- sloppy_not_null& operator=(const gsl::not_null<T>& other)
- {
- gsl::not_null<T>::operator=(other);
- return *this;
- }
-
- // prevents compilation when someone attempts to assign a null pointer constant
- sloppy_not_null(std::nullptr_t) = delete;
- sloppy_not_null& operator=(std::nullptr_t) = delete;
-
- // unwanted operators...pointers only point to single objects!
- sloppy_not_null& operator++() = delete;
- sloppy_not_null& operator--() = delete;
- sloppy_not_null operator++(int) = delete;
- sloppy_not_null operator--(int) = delete;
- sloppy_not_null& operator+=(std::ptrdiff_t) = delete;
- sloppy_not_null& operator-=(std::ptrdiff_t) = delete;
- void operator[](std::ptrdiff_t) const = delete;
-};
-
-// more unwanted operators
-template <class T, class U>
-std::ptrdiff_t operator-(const sloppy_not_null<T>&, const sloppy_not_null<U>&) = delete;
-template <class T>
-sloppy_not_null<T> operator-(const sloppy_not_null<T>&, std::ptrdiff_t) = delete;
-template <class T>
-sloppy_not_null<T> operator+(const sloppy_not_null<T>&, std::ptrdiff_t) = delete;
-template <class T>
-sloppy_not_null<T> operator+(std::ptrdiff_t, const sloppy_not_null<T>&) = delete;
-
-} // namespace gsl
-
-namespace std
-{
-template <class T>
-struct hash<gsl_helpers::sloppy_not_null<T>>
-{
- std::size_t operator()(const gsl_helpers::sloppy_not_null<T>& value) const { return hash<T>{}(value); }
-};
-
-} // namespace std
-
-#if defined(_MSC_VER) && _MSC_VER < 1910
-#undef constexpr
-#pragma pop_macro("constexpr")
-
-#endif // defined(_MSC_VER) && _MSC_VER < 1910
-
-#endif // GSL_TRANSITION_H
-
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 2d37a51..832513f 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.7)
+cmake_minimum_required(VERSION 3.0.2)
project(GSLTests CXX)
@@ -33,14 +33,24 @@ endif()
# this interface adds compile options to how the tests are run
# please try to keep entries ordered =)
add_library(gsl_tests_config INTERFACE)
-target_compile_options(gsl_tests_config INTERFACE
- $<$<CXX_COMPILER_ID:MSVC>:
+if(MSVC) # MSVC or simulating MSVC
+ target_compile_options(gsl_tests_config INTERFACE
+ ${GSL_CPLUSPLUS_OPT}
/EHsc
/W4
/WX
- >
- ${GSL_CPLUSPLUS_OPT}
- $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:
+ $<$<CXX_COMPILER_ID:Clang>:
+ -Weverything
+ -Wno-c++98-compat
+ -Wno-c++98-compat-pedantic
+ -Wno-missing-braces
+ -Wno-missing-prototypes
+ -Wno-unknown-attributes
+ $<$<EQUAL:${GSL_CXX_STANDARD},14>:-Wno-unused-member-function>
+ >
+ )
+else()
+ target_compile_options(gsl_tests_config INTERFACE
-fno-strict-aliasing
-Wall
-Wcast-align
@@ -48,16 +58,25 @@ target_compile_options(gsl_tests_config INTERFACE
-Wctor-dtor-privacy
-Werror
-Wextra
- -Wno-missing-braces
- -Wno-unknown-attributes
- -Wnon-virtual-dtor
- -Wold-style-cast
- -Woverloaded-virtual
-Wpedantic
-Wshadow
-Wsign-conversion
- >
-)
+ $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
+ -Weverything
+ -Wno-c++98-compat
+ -Wno-c++98-compat-pedantic
+ -Wno-missing-braces
+ -Wno-missing-prototypes
+ -Wno-padded
+ -Wno-unknown-attributes
+ $<$<EQUAL:${GSL_CXX_STANDARD},14>:-Wno-unused-member-function>
+ -Wno-weak-vtables
+ >
+ $<$<CXX_COMPILER_ID:Clang>:
+ $<$<CXX_COMPILER_VERSION:5.0.2>:-Wno-undefined-func-template>
+ >
+ )
+endif(MSVC)
# for tests to find the catch header
target_include_directories(gsl_tests_config INTERFACE
@@ -107,7 +126,7 @@ add_gsl_test(utils_tests)
add_gsl_test(owner_tests)
add_gsl_test(byte_tests)
add_gsl_test(algorithm_tests)
-add_gsl_test(sloppy_notnull_tests)
+add_gsl_test(strict_notnull_tests)
# No exception tests
@@ -121,34 +140,49 @@ endforeach(flag_var)
# this interface adds compile options to how the tests are run
# please try to keep entries ordered =)
add_library(gsl_tests_config_noexcept INTERFACE)
-target_compile_options(gsl_tests_config_noexcept INTERFACE
- $<$<CXX_COMPILER_ID:MSVC>:
- /D_HAS_EXCEPTIONS=0
- /wd4702
- /wd4577
+if(MSVC) # MSVC or simulating MSVC
+ target_compile_definitions(gsl_tests_config_noexcept INTERFACE
+ _HAS_EXCEPTIONS=0
+ )
+ target_compile_options(gsl_tests_config_noexcept INTERFACE
+ ${GSL_CPLUSPLUS_OPT}
/W4
/WX
- >
- ${GSL_CPLUSPLUS_OPT}
- $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:
- -fno-strict-aliasing
+ $<$<CXX_COMPILER_ID:MSVC>:
+ /wd4577
+ /wd4702
+ >
+ $<$<CXX_COMPILER_ID:Clang>:
+ -Weverything
+ -Wno-c++98-compat
+ -Wno-c++98-compat-pedantic
+ -Wno-missing-prototypes
+ -Wno-unknown-attributes
+ >
+ )
+else()
+ target_compile_options(gsl_tests_config_noexcept INTERFACE
-fno-exceptions
+ -fno-strict-aliasing
-Wall
-Wcast-align
-Wconversion
-Wctor-dtor-privacy
-Werror
-Wextra
- -Wno-missing-braces
- -Wno-unknown-attributes
- -Wnon-virtual-dtor
- -Wold-style-cast
- -Woverloaded-virtual
-Wpedantic
-Wshadow
-Wsign-conversion
- >
-)
+ $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
+ -Weverything
+ -Wno-c++98-compat
+ -Wno-c++98-compat-pedantic
+ -Wno-missing-prototypes
+ -Wno-unknown-attributes
+ -Wno-weak-vtables
+ >
+ )
+endif(MSVC)
# set definitions for tests
target_compile_definitions(gsl_tests_config_noexcept INTERFACE
diff --git a/tests/multi_span_tests.cpp b/tests/multi_span_tests.cpp
index 9c05cb4..7e3ec89 100644
--- a/tests/multi_span_tests.cpp
+++ b/tests/multi_span_tests.cpp
@@ -1782,4 +1782,4 @@ TEST_CASE("iterator")
#ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static);
-#endif \ No newline at end of file
+#endif
diff --git a/tests/no_exception_ensure_tests.cpp b/tests/no_exception_ensure_tests.cpp
index 3a7f007..b1ae15b 100644
--- a/tests/no_exception_ensure_tests.cpp
+++ b/tests/no_exception_ensure_tests.cpp
@@ -14,21 +14,17 @@
//
///////////////////////////////////////////////////////////////////////////////
-#include <cstdlib> // for std::exit
-#include <gsl/span> // for span
+#include <cstdlib> // for std::exit
+#include <gsl/span> // for span
int operator_subscript_no_throw() noexcept
{
- int arr[10];
- const gsl::span<int> sp { arr };
+ int arr[10];
+ const gsl::span<int> sp{arr};
return sp[11];
}
-
-void test_terminate()
-{
- std::exit(0);
-}
+[[noreturn]] void test_terminate() { std::exit(0); }
void setup_termination_handler() noexcept
{
@@ -44,7 +40,6 @@ void setup_termination_handler() noexcept
#endif
}
-
int main() noexcept
{
setup_termination_handler();
diff --git a/tests/no_exception_throw_tests.cpp b/tests/no_exception_throw_tests.cpp
index e9f4dac..b28ad00 100644
--- a/tests/no_exception_throw_tests.cpp
+++ b/tests/no_exception_throw_tests.cpp
@@ -14,20 +14,17 @@
//
///////////////////////////////////////////////////////////////////////////////
-#include <cstdlib> // for std::exit
-#include <gsl/gsl_util> // for narrow
+#include <cstdlib> // for std::exit
#include <gsl/gsl_assert> // for get_terminate
+#include <gsl/gsl_util> // for narrow
int narrow_no_throw()
{
const long long bigNumber = 0x0fffffffffffffff;
- return gsl::narrow<int>(bigNumber);
+ return gsl::narrow<int>(bigNumber);
}
-void test_terminate()
-{
- std::exit(0);
-}
+[[noreturn]] void test_terminate() { std::exit(0); }
void setup_termination_handler() noexcept
{
@@ -43,7 +40,6 @@ void setup_termination_handler() noexcept
#endif
}
-
int main()
{
setup_termination_handler();
diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp
index 668c0a2..ce5a123 100644
--- a/tests/notnull_tests.cpp
+++ b/tests/notnull_tests.cpp
@@ -25,7 +25,7 @@
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
-#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
+#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
#include <algorithm> // for addressof
#include <memory> // for shared_ptr, make_shared, operator<, opera...
@@ -128,47 +128,105 @@ struct NonCopyableNonMovable
};
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
-bool helper(not_null<int*> p)
-{
- return *p == 12;
-}
-
+bool helper(not_null<int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
-bool helper_const(not_null<const int*> p)
-{
- return *p == 12;
-}
+bool helper_const(not_null<const int*> p) { return *p == 12; }
+
+int* return_pointer() { return nullptr; }
+const int* return_pointer_const() { return nullptr; }
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("TestNotNullConstructors")
{
+ {
#ifdef CONFIRM_COMPILATION_ERRORS
- not_null<int*> p = nullptr; // yay...does not compile!
- not_null<std::vector<char>*> p = 0; // yay...does not compile!
- not_null<int*> p; // yay...does not compile!
- std::unique_ptr<int> up = std::make_unique<int>(120);
- not_null<int*> p = up;
-
- // Forbid non-nullptr assignable types
- not_null<std::vector<int>> f(std::vector<int>{1});
- not_null<int> z(10);
- not_null<std::vector<int>> y({1, 2});
+ not_null<int*> p = nullptr; // yay...does not compile!
+ not_null<std::vector<char>*> p1 = 0; // yay...does not compile!
+ not_null<int*> p2; // yay...does not compile!
+ std::unique_ptr<int> up = std::make_unique<int>(120);
+ not_null<int*> p3 = up;
+
+ // Forbid non-nullptr assignable types
+ not_null<std::vector<int>> f(std::vector<int>{1});
+ not_null<int> z(10);
+ not_null<std::vector<int>> y({1, 2});
#endif
- int i = 12;
- auto rp = RefCounted<int>(&i);
- not_null<int*> p(rp);
- CHECK(p.get() == &i);
+ }
- not_null<std::shared_ptr<int>> x(
- std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
+ {
+ // from shared pointer
+ int i = 12;
+ auto rp = RefCounted<int>(&i);
+ not_null<int*> p(rp);
+ CHECK(p.get() == &i);
-#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
- int* pi = nullptr;
- CHECK_THROWS_AS(not_null<decltype(pi)>(pi), fail_fast);
-#endif
+ not_null<std::shared_ptr<int>> x(
+ std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
+
+ int* pi = nullptr;
+ CHECK_THROWS_AS(not_null<decltype(pi)>(pi), fail_fast);
+ }
+
+ {
+ // from pointer to local
+ int t = 42;
+
+ not_null<int*> x = &t;
+ helper(&t);
+ helper_const(&t);
+
+ CHECK(*x == 42);
+ }
+
+ {
+ // from raw pointer
+ // from not_null pointer
+
+ int t = 42;
+ int* p = &t;
+
+ not_null<int*> x = p;
+ helper(p);
+ helper_const(p);
+ helper(x);
+ helper_const(x);
+
+ CHECK(*x == 42);
+ }
+
+ {
+ // from raw const pointer
+ // from not_null const pointer
+
+ int t = 42;
+ const int* cp = &t;
+
+ not_null<const int*> x = cp;
+ helper_const(cp);
+ helper_const(x);
+
+ CHECK(*x == 42);
+ }
+
+ {
+ // from not_null const pointer, using auto
+ int t = 42;
+ const int* cp = &t;
+
+ auto x = not_null<const int*>{cp};
+
+ CHECK(*x == 42);
+ }
+
+ {
+ // from returned pointer
+
+ CHECK_THROWS_AS(helper(return_pointer()), fail_fast);
+ CHECK_THROWS_AS(helper_const(return_pointer()), fail_fast);
+ }
}
-template<typename T>
+template <typename T>
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
void ostream_helper(T v)
{
@@ -193,7 +251,7 @@ TEST_CASE("TestNotNullostream")
{
ostream_helper<int>(17);
ostream_helper<float>(21.5f);
- ostream_helper<double>(3.4566e-7f);
+ ostream_helper<double>(3.4566e-7);
ostream_helper<char>('c');
ostream_helper<uint16_t>(0x0123u);
ostream_helper<const char*>("cstring");
@@ -474,5 +532,5 @@ TEST_CASE("TestMakeNotNull")
#endif
}
-static_assert(std::is_nothrow_move_constructible<not_null<void *>>::value, "not_null must be no-throw move constructible");
-
+static_assert(std::is_nothrow_move_constructible<not_null<void*>>::value,
+ "not_null must be no-throw move constructible");
diff --git a/tests/sloppy_notnull_tests.cpp b/tests/sloppy_notnull_tests.cpp
deleted file mode 100644
index 51983f5..0000000
--- a/tests/sloppy_notnull_tests.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
-//
-// This code is licensed under the MIT License (MIT).
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef _MSC_VER
-// blanket turn off warnings from CppCoreCheck from catch
-// so people aren't annoyed by them when running the tool.
-#pragma warning(disable : 26440 26426) // from catch
-
-// Fix VS2015 build breaks in Release
-#pragma warning(disable : 4702) // unreachable code
-#endif
-
-#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
-
-#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
-#include <samples/gsl_transition> // for sloppy_not_null
-
-namespace gsl
-{
-struct fail_fast;
-} // namespace gsl
-
-using namespace gsl;
-using namespace gsl_helpers;
-
-GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
-bool helper(not_null<int*> p) { return *p == 12; }
-GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
-bool helper_const(not_null<const int*> p) { return *p == 12; }
-
-GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
-bool sloppy_helper(sloppy_not_null<int*> p) { return *p == 12; }
-GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
-bool sloppy_helper_const(sloppy_not_null<const int*> p) { return *p == 12; }
-
-TEST_CASE("TestSloppyNotNull")
-{
- {
- // raw ptr <-> sloppy_not_null
- int x = 42;
-
- const sloppy_not_null<int*> snn = &x;
-
- sloppy_helper(&x);
- sloppy_helper_const(&x);
-
- CHECK(*snn == 42);
- }
-
- {
- // sloppy_not_null -> sloppy_not_null
- int x = 42;
-
- sloppy_not_null<int*> snn1{&x};
- const sloppy_not_null<int*> snn2{&x};
-
- sloppy_helper(snn1);
- sloppy_helper_const(snn1);
-
- CHECK(snn1 == snn2);
- }
-
- {
- // sloppy_not_null -> not_null
- int x = 42;
-
- sloppy_not_null<int*> snn{&x};
-
- const not_null<int*> nn1 = snn;
- const not_null<int*> nn2{snn};
-
- helper(snn);
- helper_const(snn);
-
- CHECK(snn == nn1);
- CHECK(snn == nn2);
- }
-
- {
- // not_null -> sloppy_not_null
- int x = 42;
-
- not_null<int*> nn{&x};
-
- const sloppy_not_null<int*> snn1{nn};
- const sloppy_not_null<int*> snn2 = nn;
-
- sloppy_helper(nn);
- sloppy_helper_const(nn);
-
- CHECK(snn1 == nn);
- CHECK(snn2 == nn);
-
- std::hash<sloppy_not_null<int*>> hash_snn;
- std::hash<not_null<int*>> hash_nn;
-
- CHECK(hash_nn(snn1) == hash_nn(nn));
- CHECK(hash_snn(snn1) == hash_nn(nn));
- CHECK(hash_nn(snn1) == hash_nn(snn2));
- CHECK(hash_snn(snn1) == hash_snn(nn));
- }
-
-#ifdef CONFIRM_COMPILATION_ERRORS
- {
- sloppy_not_null<int*> p{nullptr};
- }
-#endif
-}
-
-static_assert(std::is_nothrow_move_constructible<sloppy_not_null<void*>>::value,
- "sloppy_not_null must be no-throw move constructible");
diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp
index 07a59c8..d22dc08 100644
--- a/tests/span_tests.cpp
+++ b/tests/span_tests.cpp
@@ -37,9 +37,10 @@
#include <type_traits> // for integral_constant<>::value, is_default_co...
#include <vector> // for vector
-namespace gsl {
+namespace gsl
+{
struct fail_fast;
-} // namespace gsl
+} // namespace gsl
using namespace std;
using namespace gsl;
@@ -54,9 +55,12 @@ struct DerivedClass : BaseClass
};
struct AddressOverloaded
{
+#if (__cplusplus > 201402L)
+ [[maybe_unused]]
+#endif
AddressOverloaded operator&() const { return {}; }
};
-}
+} // namespace
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("default_constructor")
@@ -452,7 +456,13 @@ TEST_CASE("from_std_array_constructor")
CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()));
}
- std::array<AddressOverloaded, 4> ao_arr{};
+ {
+ std::array<int, 0> empty_arr{};
+ span<int> s{empty_arr};
+ CHECK((s.size() == 0 && s.empty()));
+ }
+
+ std::array<AddressOverloaded, 4> ao_arr{};
{
span<AddressOverloaded, 4> fs{ao_arr};
@@ -500,15 +510,16 @@ TEST_CASE("from_std_array_constructor")
CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()));
}
- // This test checks for the bug found in gcc 6.1, 6.2, 6.3, 7.1, 7.2, 7.3 - issue #590
+ // This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590
{
span<int> s1 = make_span(arr);
static span<int> s2;
s2 = s1;
- #if __GNUC__ == 6 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
- // Known to be broken in gcc 6.4 with optimizations
+ #if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
+ __GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
+ // Known to be broken in gcc 6.4 and 6.5 with optimizations
// Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116
CHECK(s1.size() == 4);
CHECK(s2.size() == 0);
diff --git a/tests/strict_notnull_tests.cpp b/tests/strict_notnull_tests.cpp
new file mode 100644
index 0000000..055afec
--- /dev/null
+++ b/tests/strict_notnull_tests.cpp
@@ -0,0 +1,193 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef _MSC_VER
+// blanket turn off warnings from CppCoreCheck from catch
+// so people aren't annoyed by them when running the tool.
+#pragma warning(disable : 26440 26426) // from catch
+
+// Fix VS2015 build breaks in Release
+#pragma warning(disable : 4702) // unreachable code
+#endif
+
+#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
+#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
+
+namespace gsl
+{
+struct fail_fast;
+} // namespace gsl
+
+using namespace gsl;
+
+GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
+bool helper(not_null<int*> p) { return *p == 12; }
+GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
+bool helper_const(not_null<const int*> p) { return *p == 12; }
+
+GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
+bool strict_helper(strict_not_null<int*> p) { return *p == 12; }
+GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
+bool strict_helper_const(strict_not_null<const int*> p) { return *p == 12; }
+
+int* return_pointer() { return nullptr; }
+const int* return_pointer_const() { return nullptr; }
+
+GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
+TEST_CASE("TestStrictNotNull")
+{
+ {
+ // raw ptr <-> strict_not_null
+ int x = 42;
+
+#ifdef CONFIRM_COMPILATION_ERRORS
+ strict_not_null<int*> snn = &x;
+ strict_helper(&x);
+ strict_helper_const(&x);
+ strict_helper(return_pointer());
+ strict_helper_const(return_pointer_const());
+#endif
+
+ const strict_not_null<int*> snn1{&x};
+
+ helper(snn1);
+ helper_const(snn1);
+
+ CHECK(*snn1 == 42);
+ }
+
+ {
+ // strict_not_null -> strict_not_null
+ int x = 42;
+
+ strict_not_null<int*> snn1{&x};
+ const strict_not_null<int*> snn2{&x};
+
+ strict_helper(snn1);
+ strict_helper_const(snn1);
+ strict_helper_const(snn2);
+
+ CHECK(snn1 == snn2);
+ }
+
+ {
+ // strict_not_null -> not_null
+ int x = 42;
+
+ strict_not_null<int*> snn{&x};
+
+ const not_null<int*> nn1 = snn;
+ const not_null<int*> nn2{snn};
+
+ helper(snn);
+ helper_const(snn);
+
+ CHECK(snn == nn1);
+ CHECK(snn == nn2);
+ }
+
+ {
+ // not_null -> strict_not_null
+ int x = 42;
+
+ not_null<int*> nn{&x};
+
+ const strict_not_null<int*> snn1{nn};
+ const strict_not_null<int*> snn2{nn};
+
+ strict_helper(nn);
+ strict_helper_const(nn);
+
+ CHECK(snn1 == nn);
+ CHECK(snn2 == nn);
+
+ std::hash<strict_not_null<int*>> hash_snn;
+ std::hash<not_null<int*>> hash_nn;
+
+ CHECK(hash_nn(snn1) == hash_nn(nn));
+ CHECK(hash_snn(snn1) == hash_nn(nn));
+ CHECK(hash_nn(snn1) == hash_nn(snn2));
+ CHECK(hash_snn(snn1) == hash_snn(nn));
+ }
+
+#ifdef CONFIRM_COMPILATION_ERRORS
+ {
+ strict_not_null<int*> p{nullptr};
+ }
+#endif
+}
+
+#if defined(__cplusplus) && (__cplusplus >= 201703L)
+
+GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
+TEST_CASE("TestStrictNotNullConstructorTypeDeduction")
+{
+ {
+ int i = 42;
+
+ strict_not_null x{&i};
+ helper(strict_not_null{&i});
+ helper_const(strict_not_null{&i});
+
+ CHECK(*x == 42);
+ }
+
+ {
+ int i = 42;
+ int* p = &i;
+
+ strict_not_null x{p};
+ helper(strict_not_null{p});
+ helper_const(strict_not_null{p});
+
+ CHECK(*x == 42);
+ }
+
+ {
+ auto workaround_macro = []() {
+ int* p1 = nullptr;
+ const strict_not_null x{p1};
+ };
+ CHECK_THROWS_AS(workaround_macro(), fail_fast);
+ }
+
+ {
+ auto workaround_macro = []() {
+ const int* p1 = nullptr;
+ const strict_not_null x{p1};
+ };
+ CHECK_THROWS_AS(workaround_macro(), fail_fast);
+ }
+
+ {
+ int* p = nullptr;
+
+ CHECK_THROWS_AS(helper(strict_not_null{p}), fail_fast);
+ CHECK_THROWS_AS(helper_const(strict_not_null{p}), fail_fast);
+ }
+
+#ifdef CONFIRM_COMPILATION_ERRORS
+ {
+ strict_not_null x{nullptr};
+ helper(strict_not_null{nullptr});
+ helper_const(strict_not_null{nullptr});
+ }
+#endif
+}
+#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
+
+static_assert(std::is_nothrow_move_constructible<strict_not_null<void*>>::value,
+ "strict_not_null must be no-throw move constructible");
diff --git a/tests/strided_span_tests.cpp b/tests/strided_span_tests.cpp
index 2310f5b..1563d90 100644
--- a/tests/strided_span_tests.cpp
+++ b/tests/strided_span_tests.cpp
@@ -117,7 +117,7 @@ TEST_CASE("strided_span_constructors")
CHECK(sav.bounds().strides() == multi_span_index<1>{1});
CHECK(sav[1] == 2);
-#if _MSC_VER > 1800
+#if defined(_MSC_VER) && _MSC_VER > 1800
// strided_span<const int, 1> sav_c{ {src}, {2, 1} };
strided_span<const int, 1> sav_c{multi_span<const int>{src},
strided_bounds<1>{2, 1}};
@@ -129,7 +129,7 @@ TEST_CASE("strided_span_constructors")
CHECK(sav_c.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_c[1] == 2);
-#if _MSC_VER > 1800
+#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<volatile int, 1> sav_v{src, {2, 1}};
#else
strided_span<volatile int, 1> sav_v{multi_span<volatile int>{src},
@@ -139,7 +139,7 @@ TEST_CASE("strided_span_constructors")
CHECK(sav_v.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_v[1] == 2);
-#if _MSC_VER > 1800
+#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
#else
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
@@ -159,7 +159,7 @@ TEST_CASE("strided_span_constructors")
CHECK(sav_c.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_c[1] == 2);
-#if _MSC_VER > 1800
+#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
#else
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
@@ -180,7 +180,7 @@ TEST_CASE("strided_span_constructors")
CHECK(sav_v.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_v[1] == 2);
-#if _MSC_VER > 1800
+#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
#else
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
@@ -598,7 +598,7 @@ void iterate_every_other_element(multi_span<int, dynamic_range> av)
// pick every other element
auto length = av.size() / 2;
-#if _MSC_VER > 1800
+#if defined(_MSC_VER) && _MSC_VER > 1800
auto bounds = strided_bounds<1>({length}, {2});
#else
auto bounds = strided_bounds<1>(multi_span_index<1>{length}, multi_span_index<1>{2});
diff --git a/tests/test.cpp b/tests/test.cpp
index dbdebb6..47daf5c 100644
--- a/tests/test.cpp
+++ b/tests/test.cpp
@@ -20,7 +20,8 @@
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
-#pragma warning(disable : 26401 26409 26415 26418 26426 26429 26432 26433 26434 26435 26436 26439 26440 26443 26444 26446 26447 26451 26460 26461 26466 26472 26481 26482 26485 26492 26493 26494 26495 26496 26497) // from catch
+#include <CodeAnalysis/Warnings.h>
+#pragma warning(disable : ALL_CODE_ANALYSIS_WARNINGS) // from catch
#endif // _MSC_VER
#include <catch/catch.hpp>
diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp
index 05f8d0f..3d54ce6 100644
--- a/tests/utils_tests.cpp
+++ b/tests/utils_tests.cpp
@@ -80,7 +80,7 @@ TEST_CASE("finally_function_with_bind")
CHECK(i == 1);
}
-int j = 0;
+static int j = 0;
void g() { j += 1; }
TEST_CASE("finally_function_ptr")
{
@@ -126,4 +126,8 @@ TEST_CASE("narrow")
n = -42;
CHECK_THROWS_AS(narrow<unsigned>(n), narrowing_error);
+
+#if GSL_CONSTEXPR_NARROW
+ static_assert(narrow<char>(120) == 120, "Fix GSL_CONSTEXPR_NARROW");
+#endif
}