gtest migration

This commit is contained in:
Jordan Maples [MSFT] 2019-12-03 14:32:25 -08:00
parent 7e99e76c97
commit 2b10729386
17 changed files with 3453 additions and 3588 deletions

View File

@ -50,19 +50,6 @@
#endif
//
// There are three configuration options for this GSL implementation's behavior
// when pre/post conditions on the GSL types are violated:
//
// 1. GSL_TERMINATE_ON_CONTRACT_VIOLATION: std::terminate will be called (default)
// 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown
// 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens
//
#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) || defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) || \
defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION
#endif
#define GSL_STRINGIFY_DETAIL(x) #x
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
@ -94,10 +81,6 @@
namespace gsl
{
struct fail_fast : public std::logic_error
{
explicit fail_fast(char const* const message) : std::logic_error(message) {}
};
namespace details
{
@ -128,7 +111,6 @@ namespace details
#endif
}
#if defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
template <typename Exception>
[[noreturn]] void throw_exception(Exception&&) noexcept
@ -136,37 +118,14 @@ namespace details
gsl::details::terminate();
}
#else
template <typename Exception>
[[noreturn]] void throw_exception(Exception&& exception)
{
throw std::forward<Exception>(exception);
}
#endif // GSL_TERMINATE_ON_CONTRACT_VIOLATION
} // namespace details
} // namespace gsl
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
#define GSL_CONTRACT_CHECK(type, cond) \
(GSL_LIKELY(cond) ? static_cast<void>(0) \
: gsl::details::throw_exception(gsl::fail_fast( \
"GSL: " type " failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__))))
#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
#define GSL_CONTRACT_CHECK(type, cond) \
(GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate())
#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
#define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond)
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
#define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond)
#define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond)

View File

@ -5,27 +5,33 @@ project(GSLTests CXX)
# will make visual studio generated project group files
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
list(APPEND CATCH_CMAKE_ARGS
"-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/external"
"-DNO_SELFTEST=true"
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download
)
if(GIT_FOUND)
# add catch
ExternalProject_Add(
catch
PREFIX ${CMAKE_BINARY_DIR}/catch
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.0.1
CMAKE_ARGS ${CATCH_CMAKE_ARGS}
LOG_DOWNLOAD 1
UPDATE_DISCONNECTED 1
)
else()
# assume catch is installed in a system directory
add_custom_target(catch)
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download
)
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
add_subdirectory(
${CMAKE_CURRENT_BINARY_DIR}/googletest-src
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL
)
if (MSVC AND (GSL_CXX_STANDARD EQUAL 17))
set(GSL_CPLUSPLUS_OPT -Zc:__cplusplus -permissive-)
endif()
@ -78,37 +84,23 @@ else()
)
endif(MSVC)
# for tests to find the catch header
target_include_directories(gsl_tests_config INTERFACE
${CMAKE_BINARY_DIR}/external/include
# for tests to find the gtest header
target_include_directories(gsl_tests_config SYSTEM INTERFACE
googletest/googletest/include
)
# set definitions for tests
target_compile_definitions(gsl_tests_config INTERFACE
GSL_THROW_ON_CONTRACT_VIOLATION
)
# create the main executable for each test. this reduces the compile time
# of each test by pre-compiling catch.
add_library(test_catch STATIC test.cpp)
target_link_libraries(test_catch
GSL
gsl_tests_config
)
add_dependencies(test_catch catch)
set_property(TARGET test_catch PROPERTY FOLDER "GSL_tests")
set_property(TARGET PROPERTY FOLDER "GSL_tests")
function(add_gsl_test name)
add_executable(${name} ${name}.cpp)
target_link_libraries(${name}
GSL
test_catch
gsl_tests_config
gtest_main
)
add_dependencies(${name} catch)
add_test(
${name}
${name}
${name}
${name}
)
# group all tests under GSL_tests
set_property(TARGET ${name} PROPERTY FOLDER "GSL_tests")
@ -141,9 +133,6 @@ endforeach(flag_var)
# please try to keep entries ordered =)
add_library(gsl_tests_config_noexcept INTERFACE)
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
@ -184,16 +173,12 @@ else()
)
endif(MSVC)
# set definitions for tests
target_compile_definitions(gsl_tests_config_noexcept INTERFACE
GSL_TERMINATE_ON_CONTRACT_VIOLATION
)
function(add_gsl_test_noexcept name)
add_executable(${name} ${name}.cpp)
target_link_libraries(${name}
GSL
gsl_tests_config_noexcept
gtest_main
)
add_test(
${name}
@ -203,5 +188,5 @@ function(add_gsl_test_noexcept name)
set_property(TARGET ${name} PROPERTY FOLDER "GSL_tests_noexcept")
endfunction()
add_gsl_test_noexcept(no_exception_throw_tests)
add_gsl_test_noexcept(no_exception_ensure_tests)
# add_gsl_test_noexcept(no_exception_throw_tests)
# add_gsl_test_noexcept(no_exception_ensure_tests)

14
tests/CMakeLists.txt.in Normal file
View File

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.0.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

View File

@ -20,7 +20,7 @@
#pragma warning(disable : 26440 26426) // from catch
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHE...
#include <gtest/gtest.h>
#include <gsl/gsl_algorithm> // for copy
#include <gsl/span> // for span
@ -35,9 +35,7 @@ struct fail_fast;
using namespace std;
using namespace gsl;
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
TEST_CASE("same_type")
TEST(algorithm_tests, same_type)
{
// dynamic source and destination span
{
@ -51,8 +49,8 @@ TEST_CASE("same_type")
copy(src_span, dst_span.subspan(src_span.size()));
for (std::size_t i = 0; i < src.size(); ++i) {
CHECK(dst[i] == src[i]);
CHECK(dst[i + src.size()] == src[i]);
EXPECT_EQ(dst[i], src[i]);
EXPECT_EQ(dst[i + src.size()], src[i]);
}
}
@ -68,8 +66,8 @@ TEST_CASE("same_type")
copy(src_span, dst_span.subspan(src_span.size()));
for (std::size_t i = 0; i < src.size(); ++i) {
CHECK(dst[i] == src[i]);
CHECK(dst[i + src.size()] == src[i]);
EXPECT_EQ(dst[i], src[i]);
EXPECT_EQ(dst[i + src.size()], src[i]);
}
}
@ -85,8 +83,8 @@ TEST_CASE("same_type")
copy(src_span, dst_span.subspan(src_span.size()));
for (std::size_t i = 0; i < src.size(); ++i) {
CHECK(dst[i] == src[i]);
CHECK(dst[i + src.size()] == src[i]);
EXPECT_EQ(dst[i], src[i]);
EXPECT_EQ(dst[i + src.size()], src[i]);
}
}
@ -102,16 +100,13 @@ TEST_CASE("same_type")
copy(src_span, dst_span.subspan(src_span.size()));
for (std::size_t i = 0; i < src.size(); ++i) {
CHECK(dst[i] == src[i]);
CHECK(dst[i + src.size()] == src[i]);
EXPECT_EQ(dst[i], src[i]);
EXPECT_EQ(dst[i + src.size()], src[i]);
}
}
}
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
TEST_CASE("compatible_type")
TEST(algorithm_tests, compatible_type)
{
// dynamic source and destination span
{
@ -125,8 +120,8 @@ TEST_CASE("compatible_type")
copy(src_span, dst_span.subspan(src_span.size()));
for (std::size_t i = 0; i < src.size(); ++i) {
CHECK(dst[i] == src[i]);
CHECK(dst[i + src.size()] == src[i]);
EXPECT_EQ(dst[i], src[i]);
EXPECT_EQ(dst[i + src.size()], src[i]);
}
}
@ -142,8 +137,8 @@ TEST_CASE("compatible_type")
copy(src_span, dst_span.subspan(src_span.size()));
for (std::size_t i = 0; i < src.size(); ++i) {
CHECK(dst[i] == src[i]);
CHECK(dst[i + src.size()] == src[i]);
EXPECT_EQ(dst[i], src[i]);
EXPECT_EQ(dst[i + src.size()], src[i]);
}
}
@ -159,8 +154,8 @@ TEST_CASE("compatible_type")
copy(src_span, dst_span.subspan(src_span.size()));
for (std::size_t i = 0; i < src.size(); ++i) {
CHECK(dst[i] == src[i]);
CHECK(dst[i + src.size()] == src[i]);
EXPECT_EQ(dst[i], src[i]);
EXPECT_EQ(dst[i + src.size()], src[i]);
}
}
@ -176,14 +171,14 @@ TEST_CASE("compatible_type")
copy(src_span, dst_span.subspan(src_span.size()));
for (std::size_t i = 0; i < src.size(); ++i) {
CHECK(dst[i] == src[i]);
CHECK(dst[i + src.size()] == src[i]);
EXPECT_EQ(dst[i], src[i]);
EXPECT_EQ(dst[i + src.size()], src[i]);
}
}
}
#ifdef CONFIRM_COMPILATION_ERRORS
TEST_CASE("incompatible_type")
TEST(algorithm_tests, incompatible_type)
{
std::array<int, 4> src{1, 2, 3, 4};
std::array<int*, 12> dst{};
@ -201,7 +196,7 @@ TEST_CASE("incompatible_type")
}
#endif
TEST_CASE("small_destination_span")
TEST(algorithm_tests, small_destination_span)
{
std::array<int, 12> src{1, 2, 3, 4};
std::array<int, 4> dst{};
@ -211,9 +206,9 @@ TEST_CASE("small_destination_span")
const span<int> dst_span_dyn(dst);
const span<int, 4> dst_span_static(dst);
CHECK_THROWS_AS(copy(src_span_dyn, dst_span_dyn), fail_fast);
CHECK_THROWS_AS(copy(src_span_dyn, dst_span_static), fail_fast);
CHECK_THROWS_AS(copy(src_span_static, dst_span_dyn), fail_fast);
EXPECT_DEATH(copy(src_span_dyn, dst_span_dyn), ".*");
EXPECT_DEATH(copy(src_span_dyn, dst_span_static), ".*");
EXPECT_DEATH(copy(src_span_static, dst_span_dyn), ".*");
#ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static);

View File

@ -20,33 +20,37 @@
#pragma warning(disable : 26440 26426) // from catch
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHECK...
#include <gtest/gtest.h>
#include <gsl/gsl_assert> // for fail_fast (ptr only), Ensures, Expects
using namespace gsl;
namespace
{
int f(int i)
{
Expects(i > 0 && i < 10);
return i;
}
TEST_CASE("expects")
{
CHECK(f(2) == 2);
CHECK_THROWS_AS(f(10), fail_fast);
}
int g(int i)
{
i++;
Ensures(i > 0 && i < 10);
return i;
}
} // namespace
TEST_CASE("ensures")
TEST(assertion_tests, expects)
{
CHECK(g(2) == 3);
CHECK_THROWS_AS(g(9), fail_fast);
EXPECT_EQ(f(2), 2);
EXPECT_DEATH(f(10), ".*");
}
TEST(assertion_tests, ensures)
{
EXPECT_EQ(g(2), 3);
EXPECT_DEATH(g(9), ".*");
}

View File

@ -20,7 +20,7 @@
#pragma warning(disable : 26440 26426) // from catch
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK_THROW...
#include <gtest/gtest.h>
#include <gsl/gsl_util> // for at
@ -29,88 +29,70 @@
#include <initializer_list> // for initializer_list
#include <vector> // for vector
namespace gsl {
struct fail_fast;
} // namespace gsl
using gsl::fail_fast;
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
TEST_CASE("static_array")
TEST(at_tests, static_array)
{
int a[4] = {1, 2, 3, 4};
const int(&c_a)[4] = a;
for (int i = 0; i < 4; ++i) {
CHECK(&gsl::at(a, i) == &a[i]);
CHECK(&gsl::at(c_a, i) == &a[i]);
EXPECT_EQ(&gsl::at(a, i), &a[i]);
EXPECT_EQ(&gsl::at(c_a, i), &a[i]);
}
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
EXPECT_DEATH(gsl::at(a, -1), ".*");
EXPECT_DEATH(gsl::at(a, 4), ".*");
EXPECT_DEATH(gsl::at(c_a, -1), ".*");
EXPECT_DEATH(gsl::at(c_a, 4), ".*");
}
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
TEST_CASE("std_array")
TEST(at_tests, std_array)
{
std::array<int, 4> a = {1, 2, 3, 4};
const std::array<int, 4>& c_a = a;
for (int i = 0; i < 4; ++i) {
CHECK(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
CHECK(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
EXPECT_EQ(&gsl::at(a, i), &a[static_cast<std::size_t>(i)]);
EXPECT_EQ(&gsl::at(c_a, i), &a[static_cast<std::size_t>(i)]);
}
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
EXPECT_DEATH(gsl::at(a, -1), ".*");
EXPECT_DEATH(gsl::at(a, 4), ".*");
EXPECT_DEATH(gsl::at(c_a, -1), ".*");
EXPECT_DEATH(gsl::at(c_a, 4), ".*");
}
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
TEST_CASE("StdVector")
TEST(at_tests, StdVector)
{
std::vector<int> a = {1, 2, 3, 4};
const std::vector<int>& c_a = a;
for (int i = 0; i < 4; ++i) {
CHECK(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
CHECK(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
EXPECT_EQ(&gsl::at(a, i), &a[static_cast<std::size_t>(i)]);
EXPECT_EQ(&gsl::at(c_a, i), &a[static_cast<std::size_t>(i)]);
}
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
EXPECT_DEATH(gsl::at(a, -1), ".*");
EXPECT_DEATH(gsl::at(a, 4), ".*");
EXPECT_DEATH(gsl::at(c_a, -1), ".*");
EXPECT_DEATH(gsl::at(c_a, 4), ".*");
}
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
TEST_CASE("InitializerList")
TEST(at_tests, InitializerList)
{
const std::initializer_list<int> a = {1, 2, 3, 4};
for (int i = 0; i < 4; ++i) {
CHECK(gsl::at(a, i) == i + 1);
CHECK(gsl::at({1, 2, 3, 4}, i) == i + 1);
EXPECT_EQ(gsl::at(a, i), i + 1);
EXPECT_EQ(gsl::at({1, 2, 3, 4}, i), i + 1);
}
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
CHECK_THROWS_AS(gsl::at({1, 2, 3, 4}, -1), fail_fast);
CHECK_THROWS_AS(gsl::at({1, 2, 3, 4}, 4), fail_fast);
EXPECT_DEATH(gsl::at(a, -1), ".*");
EXPECT_DEATH(gsl::at(a, 4), ".*");
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, -1), ".*");
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, 4), ".*");
}
#if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
static constexpr bool test_constexpr()
{
int a1[4] = {1, 2, 3, 4};

View File

@ -26,7 +26,7 @@
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, TEST_CASE
#include <gtest/gtest.h>
#include <gsl/multi_span> // for static_bounds, static_bounds_dynamic_range_t
@ -44,8 +44,7 @@ namespace
void use(std::ptrdiff_t&) {}
}
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
TEST_CASE("basic_bounds")
TEST(bounds_tests, basic_bounds)
{
for (auto point : static_bounds<dynamic_range, 3, 4>{2}) {
for (decltype(point)::size_type j = 0;
@ -57,9 +56,7 @@ TEST_CASE("basic_bounds")
}
}
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("bounds_basic")
TEST(bounds_tests, bounds_basic)
{
static_bounds<3, 4, 5> b;
const auto a = b.slice();
@ -68,9 +65,7 @@ TEST_CASE("bounds_basic")
x.slice().slice();
}
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("arrayview_iterator")
TEST(bounds_tests, arrayview_iterator)
{
static_bounds<4, dynamic_range, 2> bounds{3};
@ -88,8 +83,7 @@ TEST_CASE("arrayview_iterator")
#endif
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("bounds_convertible")
TEST(bounds_tests, bounds_convertible)
{
static_bounds<7, 4, 2> b1;
static_bounds<7, dynamic_range, 2> b2 = b1;
@ -108,12 +102,12 @@ TEST_CASE("bounds_convertible")
static_bounds<34> b6;
b5 = static_bounds<20>();
CHECK_THROWS_AS(b6 = b5, fail_fast);
EXPECT_DEATH(b6 = b5, ".*");
b5 = static_bounds<34>();
b6 = b5;
CHECK(b5 == b6);
CHECK(b5.size() == b6.size());
EXPECT_EQ(b5, b6);
EXPECT_EQ(b5.size(), b6.size());
}
#ifdef CONFIRM_COMPILATION_ERRORS

View File

@ -20,7 +20,7 @@
#pragma warning(disable : 26440 26426) // from catch
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gtest/gtest.h>
#include <gsl/gsl_byte> // for to_byte, to_integer, byte, operator&, ope...
@ -29,104 +29,103 @@ using namespace gsl;
namespace
{
TEST_CASE("construction")
{
{
const byte b = static_cast<byte>(4);
CHECK(static_cast<unsigned char>(b) == 4);
}
GSL_SUPPRESS(es.49)
{
const byte b = byte(12);
CHECK(static_cast<unsigned char>(b) == 12);
}
{
const byte b = to_byte<12>();
CHECK(static_cast<unsigned char>(b) == 12);
}
{
const unsigned char uc = 12;
const byte b = to_byte(uc);
CHECK(static_cast<unsigned char>(b) == 12);
}
#if defined(__cplusplus) && (__cplusplus >= 201703L)
{
const byte b { 14 };
CHECK(static_cast<unsigned char>(b) == 14);
}
#endif
}
TEST_CASE("bitwise_operations")
{
const byte b = to_byte<0xFF>();
byte a = to_byte<0x00>();
CHECK((b | a) == to_byte<0xFF>());
CHECK(a == to_byte<0x00>());
a |= b;
CHECK(a == to_byte<0xFF>());
a = to_byte<0x01>();
CHECK((b & a) == to_byte<0x01>());
a &= b;
CHECK(a == to_byte<0x01>());
CHECK((b ^ a) == to_byte<0xFE>());
CHECK(a == to_byte<0x01>());
a ^= b;
CHECK(a == to_byte<0xFE>());
a = to_byte<0x01>();
CHECK(~a == to_byte<0xFE>());
a = to_byte<0xFF>();
CHECK((a << 4) == to_byte<0xF0>());
CHECK((a >> 4) == to_byte<0x0F>());
a <<= 4;
CHECK(a == to_byte<0xF0>());
a >>= 4;
CHECK(a == to_byte<0x0F>());
}
TEST_CASE("to_integer")
{
const byte b = to_byte<0x12>();
CHECK(0x12 == gsl::to_integer<char>(b));
CHECK(0x12 == gsl::to_integer<short>(b));
CHECK(0x12 == gsl::to_integer<long>(b));
CHECK(0x12 == gsl::to_integer<long long>(b));
CHECK(0x12 == gsl::to_integer<unsigned char>(b));
CHECK(0x12 == gsl::to_integer<unsigned short>(b));
CHECK(0x12 == gsl::to_integer<unsigned long>(b));
CHECK(0x12 == gsl::to_integer<unsigned long long>(b));
// CHECK(0x12 == gsl::to_integer<float>(b)); // expect compile-time error
// CHECK(0x12 == gsl::to_integer<double>(b)); // expect compile-time error
}
int modify_both(gsl::byte & b, int& i)
int modify_both(gsl::byte& b, int& i)
{
i = 10;
b = to_byte<5>();
return i;
}
GSL_SUPPRESS(type.1)
TEST_CASE("aliasing")
TEST(byte_tests, construction)
{
{
const byte b = static_cast<byte>(4);
EXPECT_TRUE(static_cast<unsigned char>(b) == 4);
}
GSL_SUPPRESS(es.49)
{
const byte b = byte(12);
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
}
{
const byte b = to_byte<12>();
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
}
{
const unsigned char uc = 12;
const byte b = to_byte(uc);
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
}
#if defined(__cplusplus) && (__cplusplus >= 201703L)
{
const byte b { 14 };
EXPECT_TRUE(static_cast<unsigned char>(b) == 14);
}
#endif
}
TEST(byte_tests, bitwise_operations)
{
const byte b = to_byte<0xFF>();
byte a = to_byte<0x00>();
EXPECT_TRUE((b | a) == to_byte<0xFF>());
EXPECT_TRUE(a == to_byte<0x00>());
a |= b;
EXPECT_TRUE(a == to_byte<0xFF>());
a = to_byte<0x01>();
EXPECT_TRUE((b & a) == to_byte<0x01>());
a &= b;
EXPECT_TRUE(a == to_byte<0x01>());
EXPECT_TRUE((b ^ a) == to_byte<0xFE>());
EXPECT_TRUE(a == to_byte<0x01>());
a ^= b;
EXPECT_TRUE(a == to_byte<0xFE>());
a = to_byte<0x01>();
EXPECT_TRUE(~a == to_byte<0xFE>());
a = to_byte<0xFF>();
EXPECT_TRUE((a << 4) == to_byte<0xF0>());
EXPECT_TRUE((a >> 4) == to_byte<0x0F>());
a <<= 4;
EXPECT_TRUE(a == to_byte<0xF0>());
a >>= 4;
EXPECT_TRUE(a == to_byte<0x0F>());
}
TEST(byte_tests, to_integer)
{
const byte b = to_byte<0x12>();
EXPECT_TRUE(0x12 == gsl::to_integer<char>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<short>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<long>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<long long>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned char>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned short>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned long>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned long long>(b));
// EXPECT_TRUE(0x12 == gsl::to_integer<float>(b)); // expect compile-time error
// EXPECT_TRUE(0x12 == gsl::to_integer<double>(b)); // expect compile-time error
}
TEST(byte_tests, aliasing)
{
int i{0};
const int res = modify_both(reinterpret_cast<byte&>(i), i);
CHECK(res == i);
EXPECT_TRUE(res == i);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,7 @@
#pragma warning(disable : 4702) // unreachable code
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gtest/gtest.h>
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
@ -135,8 +135,7 @@ 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")
TEST(notnull_tests, TestNotNullConstructors)
{
{
#ifdef CONFIRM_COMPILATION_ERRORS
@ -158,13 +157,13 @@ TEST_CASE("TestNotNullConstructors")
int i = 12;
auto rp = RefCounted<int>(&i);
not_null<int*> p(rp);
CHECK(p.get() == &i);
EXPECT_EQ(p.get(), &i);
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);
EXPECT_DEATH((not_null<decltype(pi)>(pi)), ".*");
}
{
@ -175,7 +174,7 @@ TEST_CASE("TestNotNullConstructors")
helper(&t);
helper_const(&t);
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
}
{
@ -191,7 +190,7 @@ TEST_CASE("TestNotNullConstructors")
helper(x);
helper_const(x);
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
}
{
@ -205,7 +204,7 @@ TEST_CASE("TestNotNullConstructors")
helper_const(cp);
helper_const(x);
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
}
{
@ -215,19 +214,18 @@ TEST_CASE("TestNotNullConstructors")
auto x = not_null<const int*>{cp};
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
}
{
// from returned pointer
CHECK_THROWS_AS(helper(return_pointer()), fail_fast);
CHECK_THROWS_AS(helper_const(return_pointer()), fail_fast);
EXPECT_DEATH(helper(return_pointer()), ".*");
EXPECT_DEATH(helper_const(return_pointer()), ".*");
}
}
template <typename T>
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
void ostream_helper(T v)
{
not_null<T*> p(&v);
@ -236,18 +234,18 @@ void ostream_helper(T v)
std::ostringstream ref;
os << static_cast<void*>(p);
ref << static_cast<void*>(&v);
CHECK(os.str() == ref.str());
EXPECT_EQ(os.str(), ref.str());
}
{
std::ostringstream os;
std::ostringstream ref;
os << *p;
ref << v;
CHECK(os.str() == ref.str());
EXPECT_EQ(os.str(), ref.str());
}
}
TEST_CASE("TestNotNullostream")
TEST(notnull_tests, TestNotNullostream)
{
ostream_helper<int>(17);
ostream_helper<float>(21.5f);
@ -258,9 +256,7 @@ TEST_CASE("TestNotNullostream")
ostream_helper<std::string>("string");
}
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("TestNotNullCasting")
TEST(notnull_tests, TestNotNullCasting)
{
MyBase base;
MyDerived derived;
@ -270,7 +266,7 @@ TEST_CASE("TestNotNullCasting")
not_null<MyDerived*> p{&derived};
not_null<MyBase*> q(&base);
q = p; // allowed with heterogeneous copy ctor
CHECK(q == p);
EXPECT_EQ(q, p);
#ifdef CONFIRM_COMPILATION_ERRORS
q = u; // no viable conversion possible between MyBase* and Unrelated*
@ -280,20 +276,20 @@ TEST_CASE("TestNotNullCasting")
not_null<Unrelated*> s = reinterpret_cast<Unrelated*>(p);
#endif
not_null<Unrelated*> t(reinterpret_cast<Unrelated*>(p.get()));
CHECK(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get()));
EXPECT_EQ(reinterpret_cast<void*>(p.get()), reinterpret_cast<void*>(t.get()));
}
TEST_CASE("TestNotNullAssignment")
TEST(notnull_tests, TestNotNullAssignment)
{
int i = 12;
not_null<int*> p(&i);
CHECK(helper(p));
EXPECT_TRUE(helper(p));
int* q = nullptr;
CHECK_THROWS_AS(p = not_null<int*>(q), fail_fast);
EXPECT_DEATH(p = not_null<int*>(q), ".*");
}
TEST_CASE("TestNotNullRawPointerComparison")
TEST(notnull_tests, TestNotNullRawPointerComparison)
{
int ints[2] = {42, 43};
int* p1 = &ints[0];
@ -302,34 +298,33 @@ TEST_CASE("TestNotNullRawPointerComparison")
using NotNull1 = not_null<decltype(p1)>;
using NotNull2 = not_null<decltype(p2)>;
CHECK((NotNull1(p1) == NotNull1(p1)) == true);
CHECK((NotNull1(p1) == NotNull2(p2)) == false);
EXPECT_EQ((NotNull1(p1) == NotNull1(p1)), true);
EXPECT_EQ((NotNull1(p1) == NotNull2(p2)), false);
CHECK((NotNull1(p1) != NotNull1(p1)) == false);
CHECK((NotNull1(p1) != NotNull2(p2)) == true);
EXPECT_EQ((NotNull1(p1) != NotNull1(p1)), false);
EXPECT_EQ((NotNull1(p1) != NotNull2(p2)), true);
CHECK((NotNull1(p1) < NotNull1(p1)) == false);
CHECK((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
CHECK((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
EXPECT_EQ((NotNull1(p1) < NotNull1(p1)), false);
EXPECT_EQ((NotNull1(p1) < NotNull2(p2)), (p1 < p2));
EXPECT_EQ((NotNull2(p2) < NotNull1(p1)), (p2 < p1));
CHECK((NotNull1(p1) > NotNull1(p1)) == false);
CHECK((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
CHECK((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
EXPECT_EQ((NotNull1(p1) > NotNull1(p1)), false);
EXPECT_EQ((NotNull1(p1) > NotNull2(p2)), (p1 > p2));
EXPECT_EQ((NotNull2(p2) > NotNull1(p1)), (p2 > p1));
CHECK((NotNull1(p1) <= NotNull1(p1)) == true);
CHECK((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
CHECK((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
EXPECT_EQ((NotNull1(p1) <= NotNull1(p1)), true);
EXPECT_EQ((NotNull1(p1) <= NotNull2(p2)), (p1 <= p2));
EXPECT_EQ((NotNull2(p2) <= NotNull1(p1)), (p2 <= p1));
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("TestNotNullDereferenceOperator")
TEST(notnull_tests, TestNotNullDereferenceOperator)
{
{
auto sp1 = std::make_shared<NonCopyableNonMovable>();
using NotNullSp1 = not_null<decltype(sp1)>;
CHECK(typeid(*sp1) == typeid(*NotNullSp1(sp1)));
CHECK(std::addressof(*NotNullSp1(sp1)) == std::addressof(*sp1));
EXPECT_EQ(typeid(*sp1), typeid(*NotNullSp1(sp1)));
EXPECT_EQ(std::addressof(*NotNullSp1(sp1)), std::addressof(*sp1));
}
{
@ -337,22 +332,22 @@ TEST_CASE("TestNotNullDereferenceOperator")
CustomPtr<int> p1(&ints[0]);
using NotNull1 = not_null<decltype(p1)>;
CHECK(typeid(*NotNull1(p1)) == typeid(*p1));
CHECK(*NotNull1(p1) == 42);
EXPECT_EQ(typeid(*NotNull1(p1)), typeid(*p1));
EXPECT_EQ(*NotNull1(p1), 42);
*NotNull1(p1) = 43;
CHECK(ints[0] == 43);
EXPECT_EQ(ints[0], 43);
}
{
int v = 42;
gsl::not_null<int*> p(&v);
CHECK(typeid(*p) == typeid(*(&v)));
EXPECT_EQ(typeid(*p), typeid(*(&v)));
*p = 43;
CHECK(v == 43);
EXPECT_EQ(v, 43);
}
}
TEST_CASE("TestNotNullSharedPtrComparison")
TEST(notnull_tests, TestNotNullSharedPtrComparison)
{
auto sp1 = std::make_shared<int>(42);
auto sp2 = std::make_shared<const int>(43);
@ -360,31 +355,30 @@ TEST_CASE("TestNotNullSharedPtrComparison")
using NotNullSp1 = not_null<decltype(sp1)>;
using NotNullSp2 = not_null<decltype(sp2)>;
CHECK((NotNullSp1(sp1) == NotNullSp1(sp1)) == true);
CHECK((NotNullSp1(sp1) == NotNullSp2(sp2)) == false);
EXPECT_EQ((NotNullSp1(sp1) == NotNullSp1(sp1)), true);
EXPECT_EQ((NotNullSp1(sp1) == NotNullSp2(sp2)), false);
CHECK((NotNullSp1(sp1) != NotNullSp1(sp1)) == false);
CHECK((NotNullSp1(sp1) != NotNullSp2(sp2)) == true);
EXPECT_EQ((NotNullSp1(sp1) != NotNullSp1(sp1)), false);
EXPECT_EQ((NotNullSp1(sp1) != NotNullSp2(sp2)), true);
CHECK((NotNullSp1(sp1) < NotNullSp1(sp1)) == false);
CHECK((NotNullSp1(sp1) < NotNullSp2(sp2)) == (sp1 < sp2));
CHECK((NotNullSp2(sp2) < NotNullSp1(sp1)) == (sp2 < sp1));
EXPECT_EQ((NotNullSp1(sp1) < NotNullSp1(sp1)), false);
EXPECT_EQ((NotNullSp1(sp1) < NotNullSp2(sp2)), (sp1 < sp2));
EXPECT_EQ((NotNullSp2(sp2) < NotNullSp1(sp1)), (sp2 < sp1));
CHECK((NotNullSp1(sp1) > NotNullSp1(sp1)) == false);
CHECK((NotNullSp1(sp1) > NotNullSp2(sp2)) == (sp1 > sp2));
CHECK((NotNullSp2(sp2) > NotNullSp1(sp1)) == (sp2 > sp1));
EXPECT_EQ((NotNullSp1(sp1) > NotNullSp1(sp1)), false);
EXPECT_EQ((NotNullSp1(sp1) > NotNullSp2(sp2)), (sp1 > sp2));
EXPECT_EQ((NotNullSp2(sp2) > NotNullSp1(sp1)), (sp2 > sp1));
CHECK((NotNullSp1(sp1) <= NotNullSp1(sp1)) == true);
CHECK((NotNullSp1(sp1) <= NotNullSp2(sp2)) == (sp1 <= sp2));
CHECK((NotNullSp2(sp2) <= NotNullSp1(sp1)) == (sp2 <= sp1));
EXPECT_EQ((NotNullSp1(sp1) <= NotNullSp1(sp1)), true);
EXPECT_EQ((NotNullSp1(sp1) <= NotNullSp2(sp2)), (sp1 <= sp2));
EXPECT_EQ((NotNullSp2(sp2) <= NotNullSp1(sp1)), (sp2 <= sp1));
CHECK((NotNullSp1(sp1) >= NotNullSp1(sp1)) == true);
CHECK((NotNullSp1(sp1) >= NotNullSp2(sp2)) == (sp1 >= sp2));
CHECK((NotNullSp2(sp2) >= NotNullSp1(sp1)) == (sp2 >= sp1));
EXPECT_EQ((NotNullSp1(sp1) >= NotNullSp1(sp1)), true);
EXPECT_EQ((NotNullSp1(sp1) >= NotNullSp2(sp2)), (sp1 >= sp2));
EXPECT_EQ((NotNullSp2(sp2) >= NotNullSp1(sp1)), (sp2 >= sp1));
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("TestNotNullCustomPtrComparison")
TEST(notnull_tests, TestNotNullCustomPtrComparison)
{
int ints[2] = {42, 43};
CustomPtr<int> p1(&ints[0]);
@ -393,33 +387,32 @@ TEST_CASE("TestNotNullCustomPtrComparison")
using NotNull1 = not_null<decltype(p1)>;
using NotNull2 = not_null<decltype(p2)>;
CHECK((NotNull1(p1) == NotNull1(p1)) == "true");
CHECK((NotNull1(p1) == NotNull2(p2)) == "false");
EXPECT_EQ((NotNull1(p1) == NotNull1(p1)), "true");
EXPECT_EQ((NotNull1(p1) == NotNull2(p2)), "false");
CHECK((NotNull1(p1) != NotNull1(p1)) == "false");
CHECK((NotNull1(p1) != NotNull2(p2)) == "true");
EXPECT_EQ((NotNull1(p1) != NotNull1(p1)), "false");
EXPECT_EQ((NotNull1(p1) != NotNull2(p2)), "true");
CHECK((NotNull1(p1) < NotNull1(p1)) == "false");
CHECK((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
CHECK((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
EXPECT_EQ((NotNull1(p1) < NotNull1(p1)), "false");
EXPECT_EQ((NotNull1(p1) < NotNull2(p2)), (p1 < p2));
EXPECT_EQ((NotNull2(p2) < NotNull1(p1)), (p2 < p1));
CHECK((NotNull1(p1) > NotNull1(p1)) == "false");
CHECK((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
CHECK((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
EXPECT_EQ((NotNull1(p1) > NotNull1(p1)), "false");
EXPECT_EQ((NotNull1(p1) > NotNull2(p2)), (p1 > p2));
EXPECT_EQ((NotNull2(p2) > NotNull1(p1)), (p2 > p1));
CHECK((NotNull1(p1) <= NotNull1(p1)) == "true");
CHECK((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
CHECK((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
EXPECT_EQ((NotNull1(p1) <= NotNull1(p1)), "true");
EXPECT_EQ((NotNull1(p1) <= NotNull2(p2)), (p1 <= p2));
EXPECT_EQ((NotNull2(p2) <= NotNull1(p1)), (p2 <= p1));
CHECK((NotNull1(p1) >= NotNull1(p1)) == "true");
CHECK((NotNull1(p1) >= NotNull2(p2)) == (p1 >= p2));
CHECK((NotNull2(p2) >= NotNull1(p1)) == (p2 >= p1));
EXPECT_EQ((NotNull1(p1) >= NotNull1(p1)), "true");
EXPECT_EQ((NotNull1(p1) >= NotNull2(p2)), (p1 >= p2));
EXPECT_EQ((NotNull2(p2) >= NotNull1(p1)), (p2 >= p1));
}
#if defined(__cplusplus) && (__cplusplus >= 201703L)
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("TestNotNullConstructorTypeDeduction")
TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
{
{
int i = 42;
@ -428,7 +421,7 @@ TEST_CASE("TestNotNullConstructorTypeDeduction")
helper(not_null{&i});
helper_const(not_null{&i});
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
}
{
@ -439,7 +432,7 @@ TEST_CASE("TestNotNullConstructorTypeDeduction")
helper(not_null{p});
helper_const(not_null{p});
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
}
{
@ -447,7 +440,7 @@ TEST_CASE("TestNotNullConstructorTypeDeduction")
int* p1 = nullptr;
const not_null x{p1};
};
CHECK_THROWS_AS(workaround_macro(), fail_fast);
EXPECT_DEATH(workaround_macro(), ".*");
}
{
@ -455,14 +448,14 @@ TEST_CASE("TestNotNullConstructorTypeDeduction")
const int* p1 = nullptr;
const not_null x{p1};
};
CHECK_THROWS_AS(workaround_macro(), fail_fast);
EXPECT_DEATH(workaround_macro(), ".*");
}
{
int* p = nullptr;
CHECK_THROWS_AS(helper(not_null{p}), fail_fast);
CHECK_THROWS_AS(helper_const(not_null{p}), fail_fast);
EXPECT_DEATH(helper(not_null{p}), ".*");
EXPECT_DEATH(helper_const(not_null{p}), ".*");
}
#ifdef CONFIRM_COMPILATION_ERRORS
@ -475,7 +468,7 @@ TEST_CASE("TestNotNullConstructorTypeDeduction")
}
#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
TEST_CASE("TestMakeNotNull")
TEST(notnull_tests, TestMakeNotNull)
{
{
int i = 42;
@ -484,7 +477,7 @@ TEST_CASE("TestMakeNotNull")
helper(make_not_null(&i));
helper_const(make_not_null(&i));
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
}
{
@ -495,39 +488,39 @@ TEST_CASE("TestMakeNotNull")
helper(make_not_null(p));
helper_const(make_not_null(p));
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
}
{
const auto workaround_macro = []() {
int* p1 = nullptr;
const auto x = make_not_null(p1);
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
};
CHECK_THROWS_AS(workaround_macro(), fail_fast);
EXPECT_DEATH(workaround_macro(), ".*");
}
{
const auto workaround_macro = []() {
const int* p1 = nullptr;
const auto x = make_not_null(p1);
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
};
CHECK_THROWS_AS(workaround_macro(), fail_fast);
EXPECT_DEATH(workaround_macro(), ".*");
}
{
int* p = nullptr;
CHECK_THROWS_AS(helper(make_not_null(p)), fail_fast);
CHECK_THROWS_AS(helper_const(make_not_null(p)), fail_fast);
EXPECT_DEATH(helper(make_not_null(p)), ".*");
EXPECT_DEATH(helper_const(make_not_null(p)), ".*");
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
CHECK_THROWS_AS(make_not_null(nullptr), fail_fast);
CHECK_THROWS_AS(helper(make_not_null(nullptr)), fail_fast);
CHECK_THROWS_AS(helper_const(make_not_null(nullptr)), fail_fast);
EXPECT_DEATH(make_not_null(nullptr), ".*");
EXPECT_DEATH(helper(make_not_null(nullptr)), ".*");
EXPECT_DEATH(helper_const(make_not_null(nullptr)), ".*");
}
#endif
}

View File

@ -21,7 +21,7 @@
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gtest/gtest.h>
#include <gsl/pointers> // for owner
@ -30,19 +30,16 @@ using namespace gsl;
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute
void f(int* i) { *i += 1; }
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute // TODO: false positive
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
TEST_CASE("basic_test")
TEST(owner_tests, basic_test)
{
owner<int*> p = new int(120);
CHECK(*p == 120);
EXPECT_EQ(*p, 120);
f(p);
CHECK(*p == 121);
EXPECT_EQ(*p, 121);
delete p;
}
TEST_CASE("check_pointer_constraint")
TEST(owner_tests, check_pointer_constraint)
{
#ifdef CONFIRM_COMPILATION_ERRORS
{

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,7 @@
#pragma warning(disable : 4702) // unreachable code
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gtest/gtest.h>
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
namespace gsl
@ -35,19 +35,20 @@ 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")
TEST(strict_notnull_tests, TestStrictNotNull)
{
{
// raw ptr <-> strict_not_null
@ -66,7 +67,7 @@ TEST_CASE("TestStrictNotNull")
helper(snn1);
helper_const(snn1);
CHECK(*snn1 == 42);
EXPECT_EQ(*snn1, 42);
}
{
@ -80,7 +81,7 @@ TEST_CASE("TestStrictNotNull")
strict_helper_const(snn1);
strict_helper_const(snn2);
CHECK(snn1 == snn2);
EXPECT_EQ(snn1, snn2);
}
{
@ -95,8 +96,8 @@ TEST_CASE("TestStrictNotNull")
helper(snn);
helper_const(snn);
CHECK(snn == nn1);
CHECK(snn == nn2);
EXPECT_EQ(snn, nn1);
EXPECT_EQ(snn, nn2);
}
{
@ -111,16 +112,16 @@ TEST_CASE("TestStrictNotNull")
strict_helper(nn);
strict_helper_const(nn);
CHECK(snn1 == nn);
CHECK(snn2 == nn);
EXPECT_EQ(snn1, nn);
EXPECT_EQ(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));
EXPECT_EQ(hash_nn(snn1), hash_nn(nn));
EXPECT_EQ(hash_snn(snn1), hash_nn(nn));
EXPECT_EQ(hash_nn(snn1), hash_nn(snn2));
EXPECT_EQ(hash_snn(snn1), hash_snn(nn));
}
#ifdef CONFIRM_COMPILATION_ERRORS
@ -132,8 +133,7 @@ TEST_CASE("TestStrictNotNull")
#if defined(__cplusplus) && (__cplusplus >= 201703L)
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("TestStrictNotNullConstructorTypeDeduction")
TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
{
{
int i = 42;
@ -142,7 +142,7 @@ TEST_CASE("TestStrictNotNullConstructorTypeDeduction")
helper(strict_not_null{&i});
helper_const(strict_not_null{&i});
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
}
{
@ -153,7 +153,7 @@ TEST_CASE("TestStrictNotNullConstructorTypeDeduction")
helper(strict_not_null{p});
helper_const(strict_not_null{p});
CHECK(*x == 42);
EXPECT_EQ(*x, 42);
}
{
@ -161,7 +161,7 @@ TEST_CASE("TestStrictNotNullConstructorTypeDeduction")
int* p1 = nullptr;
const strict_not_null x{p1};
};
CHECK_THROWS_AS(workaround_macro(), fail_fast);
EXPECT_DEATH(workaround_macro(), ".*");
}
{
@ -169,14 +169,14 @@ TEST_CASE("TestStrictNotNullConstructorTypeDeduction")
const int* p1 = nullptr;
const strict_not_null x{p1};
};
CHECK_THROWS_AS(workaround_macro(), fail_fast);
EXPECT_DEATH(workaround_macro(), ".*");
}
{
int* p = nullptr;
CHECK_THROWS_AS(helper(strict_not_null{p}), fail_fast);
CHECK_THROWS_AS(helper_const(strict_not_null{p}), fail_fast);
EXPECT_DEATH(helper(strict_not_null{p}), ".*");
EXPECT_DEATH(helper_const(strict_not_null{p}), ".*");
}
#ifdef CONFIRM_COMPILATION_ERRORS

View File

@ -27,7 +27,7 @@
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHECK...
#include <gtest/gtest.h>
#include <gsl/gsl_byte> // for byte
#include <gsl/gsl_util> // for narrow_cast
@ -54,9 +54,66 @@ struct BaseClass
struct DerivedClass : BaseClass
{
};
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
void iterate_every_other_element(multi_span<int, dynamic_range> av)
{
// pick every other element
auto length = av.size() / 2;
#if defined(_MSC_VER) && _MSC_VER > 1800
auto bounds = strided_bounds<1>({length}, {2});
#else
auto bounds = strided_bounds<1>(multi_span_index<1>{length}, multi_span_index<1>{2});
#endif
strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);
EXPECT_TRUE(strided.size() == length);
EXPECT_TRUE(strided.bounds().index_bounds()[0] == length);
for (auto i = 0; i < strided.size(); ++i) {
EXPECT_TRUE(strided[i] == av[2 * i + 1]);
}
int idx = 0;
for (auto num : strided) {
EXPECT_TRUE(num == av[2 * idx + 1]);
idx++;
}
}
TEST_CASE("span_section_test")
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute // TODO: does not work
void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
{
const int expected[6] = {2, 3, 10, 11, 18, 19};
auto section = av.section({0, 1, 0}, {3, 1, 2});
for (auto i = 0; i < section.extent<0>(); ++i) {
for (auto j = 0; j < section.extent<1>(); ++j)
for (auto k = 0; k < section.extent<2>(); ++k) {
auto idx = multi_span_index<3>{i, j, k}; // avoid braces in the EXPECT_TRUE macro
EXPECT_TRUE(section[idx] == expected[2 * i + 2 * j + k]);
}
}
for (auto i = 0; i < section.extent<0>(); ++i) {
for (auto j = 0; j < section.extent<1>(); ++j)
for (auto k = 0; k < section.extent<2>(); ++k)
EXPECT_TRUE(section[i][j][k] == expected[2 * i + 2 * j + k]);
}
int i = 0;
for (const auto num : section) {
EXPECT_TRUE(num == expected[i]);
i++;
}
}
}
TEST(strided_span_tests, span_section_test)
{
int a[30][4][5];
@ -66,51 +123,52 @@ TEST_CASE("span_section_test")
(void) subsub;
}
TEST_CASE("span_section")
TEST(strided_span_tests, span_section)
{
std::vector<int> data(5 * 10);
std::iota(begin(data), end(data), 0);
const multi_span<int, 5, 10> av = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
const strided_span<int, 2> av_section_1 = av.section({1, 2}, {3, 4});
CHECK(!av_section_1.empty());
CHECK((av_section_1[{0, 0}] == 12));
CHECK((av_section_1[{0, 1}] == 13));
CHECK((av_section_1[{1, 0}] == 22));
CHECK((av_section_1[{2, 3}] == 35));
EXPECT_TRUE(!av_section_1.empty());
EXPECT_TRUE((av_section_1[{0, 0}] == 12));
EXPECT_TRUE((av_section_1[{0, 1}] == 13));
EXPECT_TRUE((av_section_1[{1, 0}] == 22));
EXPECT_TRUE((av_section_1[{2, 3}] == 35));
const strided_span<int, 2> av_section_2 = av_section_1.section({1, 2}, {2, 2});
CHECK(!av_section_2.empty());
CHECK((av_section_2[{0, 0}] == 24));
CHECK((av_section_2[{0, 1}] == 25));
CHECK((av_section_2[{1, 0}] == 34));
EXPECT_TRUE(!av_section_2.empty());
EXPECT_TRUE((av_section_2[{0, 0}] == 24));
EXPECT_TRUE((av_section_2[{0, 1}] == 25));
EXPECT_TRUE((av_section_2[{1, 0}] == 34));
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("strided_span_constructors")
TEST(strided_span_tests, strided_span_constructors)
{
// Check stride constructor
// EXPECT_TRUE stride constructor
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
const int carr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
strided_span<int, 1> sav1{arr, {{9}, {1}}}; // T -> T
CHECK(sav1.bounds().index_bounds() == multi_span_index<1>{9});
CHECK(sav1.bounds().stride() == 1);
CHECK((sav1[0] == 1 && sav1[8] == 9));
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{9});
EXPECT_TRUE(sav1.bounds().stride() == 1);
EXPECT_EQ(sav1[0], 1); EXPECT_EQ(sav1[8], 9);
strided_span<const int, 1> sav2{carr, {{4}, {2}}}; // const T -> const T
CHECK(sav2.bounds().index_bounds() == multi_span_index<1>{4});
CHECK(sav2.bounds().strides() == multi_span_index<1>{2});
CHECK((sav2[0] == 1 && sav2[3] == 7));
EXPECT_TRUE(sav2.bounds().index_bounds() == multi_span_index<1>{4});
EXPECT_TRUE(sav2.bounds().strides() == multi_span_index<1>{2});
EXPECT_EQ(sav2[0], 1); EXPECT_EQ(sav2[3], 7);
strided_span<int, 2> sav3{arr, {{2, 2}, {6, 2}}}; // T -> const T
CHECK((sav3.bounds().index_bounds() == multi_span_index<2>{2, 2}));
CHECK((sav3.bounds().strides() == multi_span_index<2>{6, 2}));
CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7));
EXPECT_TRUE((sav3.bounds().index_bounds() == multi_span_index<2>{2, 2}));
EXPECT_TRUE((sav3.bounds().strides() == multi_span_index<2>{6, 2}));
EXPECT_EQ((sav3[{0, 0}]), 1);
EXPECT_EQ((sav3[{0, 1}]), 3);
EXPECT_EQ((sav3[{1, 0}]), 7);
}
// Check multi_span constructor
// EXPECT_TRUE multi_span constructor
{
int arr[] = {1, 2};
@ -119,9 +177,9 @@ TEST_CASE("strided_span_constructors")
const multi_span<int> src = arr;
strided_span<int, 1> sav{src, {2, 1}};
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav.bounds().strides() == multi_span_index<1>{1});
CHECK(sav[1] == 2);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav[1] == 2);
#if defined(_MSC_VER) && _MSC_VER > 1800
// strided_span<const int, 1> sav_c{ {src}, {2, 1} };
@ -131,9 +189,9 @@ TEST_CASE("strided_span_constructors")
strided_span<const int, 1> sav_c{multi_span<const int>{src},
strided_bounds<1>{2, 1}};
#endif
CHECK(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_c.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_c[1] == 2);
EXPECT_TRUE(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_c.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_c[1] == 2);
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<volatile int, 1> sav_v{src, {2, 1}};
@ -141,9 +199,9 @@ TEST_CASE("strided_span_constructors")
strided_span<volatile int, 1> sav_v{multi_span<volatile int>{src},
strided_bounds<1>{2, 1}};
#endif
CHECK(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_v.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_v[1] == 2);
EXPECT_TRUE(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_v.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_v[1] == 2);
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
@ -151,9 +209,9 @@ TEST_CASE("strided_span_constructors")
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
strided_bounds<1>{2, 1}};
#endif
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_cv[1] == 2);
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_cv[1] == 2);
}
// From const-qualified source
@ -161,9 +219,9 @@ TEST_CASE("strided_span_constructors")
const multi_span<const int> src{arr};
strided_span<const int, 1> sav_c{src, {2, 1}};
CHECK(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_c.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_c[1] == 2);
EXPECT_TRUE(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_c.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_c[1] == 2);
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
@ -172,9 +230,9 @@ TEST_CASE("strided_span_constructors")
strided_bounds<1>{2, 1}};
#endif
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_cv[1] == 2);
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_cv[1] == 2);
}
// From volatile-qualified source
@ -182,9 +240,9 @@ TEST_CASE("strided_span_constructors")
const multi_span<volatile int> src{arr};
strided_span<volatile int, 1> sav_v{src, {2, 1}};
CHECK(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_v.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_v[1] == 2);
EXPECT_TRUE(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_v.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_v[1] == 2);
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
@ -192,9 +250,9 @@ TEST_CASE("strided_span_constructors")
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
strided_bounds<1>{2, 1}};
#endif
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_cv[1] == 2);
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_cv[1] == 2);
}
// From cv-qualified source
@ -202,19 +260,19 @@ TEST_CASE("strided_span_constructors")
const multi_span<const volatile int> src{arr};
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_cv[1] == 2);
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_cv[1] == 2);
}
}
// Check const-casting constructor
// EXPECT_TRUE const-casting constructor
{
int arr[2] = {4, 5};
const multi_span<int, 2> av(arr, 2);
multi_span<const int, 2> av2{av};
CHECK(av2[1] == 5);
EXPECT_TRUE(av2[1] == 5);
static_assert(
std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value,
@ -222,34 +280,35 @@ TEST_CASE("strided_span_constructors")
const strided_span<int, 1> src{arr, {2, 1}};
strided_span<const int, 1> sav{src};
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav.bounds().stride() == 1);
CHECK(sav[1] == 5);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav.bounds().stride() == 1);
EXPECT_TRUE(sav[1] == 5);
static_assert(
std::is_convertible<const strided_span<int, 1>, strided_span<const int, 1>>::value,
"ctor is not implicit!");
}
// Check copy constructor
// EXPECT_TRUE copy constructor
{
int arr1[2] = {3, 4};
const strided_span<int, 1> src1{arr1, {2, 1}};
strided_span<int, 1> sav1{src1};
CHECK(sav1.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav1.bounds().stride() == 1);
CHECK(sav1[0] == 3);
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav1.bounds().stride() == 1);
EXPECT_TRUE(sav1[0] == 3);
int arr2[6] = {1, 2, 3, 4, 5, 6};
const strided_span<const int, 2> src2{arr2, {{3, 2}, {2, 1}}};
strided_span<const int, 2> sav2{src2};
CHECK((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
CHECK((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
EXPECT_TRUE((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
EXPECT_TRUE((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
EXPECT_EQ((sav2[{0, 0}]), 1);
EXPECT_EQ((sav2[{2, 0}]), 5);
}
// Check const-casting assignment operator
// EXPECT_TRUE const-casting assignment operator
{
int arr1[2] = {1, 2};
int arr2[6] = {3, 4, 5, 6, 7, 8};
@ -257,38 +316,38 @@ TEST_CASE("strided_span_constructors")
const strided_span<int, 1> src{arr1, {{2}, {1}}};
strided_span<const int, 1> sav{arr2, {{3}, {2}}};
strided_span<const int, 1>& sav_ref = (sav = src);
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav.bounds().strides() == multi_span_index<1>{1});
CHECK(sav[0] == 1);
CHECK(&sav_ref == &sav);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav[0] == 1);
EXPECT_TRUE(&sav_ref == &sav);
}
// Check copy assignment operator
// EXPECT_TRUE copy assignment operator
{
int arr1[2] = {3, 4};
int arr1b[1] = {0};
const strided_span<int, 1> src1{arr1, {2, 1}};
strided_span<int, 1> sav1{arr1b, {1, 1}};
strided_span<int, 1>& sav1_ref = (sav1 = src1);
CHECK(sav1.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav1.bounds().strides() == multi_span_index<1>{1});
CHECK(sav1[0] == 3);
CHECK(&sav1_ref == &sav1);
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav1.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav1[0] == 3);
EXPECT_TRUE(&sav1_ref == &sav1);
const int arr2[6] = {1, 2, 3, 4, 5, 6};
const int arr2b[1] = {0};
const strided_span<const int, 2> src2{arr2, {{3, 2}, {2, 1}}};
strided_span<const int, 2> sav2{arr2b, {{1, 1}, {1, 1}}};
strided_span<const int, 2>& sav2_ref = (sav2 = src2);
CHECK((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
CHECK((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
CHECK(&sav2_ref == &sav2);
EXPECT_TRUE((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
EXPECT_TRUE((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
EXPECT_TRUE((sav2[{0, 0}] == 1));
EXPECT_TRUE((sav2[{2, 0}] == 5));
EXPECT_TRUE(&sav2_ref == &sav2);
}
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("strided_span_slice")
TEST(strided_span_tests, strided_span_slice)
{
std::vector<int> data(5 * 10);
std::iota(begin(data), end(data), 0);
@ -303,19 +362,18 @@ TEST_CASE("strided_span_slice")
{{5, 10}, {10, 1}}};
strided_span<int, 1> sav_sl = sav[2];
CHECK(sav_sl[0] == 20);
CHECK(sav_sl[9] == 29);
EXPECT_TRUE(sav_sl[0] == 20);
EXPECT_TRUE(sav_sl[9] == 29);
strided_span<const int, 1> csav_sl = sav[3];
CHECK(csav_sl[0] == 30);
CHECK(csav_sl[9] == 39);
EXPECT_TRUE(csav_sl[0] == 30);
EXPECT_TRUE(csav_sl[9] == 39);
CHECK(sav[4][0] == 40);
CHECK(sav[4][9] == 49);
EXPECT_TRUE(sav[4][0] == 40);
EXPECT_TRUE(sav[4][9] == 49);
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("strided_span_column_major")
TEST(strided_span_tests, strided_span_column_major)
{
// strided_span may be used to accommodate more peculiar
// use cases, such as column-major multidimensional array
@ -325,30 +383,29 @@ TEST_CASE("strided_span_column_major")
strided_span<int, 2> cm_sav{cm_array, {{5, 3}, {1, 5}}};
// Accessing elements
CHECK((cm_sav[{0, 0}] == 1));
CHECK((cm_sav[{0, 1}] == 2));
CHECK((cm_sav[{1, 0}] == 4));
CHECK((cm_sav[{4, 2}] == 15));
EXPECT_TRUE((cm_sav[{0, 0}] == 1));
EXPECT_TRUE((cm_sav[{0, 1}] == 2));
EXPECT_TRUE((cm_sav[{1, 0}] == 4));
EXPECT_TRUE((cm_sav[{4, 2}] == 15));
// Slice
strided_span<int, 1> cm_sl = cm_sav[3];
CHECK(cm_sl[0] == 10);
CHECK(cm_sl[1] == 11);
CHECK(cm_sl[2] == 12);
EXPECT_TRUE(cm_sl[0] == 10);
EXPECT_TRUE(cm_sl[1] == 11);
EXPECT_TRUE(cm_sl[2] == 12);
// Section
strided_span<int, 2> cm_sec = cm_sav.section({2, 1}, {3, 2});
CHECK((cm_sec.bounds().index_bounds() == multi_span_index<2>{3, 2}));
CHECK((cm_sec[{0, 0}] == 8));
CHECK((cm_sec[{0, 1}] == 9));
CHECK((cm_sec[{1, 0}] == 11));
CHECK((cm_sec[{2, 1}] == 15));
EXPECT_TRUE((cm_sec.bounds().index_bounds() == multi_span_index<2>{3, 2}));
EXPECT_TRUE((cm_sec[{0, 0}] == 8));
EXPECT_TRUE((cm_sec[{0, 1}] == 9));
EXPECT_TRUE((cm_sec[{1, 0}] == 11));
EXPECT_TRUE((cm_sec[{2, 1}] == 15));
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("strided_span_bounds")
TEST(strided_span_tests, strided_span_bounds)
{
int arr[] = {0, 1, 2, 3};
multi_span<int> av(arr);
@ -356,88 +413,88 @@ TEST_CASE("strided_span_bounds")
{
// incorrect sections
CHECK_THROWS_AS(av.section(0, 0)[0], fail_fast);
CHECK_THROWS_AS(av.section(1, 0)[0], fail_fast);
CHECK_THROWS_AS(av.section(1, 1)[1], fail_fast);
EXPECT_DEATH(av.section(0, 0)[0], ".*");
EXPECT_DEATH(av.section(1, 0)[0], ".*");
EXPECT_DEATH(av.section(1, 1)[1], ".*");
CHECK_THROWS_AS(av.section(2, 5), fail_fast);
CHECK_THROWS_AS(av.section(5, 2), fail_fast);
CHECK_THROWS_AS(av.section(5, 0), fail_fast);
CHECK_THROWS_AS(av.section(0, 5), fail_fast);
CHECK_THROWS_AS(av.section(5, 5), fail_fast);
EXPECT_DEATH(av.section(2, 5), ".*");
EXPECT_DEATH(av.section(5, 2), ".*");
EXPECT_DEATH(av.section(5, 0), ".*");
EXPECT_DEATH(av.section(0, 5), ".*");
EXPECT_DEATH(av.section(5, 5), ".*");
}
{
// zero stride
strided_span<int, 1> sav{av, {{4}, {}}};
CHECK(sav[0] == 0);
CHECK(sav[3] == 0);
CHECK_THROWS_AS(sav[4], fail_fast);
EXPECT_TRUE(sav[0] == 0);
EXPECT_TRUE(sav[3] == 0);
EXPECT_DEATH(sav[4], ".*");
}
{
// zero extent
strided_span<int, 1> sav{av, {{}, {1}}};
CHECK_THROWS_AS(sav[0], fail_fast);
EXPECT_DEATH(sav[0], ".*");
}
{
// zero extent and stride
strided_span<int, 1> sav{av, {{}, {}}};
CHECK_THROWS_AS(sav[0], fail_fast);
EXPECT_DEATH(sav[0], ".*");
}
{
// strided array ctor with matching strided bounds
strided_span<int, 1> sav{arr, {4, 1}};
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{4});
CHECK(sav[3] == 3);
CHECK_THROWS_AS(sav[4], fail_fast);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{4});
EXPECT_TRUE(sav[3] == 3);
EXPECT_DEATH(sav[4], ".*");
}
{
// strided array ctor with smaller strided bounds
strided_span<int, 1> sav{arr, {2, 1}};
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav[1] == 1);
CHECK_THROWS_AS(sav[2], fail_fast);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav[1] == 1);
EXPECT_DEATH(sav[2], ".*");
}
{
// strided array ctor with fitting irregular bounds
strided_span<int, 1> sav{arr, {2, 3}};
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav[0] == 0);
CHECK(sav[1] == 3);
CHECK_THROWS_AS(sav[2], fail_fast);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav[0] == 0);
EXPECT_TRUE(sav[1] == 3);
EXPECT_DEATH(sav[2], ".*");
}
{
// bounds cross data boundaries - from static arrays
CHECK_THROWS_AS((strided_span<int, 1>{arr, {3, 2}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{arr, {3, 3}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{arr, {4, 5}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{arr, {5, 1}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{arr, {5, 5}}), fail_fast);
EXPECT_DEATH((strided_span<int, 1>{arr, {3, 2}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{arr, {3, 3}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{arr, {4, 5}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{arr, {5, 1}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{arr, {5, 5}}), ".*");
}
{
// bounds cross data boundaries - from array view
CHECK_THROWS_AS((strided_span<int, 1>{av, {3, 2}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av, {3, 3}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av, {4, 5}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av, {5, 1}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av, {5, 5}}), fail_fast);
EXPECT_DEATH((strided_span<int, 1>{av, {3, 2}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{av, {3, 3}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{av, {4, 5}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{av, {5, 1}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{av, {5, 5}}), ".*");
}
{
// bounds cross data boundaries - from dynamic arrays
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {3, 2}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {3, 3}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {4, 5}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {5, 1}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {5, 5}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 2, {2, 2}}), fail_fast);
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {3, 2}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {3, 3}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {4, 5}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {5, 1}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {5, 5}}), ".*");
EXPECT_DEATH((strided_span<int, 1>{av.data(), 2, {2, 2}}), ".*");
}
#ifdef CONFIRM_COMPILATION_ERRORS
@ -464,8 +521,7 @@ TEST_CASE("strided_span_bounds")
#endif
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("strided_span_type_conversion")
TEST(strided_span_tests, strided_span_type_conversion)
{
int arr[] = {0, 1, 2, 3};
multi_span<int> av(arr);
@ -490,10 +546,10 @@ TEST_CASE("strided_span_type_conversion")
strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}};
strided_span<const byte, 2> sav2{bytes.data(), bytes.size(), bounds};
strided_span<const int, 2> sav3 = sav2.as_strided_span<const int>();
CHECK(sav3[0][0] == 0);
CHECK(sav3[1][0] == 2);
CHECK_THROWS_AS(sav3[1][1], fail_fast);
CHECK_THROWS_AS(sav3[0][1], fail_fast);
EXPECT_TRUE(sav3[0][0] == 0);
EXPECT_TRUE(sav3[1][0] == 2);
EXPECT_DEATH(sav3[1][1], ".*");
EXPECT_DEATH(sav3[0][1], ".*");
}
// retype strided array with regular strides - from multi_span
@ -503,10 +559,10 @@ TEST_CASE("strided_span_type_conversion")
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
strided_span<const byte, 2> sav2{bytes2, bounds};
strided_span<int, 2> sav3 = sav2.as_strided_span<int>();
CHECK(sav3[0][0] == 0);
CHECK(sav3[1][0] == 2);
CHECK_THROWS_AS(sav3[1][1], fail_fast);
CHECK_THROWS_AS(sav3[0][1], fail_fast);
EXPECT_TRUE(sav3[0][0] == 0);
EXPECT_TRUE(sav3[1][0] == 2);
EXPECT_DEATH(sav3[1][1], ".*");
EXPECT_DEATH(sav3[0][1], ".*");
}
// retype strided array with not enough elements - last dimension of the array is too small
@ -515,7 +571,7 @@ TEST_CASE("strided_span_type_conversion")
multi_span<const byte, 2, dynamic_range> bytes2 =
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
strided_span<const byte, 2> sav2{bytes2, bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), ".*");
}
// retype strided array with not enough elements - strides are too small
@ -524,7 +580,7 @@ TEST_CASE("strided_span_type_conversion")
multi_span<const byte, 2, dynamic_range> bytes2 =
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
strided_span<const byte, 2> sav2{bytes2, bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), ".*");
}
// retype strided array with not enough elements - last dimension does not divide by the new
@ -534,7 +590,7 @@ TEST_CASE("strided_span_type_conversion")
multi_span<const byte, 2, dynamic_range> bytes2 =
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
strided_span<const byte, 2> sav2{bytes2, bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), ".*");
}
// retype strided array with not enough elements - strides does not divide by the new
@ -544,88 +600,58 @@ TEST_CASE("strided_span_type_conversion")
multi_span<const byte, 2, dynamic_range> bytes2 =
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
strided_span<const byte, 2> sav2{bytes2, bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), ".*");
}
// retype strided array with irregular strides - from raw data
{
strided_bounds<1> bounds{bytes.size() / 2, 2};
strided_span<const byte, 1> sav2{bytes.data(), bytes.size(), bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), ".*");
}
// retype strided array with irregular strides - from multi_span
{
strided_bounds<1> bounds{bytes.size() / 2, 2};
strided_span<const byte, 1> sav2{bytes, bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), ".*");
}
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
TEST_CASE("empty_strided_spans")
TEST(strided_span_tests, empty_strided_spans)
{
{
multi_span<int, 0> empty_av(nullptr);
strided_span<int, 1> empty_sav{empty_av, {0, 1}};
CHECK(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
CHECK(empty_sav.empty());
CHECK_THROWS_AS(empty_sav[0], fail_fast);
CHECK_THROWS_AS(empty_sav.begin()[0], fail_fast);
CHECK_THROWS_AS(empty_sav.cbegin()[0], fail_fast);
EXPECT_TRUE(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
EXPECT_TRUE(empty_sav.empty());
EXPECT_DEATH(empty_sav[0], ".*");
EXPECT_DEATH(empty_sav.begin()[0], ".*");
EXPECT_DEATH(empty_sav.cbegin()[0], ".*");
for (const auto& v : empty_sav) {
(void) v;
CHECK(false);
EXPECT_TRUE(false);
}
}
{
strided_span<int, 1> empty_sav{nullptr, 0, {0, 1}};
CHECK(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
CHECK_THROWS_AS(empty_sav[0], fail_fast);
CHECK_THROWS_AS(empty_sav.begin()[0], fail_fast);
CHECK_THROWS_AS(empty_sav.cbegin()[0], fail_fast);
EXPECT_TRUE(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
EXPECT_DEATH(empty_sav[0], ".*");
EXPECT_DEATH(empty_sav.begin()[0], ".*");
EXPECT_DEATH(empty_sav.cbegin()[0], ".*");
for (const auto& v : empty_sav) {
(void) v;
CHECK(false);
EXPECT_TRUE(false);
}
}
}
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);
CHECK(strided.size() == length);
CHECK(strided.bounds().index_bounds()[0] == length);
for (auto i = 0; i < strided.size(); ++i) {
CHECK(strided[i] == av[2 * i + 1]);
}
int idx = 0;
for (auto num : strided) {
CHECK(num == av[2 * idx + 1]);
idx++;
}
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("strided_span_section_iteration")
TEST(strided_span_tests, strided_span_section_iteration)
{
int arr[8] = {4, 0, 5, 1, 6, 2, 7, 3};
@ -642,12 +668,7 @@ TEST_CASE("strided_span_section_iteration")
}
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
TEST_CASE("dynamic_strided_span_section_iteration")
TEST(strided_span_tests, dynamic_strided_span_section_iteration)
{
auto arr = new int[8];
for (int i = 0; i < 4; ++i) {
@ -661,39 +682,7 @@ TEST_CASE("dynamic_strided_span_section_iteration")
delete[] arr;
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute // TODO: does not work
void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
{
const int expected[6] = {2, 3, 10, 11, 18, 19};
auto section = av.section({0, 1, 0}, {3, 1, 2});
for (auto i = 0; i < section.extent<0>(); ++i) {
for (auto j = 0; j < section.extent<1>(); ++j)
for (auto k = 0; k < section.extent<2>(); ++k) {
auto idx = multi_span_index<3>{i, j, k}; // avoid braces in the CHECK macro
CHECK(section[idx] == expected[2 * i + 2 * j + k]);
}
}
for (auto i = 0; i < section.extent<0>(); ++i) {
for (auto j = 0; j < section.extent<1>(); ++j)
for (auto k = 0; k < section.extent<2>(); ++k)
CHECK(section[i][j][k] == expected[2 * i + 2 * j + k]);
}
int i = 0;
for (const auto num : section) {
CHECK(num == expected[i]);
i++;
}
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
TEST_CASE("strided_span_section_iteration_3d")
TEST(strided_span_tests, strided_span_section_iteration_3d)
{
int arr[3][4][2]{};
for (auto i = 0; i < 3; ++i) {
@ -707,12 +696,7 @@ TEST_CASE("strided_span_section_iteration_3d")
}
}
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
GSL_SUPPRESS(r.3) // NO-FORMAT: attribute
GSL_SUPPRESS(r.5) // NO-FORMAT: attribute
GSL_SUPPRESS(r.11) // NO-FORMAT: attribute
TEST_CASE("dynamic_strided_span_section_iteration_3d")
TEST(strided_span_tests, dynamic_strided_span_section_iteration_3d)
{
const auto height = 12, width = 2;
const auto size = height * width;
@ -744,10 +728,7 @@ TEST_CASE("dynamic_strided_span_section_iteration_3d")
delete[] arr;
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
TEST_CASE("strided_span_conversion")
TEST(strided_span_tests, strided_span_conversion)
{
// get an multi_span of 'c' values from the list of X's
@ -767,8 +748,8 @@ TEST_CASE("strided_span_conversion")
// convert to 4x12 array of bytes
auto av = as_multi_span(as_bytes(as_multi_span(&arr[0], 4)), dim(d1), dim(d2));
CHECK(av.bounds().index_bounds()[0] == 4);
CHECK(av.bounds().index_bounds()[1] == 12);
EXPECT_TRUE(av.bounds().index_bounds()[0] == 4);
EXPECT_TRUE(av.bounds().index_bounds()[1] == 12);
// get the last 4 columns
auto section = av.section({0, 2 * s}, {4, s}); // { { arr[0].c[0], arr[0].c[1], arr[0].c[2],
@ -778,8 +759,8 @@ TEST_CASE("strided_span_conversion")
// convert to array 4x1 array of integers
auto cs = section.as_strided_span<int>(); // { { arr[0].c }, {arr[1].c } , ... }
CHECK(cs.bounds().index_bounds()[0] == 4);
CHECK(cs.bounds().index_bounds()[1] == 1);
EXPECT_TRUE(cs.bounds().index_bounds()[0] == 4);
EXPECT_TRUE(cs.bounds().index_bounds()[1] == 1);
// transpose to 1x4 array
strided_bounds<2> reverse_bounds{
@ -791,12 +772,12 @@ TEST_CASE("strided_span_conversion")
// slice to get a one-dimensional array of c's
strided_span<int, 1> result = transposed[0];
CHECK(result.bounds().index_bounds()[0] == 4);
CHECK_THROWS_AS(result.bounds().index_bounds()[1], fail_fast);
EXPECT_TRUE(result.bounds().index_bounds()[0] == 4);
EXPECT_DEATH(result.bounds().index_bounds()[1], ".*");
int i = 0;
for (auto& num : result) {
CHECK(num == arr[i].c);
EXPECT_TRUE(num == arr[i].c);
i++;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -24,4 +24,3 @@
#pragma warning(disable : ALL_CODE_ANALYSIS_WARNINGS) // from catch
#endif // _MSC_VER
#include <catch/catch.hpp>

View File

@ -21,7 +21,7 @@
#endif
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gtest/gtest.h>
#include <gsl/gsl_util> // for narrow, finally, narrow_cast, narrowing_e...
@ -33,101 +33,100 @@
using namespace gsl;
TEST_CASE("sanity check for gsl::index typedef")
void f(int& i) { i += 1; }
static int j = 0;
void g() { j += 1; }
TEST(utils_tests, sanity_check_for_gsl_index_typedef)
{
static_assert(std::is_same<gsl::index, std::ptrdiff_t>::value,
"gsl::index represents wrong arithmetic type");
}
void f(int& i) { i += 1; }
TEST_CASE("finally_lambda")
TEST(utils_tests, finally_lambda)
{
int i = 0;
{
auto _ = finally([&]() { f(i); });
CHECK(i == 0);
EXPECT_EQ(i, 0);
}
CHECK(i == 1);
EXPECT_EQ(i, 1);
}
TEST_CASE("finally_lambda_move")
TEST(utils_tests, finally_lambda_move)
{
int i = 0;
{
auto _1 = finally([&]() { f(i); });
{
auto _2 = std::move(_1);
CHECK(i == 0);
EXPECT_EQ(i, 0);
}
CHECK(i == 1);
EXPECT_EQ(i, 1);
{
auto _2 = std::move(_1);
CHECK(i == 1);
EXPECT_EQ(i, 1);
}
CHECK(i == 1);
EXPECT_EQ(i, 1);
}
CHECK(i == 1);
EXPECT_EQ(i, 1);
}
TEST_CASE("finally_function_with_bind")
TEST(utils_tests, finally_function_with_bind)
{
int i = 0;
{
auto _ = finally(std::bind(&f, std::ref(i)));
CHECK(i == 0);
EXPECT_EQ(i, 0);
}
CHECK(i == 1);
EXPECT_EQ(i, 1);
}
static int j = 0;
void g() { j += 1; }
TEST_CASE("finally_function_ptr")
TEST(utils_tests, finally_function_ptr)
{
j = 0;
{
auto _ = finally(&g);
CHECK(j == 0);
EXPECT_EQ(j, 0);
}
CHECK(j == 1);
EXPECT_EQ(j, 1);
}
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
TEST_CASE("narrow_cast")
TEST(utils_tests, narrow_cast)
{
int n = 120;
char c = narrow_cast<char>(n);
CHECK(c == 120);
EXPECT_EQ(c, 120);
n = 300;
unsigned char uc = narrow_cast<unsigned char>(n);
CHECK(uc == 44);
EXPECT_EQ(uc, 44);
}
GSL_SUPPRESS(con.5) // NO-FORMAT: attribute
TEST_CASE("narrow")
TEST(utils_tests, narrow)
{
int n = 120;
const char c = narrow<char>(n);
CHECK(c == 120);
EXPECT_EQ(c, 120);
n = 300;
CHECK_THROWS_AS(narrow<char>(n), narrowing_error);
EXPECT_DEATH(narrow<char>(n), ".*");
const auto int32_max = std::numeric_limits<int32_t>::max();
const auto int32_min = std::numeric_limits<int32_t>::min();
CHECK(narrow<uint32_t>(int32_t(0)) == 0);
CHECK(narrow<uint32_t>(int32_t(1)) == 1);
CHECK(narrow<uint32_t>(int32_max) == static_cast<uint32_t>(int32_max));
EXPECT_TRUE(narrow<uint32_t>(int32_t(0)) == 0);
EXPECT_TRUE(narrow<uint32_t>(int32_t(1)) == 1);
EXPECT_TRUE(narrow<uint32_t>(int32_max) == static_cast<uint32_t>(int32_max));
CHECK_THROWS_AS(narrow<uint32_t>(int32_t(-1)), narrowing_error);
CHECK_THROWS_AS(narrow<uint32_t>(int32_min), narrowing_error);
EXPECT_DEATH(narrow<uint32_t>(int32_t(-1)), ".*");
EXPECT_DEATH(narrow<uint32_t>(int32_min), ".*");
n = -42;
CHECK_THROWS_AS(narrow<unsigned>(n), narrowing_error);
EXPECT_DEATH(narrow<unsigned>(n), ".*");
#if GSL_CONSTEXPR_NARROW
static_assert(narrow<char>(120) == 120, "Fix GSL_CONSTEXPR_NARROW");
#endif
}