diff --git a/include/gsl/assert b/include/gsl/assert index 0cc54f6..a601204 100644 --- a/include/gsl/assert +++ b/include/gsl/assert @@ -22,6 +22,7 @@ // Currently terminate is a no-op in this mode, so we add termination behavior back // #if defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)) +#define GSL_KERNEL_MODE #define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND #include diff --git a/include/gsl/gsl_algorithm b/include/gsl/gsl_algorithm index 9f1dd50..303a5ae 100644 --- a/include/gsl/gsl_algorithm +++ b/include/gsl/gsl_algorithm @@ -1,3 +1,4 @@ #pragma once -#pragma message("This header will soon be removed. Use instead of ") +#pragma message( \ + "This header will soon be removed. Use instead of ") #include diff --git a/include/gsl/narrow b/include/gsl/narrow index d47d9fd..67aac05 100644 --- a/include/gsl/narrow +++ b/include/gsl/narrow @@ -30,7 +30,7 @@ template // clang-format off GSL_SUPPRESS(type.1) // NO-FORMAT: attribute GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false) -// clang-format on + // clang-format on constexpr T narrow(U u) noexcept(false) { constexpr const bool is_different_signedness = diff --git a/include/gsl/pointers b/include/gsl/pointers index 2f1b15f..e6b2348 100644 --- a/include/gsl/pointers +++ b/include/gsl/pointers @@ -34,12 +34,19 @@ namespace gsl namespace details { -template -struct is_comparable_to_nullptr : std::false_type {}; + template + struct is_comparable_to_nullptr : std::false_type + { + }; -template -struct is_comparable_to_nullptr() != nullptr), bool>::value>> : std::true_type {}; -} // namespace details + template + struct is_comparable_to_nullptr< + T, + std::enable_if_t() != nullptr), bool>::value>> + : std::true_type + { + }; +} // namespace details // // GSL.owner: ownership pointers diff --git a/include/gsl/span b/include/gsl/span index 506eb4c..cc8a7b9 100644 --- a/include/gsl/span +++ b/include/gsl/span @@ -21,10 +21,11 @@ #include // for byte #include // for narrow_cast -#include // for array -#include // for ptrdiff_t, size_t, nullptr_t -#include // for reverse_iterator, distance, random_access_... -#include // for enable_if_t, declval, is_convertible, inte... +#include // for array +#include // for ptrdiff_t, size_t, nullptr_t +#include // for span specialization of gsl::at and other span-related extensions +#include // for reverse_iterator, distance, random_access_... +#include // for enable_if_t, declval, is_convertible, inte... #if defined(_MSC_VER) && !defined(__clang__) #pragma warning(push) @@ -60,12 +61,6 @@ namespace gsl { -// [views.constants], constants -constexpr const std::size_t dynamic_extent = narrow_cast(-1); - -template -class span; - // implementation details namespace details { diff --git a/include/gsl/span_ext b/include/gsl/span_ext index b7c12cf..5feb2b8 100644 --- a/include/gsl/span_ext +++ b/include/gsl/span_ext @@ -27,16 +27,29 @@ // /////////////////////////////////////////////////////////////////////////////// -#include // for span -#include // for narrow_cast, narrow +#include // GSL_KERNEL_MODE +#include // for narrow_cast, narrow -#include // for lexicographical_compare -#include // for ptrdiff_t, size_t +#include // for ptrdiff_t, size_t #include +#ifndef GSL_KERNEL_MODE +#include // for lexicographical_compare +#endif // GSL_KERNEL_MODE + namespace gsl { +// [span.views.constants], constants +constexpr const std::size_t dynamic_extent = narrow_cast(-1); + +template +class span; + +// std::equal and std::lexicographical_compare are not /kernel compatible +// so all comparison operators must be removed for kernel mode. +#ifndef GSL_KERNEL_MODE + // [span.comparison], span comparison operators template constexpr bool operator==(span l, span r) @@ -74,6 +87,8 @@ constexpr bool operator>=(span l, span return !(l < r); } +#endif // GSL_KERNEL_MODE + // // make_span() - Utility functions for creating spans // diff --git a/include/gsl/util b/include/gsl/util index 2d67b7f..db66aae 100644 --- a/include/gsl/util +++ b/include/gsl/util @@ -25,6 +25,10 @@ #include // for is_signed, integral_constant #include // for exchange, forward +#if defined(__cplusplus) && __cplusplus >= 202002L +#include +#endif // __cplusplus >= 202002L + #if defined(_MSC_VER) && !defined(__clang__) #pragma warning(push) @@ -92,8 +96,8 @@ finally(F&& f) noexcept template // clang-format off GSL_SUPPRESS(type.1) // NO-FORMAT: attribute -// clang-format on -constexpr T narrow_cast(U&& u) noexcept + // clang-format on + constexpr T narrow_cast(U&& u) noexcept { return static_cast(std::forward(u)); } @@ -105,7 +109,7 @@ template // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute -// clang-format on + // clang-format on constexpr T& at(T (&arr)[N], const index i) { Expects(i >= 0 && i < narrow_cast(N)); @@ -116,7 +120,7 @@ template // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute -// clang-format on + // clang-format on constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()]) { Expects(i >= 0 && i < narrow_cast(cont.size())); @@ -127,13 +131,21 @@ GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute template // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute -// clang-format on -constexpr T at(const std::initializer_list cont, const index i) + // clang-format on + constexpr T at(const std::initializer_list cont, const index i) { Expects(i >= 0 && i < narrow_cast(cont.size())); return *(cont.begin() + i); } +#if defined(__cplusplus) && __cplusplus >= 202002L +template +constexpr auto at(std::span sp, const index i) +{ + Expects(i >= 0 && i < narrow_cast(sp.size())); + return sp[i]; +} +#endif // __cplusplus >= 202002L } // namespace gsl #if defined(_MSC_VER) && !defined(__clang__) diff --git a/tests/algorithm_tests.cpp b/tests/algorithm_tests.cpp index 0f209ac..16746b4 100644 --- a/tests/algorithm_tests.cpp +++ b/tests/algorithm_tests.cpp @@ -14,16 +14,13 @@ // /////////////////////////////////////////////////////////////////////////////// -#include +#include // for array +#include // for size_t #include // for copy -#include // for span -#include // for array -#include // for size_t +#include // for span +#include -namespace -{ - static constexpr char deathstring[] = "Expected Death"; -} +#include "deathTestCommon.h" namespace gsl { @@ -204,10 +201,11 @@ TEST(algorithm_tests, incompatible_type) TEST(algorithm_tests, small_destination_span) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. small_destination_span"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); std::array src{1, 2, 3, 4}; std::array dst{}; @@ -217,9 +215,9 @@ TEST(algorithm_tests, small_destination_span) const span dst_span_dyn(dst); const span dst_span_static(dst); - EXPECT_DEATH(copy(src_span_dyn, dst_span_dyn), deathstring); - EXPECT_DEATH(copy(src_span_dyn, dst_span_static), deathstring); - EXPECT_DEATH(copy(src_span_static, dst_span_dyn), deathstring); + EXPECT_DEATH(copy(src_span_dyn, dst_span_dyn), expected); + EXPECT_DEATH(copy(src_span_dyn, dst_span_static), expected); + EXPECT_DEATH(copy(src_span_static, dst_span_dyn), expected); #ifdef CONFIRM_COMPILATION_ERRORS copy(src_span_static, dst_span_static); diff --git a/tests/assertion_tests.cpp b/tests/assertion_tests.cpp index 6b5fb0b..dd3ca06 100644 --- a/tests/assertion_tests.cpp +++ b/tests/assertion_tests.cpp @@ -14,14 +14,14 @@ // /////////////////////////////////////////////////////////////////////////////// -#include +#include "deathTestCommon.h" #include // for fail_fast (ptr only), Ensures, Expects +#include using namespace gsl; namespace { -static constexpr char deathstring[] = "Expected Death"; int f(int i) { @@ -39,23 +39,22 @@ int g(int i) TEST(assertion_tests, expects) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. expects"; std::abort(); }); EXPECT_TRUE(f(2) == 2); - EXPECT_DEATH(f(10), deathstring); + EXPECT_DEATH(f(10), GetExpectedDeathString(terminateHandler)); } - TEST(assertion_tests, ensures) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. ensures"; std::abort(); }); EXPECT_TRUE(g(2) == 3); - EXPECT_DEATH(g(9), deathstring); + EXPECT_DEATH(g(9), GetExpectedDeathString(terminateHandler)); } diff --git a/tests/at_tests.cpp b/tests/at_tests.cpp index 1285139..92a8e4d 100644 --- a/tests/at_tests.cpp +++ b/tests/at_tests.cpp @@ -22,31 +22,33 @@ #include // for size_t #include // for initializer_list #include // for vector +#if defined(__cplusplus) && __cplusplus >= 202002L +#include +#endif // __cplusplus >= 202002L -namespace -{ - static constexpr char deathstring[] = "Expected Death"; -} +#include "deathTestCommon.h" TEST(at_tests, static_array) { int a[4] = {1, 2, 3, 4}; const int(&c_a)[4] = a; - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < 4; ++i) + { EXPECT_TRUE(&gsl::at(a, i) == &a[i]); EXPECT_TRUE(&gsl::at(c_a, i) == &a[i]); } - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. static_array"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); - EXPECT_DEATH(gsl::at(a, -1), deathstring); - EXPECT_DEATH(gsl::at(a, 4), deathstring); - EXPECT_DEATH(gsl::at(c_a, -1), deathstring); - EXPECT_DEATH(gsl::at(c_a, 4), deathstring); + EXPECT_DEATH(gsl::at(a, -1), expected); + EXPECT_DEATH(gsl::at(a, 4), expected); + EXPECT_DEATH(gsl::at(c_a, -1), expected); + EXPECT_DEATH(gsl::at(c_a, 4), expected); } TEST(at_tests, std_array) @@ -54,20 +56,22 @@ TEST(at_tests, std_array) std::array a = {1, 2, 3, 4}; const std::array& c_a = a; - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < 4; ++i) + { EXPECT_TRUE(&gsl::at(a, i) == &a[static_cast(i)]); EXPECT_TRUE(&gsl::at(c_a, i) == &a[static_cast(i)]); } - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. std_array"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); - EXPECT_DEATH(gsl::at(a, -1), deathstring); - EXPECT_DEATH(gsl::at(a, 4), deathstring); - EXPECT_DEATH(gsl::at(c_a, -1), deathstring); - EXPECT_DEATH(gsl::at(c_a, 4), deathstring); + EXPECT_DEATH(gsl::at(a, -1), expected); + EXPECT_DEATH(gsl::at(a, 4), expected); + EXPECT_DEATH(gsl::at(c_a, -1), expected); + EXPECT_DEATH(gsl::at(c_a, 4), expected); } TEST(at_tests, std_vector) @@ -75,42 +79,68 @@ TEST(at_tests, std_vector) std::vector a = {1, 2, 3, 4}; const std::vector& c_a = a; - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < 4; ++i) + { EXPECT_TRUE(&gsl::at(a, i) == &a[static_cast(i)]); EXPECT_TRUE(&gsl::at(c_a, i) == &a[static_cast(i)]); } - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. std_vector"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); - EXPECT_DEATH(gsl::at(a, -1), deathstring); - EXPECT_DEATH(gsl::at(a, 4), deathstring); - EXPECT_DEATH(gsl::at(c_a, -1), deathstring); - EXPECT_DEATH(gsl::at(c_a, 4), deathstring); + EXPECT_DEATH(gsl::at(a, -1), expected); + EXPECT_DEATH(gsl::at(a, 4), expected); + EXPECT_DEATH(gsl::at(c_a, -1), expected); + EXPECT_DEATH(gsl::at(c_a, 4), expected); } TEST(at_tests, InitializerList) { const std::initializer_list a = {1, 2, 3, 4}; - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < 4; ++i) + { EXPECT_TRUE(gsl::at(a, i) == i + 1); EXPECT_TRUE(gsl::at({1, 2, 3, 4}, i) == i + 1); } - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. InitializerList"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); - EXPECT_DEATH(gsl::at(a, -1), deathstring); - EXPECT_DEATH(gsl::at(a, 4), deathstring); - EXPECT_DEATH(gsl::at({1, 2, 3, 4}, -1), deathstring); - EXPECT_DEATH(gsl::at({1, 2, 3, 4}, 4), deathstring); + EXPECT_DEATH(gsl::at(a, -1), expected); + EXPECT_DEATH(gsl::at(a, 4), expected); + EXPECT_DEATH(gsl::at({1, 2, 3, 4}, -1), expected); + EXPECT_DEATH(gsl::at({1, 2, 3, 4}, 4), expected); } +#if defined(__cplusplus) && __cplusplus >= 202002L +TEST(at_tests, std_span) +{ + std::vector vec{1, 2, 3, 4, 5}; + std::span sp{vec}; + + std::vector cvec{1, 2, 3, 4, 5}; + std::span csp{cvec}; + + for (size_t i = 0, i < vec.size(); ++i) + { + EXPECT_TRUE(&gsl::at(sp, i) == &vec[i]); + EXPECT_TRUE(&gsl::at(csp, i) == &cvec[i]); + } + + EXPECT_DEATH(gsl::at(sp, -1), expected); + EXPECT_DEATH(gsl::at(sp, sp.size()), expected); + EXPECT_DEATH(gsl::at(csp, -1), expected); + EXPECT_DEATH(gsl::at(csp, sp.size()), expected); +} +#endif // __cplusplus >= 202002L + #if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910 static constexpr bool test_constexpr() { @@ -119,7 +149,8 @@ static constexpr bool test_constexpr() std::array a2 = {1, 2, 3, 4}; const std::array& c_a2 = a2; - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < 4; ++i) + { if (&gsl::at(a1, i) != &a1[i]) return false; if (&gsl::at(c_a1, i) != &a1[i]) return false; // requires C++17: diff --git a/tests/byte_tests.cpp b/tests/byte_tests.cpp index 2a86cac..4432fc9 100644 --- a/tests/byte_tests.cpp +++ b/tests/byte_tests.cpp @@ -37,7 +37,9 @@ TEST(byte_tests, construction) EXPECT_TRUE(static_cast(b) == 4); } + // clang-format off GSL_SUPPRESS(es.49) + // clang-format on { const byte b = byte(12); EXPECT_TRUE(static_cast(b) == 12); @@ -55,7 +57,7 @@ TEST(byte_tests, construction) #if defined(__cplusplus) && (__cplusplus >= 201703L) { - const byte b { 14 }; + const byte b{14}; EXPECT_TRUE(static_cast(b) == 14); } #endif @@ -122,7 +124,7 @@ TEST(byte_tests, aliasing) EXPECT_TRUE(res == i); } -} +} // namespace #ifdef CONFIRM_COMPILATION_ERRORS copy(src_span_static, dst_span_static); diff --git a/tests/deathTestCommon.h b/tests/deathTestCommon.h new file mode 100644 index 0000000..7bf2423 --- /dev/null +++ b/tests/deathTestCommon.h @@ -0,0 +1,11 @@ +#pragma once +#include + +constexpr char deathstring[] = "Expected Death"; +constexpr char failed_set_terminate_deathstring[] = ".*"; + +// This prevents a failed call to set_terminate from failing the test suite. +constexpr const char* GetExpectedDeathString(std::terminate_handler handle) +{ + return handle ? deathstring : failed_set_terminate_deathstring; +} diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index d4258e8..db22c72 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -25,13 +25,9 @@ #include // for basic_string, operator==, string, operator<< #include // for type_info +#include "deathTestCommon.h" using namespace gsl; -namespace -{ -constexpr char deathstring[] = "Expected Death"; -} // namespace - struct MyBase { }; @@ -64,7 +60,9 @@ struct CustomPtr template std::string operator==(CustomPtr const& lhs, CustomPtr const& rhs) { + // clang-format off GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + // clang-format on return reinterpret_cast(lhs.p_) == reinterpret_cast(rhs.p_) ? "true" : "false"; } @@ -72,7 +70,9 @@ std::string operator==(CustomPtr const& lhs, CustomPtr const& rhs) template std::string operator!=(CustomPtr const& lhs, CustomPtr const& rhs) { + // clang-format off GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + // clang-format on return reinterpret_cast(lhs.p_) != reinterpret_cast(rhs.p_) ? "true" : "false"; } @@ -80,7 +80,9 @@ std::string operator!=(CustomPtr const& lhs, CustomPtr const& rhs) template std::string operator<(CustomPtr const& lhs, CustomPtr const& rhs) { + // clang-format off GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + // clang-format on return reinterpret_cast(lhs.p_) < reinterpret_cast(rhs.p_) ? "true" : "false"; } @@ -88,7 +90,9 @@ std::string operator<(CustomPtr const& lhs, CustomPtr const& rhs) template std::string operator>(CustomPtr const& lhs, CustomPtr const& rhs) { + // clang-format off GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + // clang-format on return reinterpret_cast(lhs.p_) > reinterpret_cast(rhs.p_) ? "true" : "false"; } @@ -96,7 +100,9 @@ std::string operator>(CustomPtr const& lhs, CustomPtr const& rhs) template std::string operator<=(CustomPtr const& lhs, CustomPtr const& rhs) { + // clang-format off GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + // clang-format on return reinterpret_cast(lhs.p_) <= reinterpret_cast(rhs.p_) ? "true" : "false"; } @@ -104,7 +110,9 @@ std::string operator<=(CustomPtr const& lhs, CustomPtr const& rhs) template std::string operator>=(CustomPtr const& lhs, CustomPtr const& rhs) { + // clang-format off GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + // clang-format on return reinterpret_cast(lhs.p_) >= reinterpret_cast(rhs.p_) ? "true" : "false"; } @@ -120,9 +128,13 @@ struct NonCopyableNonMovable namespace { -GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +// clang-format off +GSL_SUPPRESS(f .4) // NO-FORMAT: attribute +// clang-format on bool helper(not_null p) { return *p == 12; } -GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +// clang-format off +GSL_SUPPRESS(f .4) // NO-FORMAT: attribute +// clang-format on bool helper_const(not_null p) { return *p == 12; } int* return_pointer() { return nullptr; } @@ -145,10 +157,12 @@ TEST(notnull_tests, TestNotNullConstructors) #endif } - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. TestNotNullConstructors"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); + { // from shared pointer int i = 12; @@ -160,7 +174,7 @@ TEST(notnull_tests, TestNotNullConstructors) std::make_shared(10)); // shared_ptr is nullptr assignable int* pi = nullptr; - EXPECT_DEATH((not_null(pi)), deathstring); + EXPECT_DEATH((not_null(pi)), expected); } { @@ -217,8 +231,8 @@ TEST(notnull_tests, TestNotNullConstructors) { // from returned pointer - EXPECT_DEATH(helper(return_pointer()), deathstring); - EXPECT_DEATH(helper_const(return_pointer()), deathstring); + EXPECT_DEATH(helper(return_pointer()), expected); + EXPECT_DEATH(helper_const(return_pointer()), expected); } } @@ -278,17 +292,18 @@ TEST(notnull_tests, TestNotNullCasting) TEST(notnull_tests, TestNotNullAssignment) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. TestNotNullAssignmentd"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); int i = 12; not_null p(&i); EXPECT_TRUE(helper(p)); int* q = nullptr; - EXPECT_DEATH(p = not_null(q), deathstring); + EXPECT_DEATH(p = not_null(q), expected); } TEST(notnull_tests, TestNotNullRawPointerComparison) @@ -437,17 +452,18 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction) EXPECT_TRUE(*x == 42); } - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. TestNotNullConstructorTypeDeduction"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); { auto workaround_macro = []() { int* p1 = nullptr; const not_null x{p1}; }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } { @@ -455,14 +471,14 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction) const int* p1 = nullptr; const not_null x{p1}; }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } { int* p = nullptr; - EXPECT_DEATH(helper(not_null{p}), deathstring); - EXPECT_DEATH(helper_const(not_null{p}), deathstring); + EXPECT_DEATH(helper(not_null{p}), expected); + EXPECT_DEATH(helper_const(not_null{p}), expected); } #ifdef CONFIRM_COMPILATION_ERRORS @@ -498,10 +514,11 @@ TEST(notnull_tests, TestMakeNotNull) EXPECT_TRUE(*x == 42); } - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. TestMakeNotNull"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); { const auto workaround_macro = []() { @@ -509,7 +526,7 @@ TEST(notnull_tests, TestMakeNotNull) const auto x = make_not_null(p1); EXPECT_TRUE(*x == 42); }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } { @@ -518,21 +535,21 @@ TEST(notnull_tests, TestMakeNotNull) const auto x = make_not_null(p1); EXPECT_TRUE(*x == 42); }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } { int* p = nullptr; - EXPECT_DEATH(helper(make_not_null(p)), deathstring); - EXPECT_DEATH(helper_const(make_not_null(p)), deathstring); + EXPECT_DEATH(helper(make_not_null(p)), expected); + EXPECT_DEATH(helper_const(make_not_null(p)), expected); } #ifdef CONFIRM_COMPILATION_ERRORS { - EXPECT_DEATH(make_not_null(nullptr), deathstring); - EXPECT_DEATH(helper(make_not_null(nullptr)), deathstring); - EXPECT_DEATH(helper_const(make_not_null(nullptr)), deathstring); + EXPECT_DEATH(make_not_null(nullptr), expected); + EXPECT_DEATH(helper(make_not_null(nullptr)), expected); + EXPECT_DEATH(helper_const(make_not_null(nullptr)), expected); } #endif } diff --git a/tests/owner_tests.cpp b/tests/owner_tests.cpp index ca8222f..87c7cec 100644 --- a/tests/owner_tests.cpp +++ b/tests/owner_tests.cpp @@ -20,7 +20,7 @@ using namespace gsl; -GSL_SUPPRESS(f.23) // NO-FORMAT: attribute +GSL_SUPPRESS(f .23) // NO-FORMAT: attribute void f(int* i) { *i += 1; } TEST(owner_tests, basic_test) @@ -34,10 +34,10 @@ TEST(owner_tests, basic_test) TEST(owner_tests, check_pointer_constraint) { - #ifdef CONFIRM_COMPILATION_ERRORS +#ifdef CONFIRM_COMPILATION_ERRORS { owner integerTest = 10; owner> sharedPtrTest(new int(10)); } - #endif +#endif } diff --git a/tests/span_compatibility_tests.cpp b/tests/span_compatibility_tests.cpp index 361db84..56bd385 100644 --- a/tests/span_compatibility_tests.cpp +++ b/tests/span_compatibility_tests.cpp @@ -17,7 +17,7 @@ #include #include // for byte -#include // for span, span_iterator, operator==, operator!= +#include // for span, span_iterator, operator==, operator!= #include // for array #include // for ptrdiff_t diff --git a/tests/span_ext_tests.cpp b/tests/span_ext_tests.cpp index 4f07188..7ce4e51 100644 --- a/tests/span_ext_tests.cpp +++ b/tests/span_ext_tests.cpp @@ -16,27 +16,26 @@ #include +#include // for span and span_ext #include // for narrow_cast, at -#include // for operator==, operator!=, make_span -#include // for array -#include // for cerr -#include // for vector +#include // for array +#include // for cerr +#include // for vector using namespace std; using namespace gsl; -namespace -{ -static constexpr char deathstring[] = "Expected Death"; -} // namespace +#include "deathTestCommon.h" TEST(span_ext_test, make_span_from_pointer_length_constructor) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. from_pointer_length_constructor"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); + int arr[4] = {1, 2, 3, 4}; { @@ -57,7 +56,7 @@ TEST(span_ext_test, make_span_from_pointer_length_constructor) { int* p = nullptr; auto workaround_macro = [=]() { make_span(p, 2); }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } } @@ -88,273 +87,275 @@ TEST(span_ext_test, make_span_from_pointer_pointer_construction) } TEST(span_ext_test, make_span_from_array_constructor) - { - int arr[5] = {1, 2, 3, 4, 5}; - int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; - int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +{ + int arr[5] = {1, 2, 3, 4, 5}; + int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; + int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - { - const auto s = make_span(arr); - EXPECT_TRUE(s.size() == 5); - EXPECT_TRUE(s.data() == std::addressof(arr[0])); - } + { + const auto s = make_span(arr); + EXPECT_TRUE(s.size() == 5); + EXPECT_TRUE(s.data() == std::addressof(arr[0])); + } - { - const auto s = make_span(std::addressof(arr2d[0]), 1); - EXPECT_TRUE(s.size() == 1); - EXPECT_TRUE(s.data() == std::addressof(arr2d[0])); - } + { + const auto s = make_span(std::addressof(arr2d[0]), 1); + EXPECT_TRUE(s.size() == 1); + EXPECT_TRUE(s.data() == std::addressof(arr2d[0])); + } - { - const auto s = make_span(std::addressof(arr3d[0]), 1); - EXPECT_TRUE(s.size() == 1); - EXPECT_TRUE(s.data() == std::addressof(arr3d[0])); - } - } + { + const auto s = make_span(std::addressof(arr3d[0]), 1); + EXPECT_TRUE(s.size() == 1); + EXPECT_TRUE(s.data() == std::addressof(arr3d[0])); + } +} - TEST(span_ext_test, make_span_from_dynamic_array_constructor) - { - double(*arr)[3][4] = new double[100][3][4]; +TEST(span_ext_test, make_span_from_dynamic_array_constructor) +{ + double(*arr)[3][4] = new double[100][3][4]; - { - auto s = make_span(&arr[0][0][0], 10); - EXPECT_TRUE(s.size() == 10); - EXPECT_TRUE(s.data() == &arr[0][0][0]); - } + { + auto s = make_span(&arr[0][0][0], 10); + EXPECT_TRUE(s.size() == 10); + EXPECT_TRUE(s.data() == &arr[0][0][0]); + } - delete[] arr; - } + delete[] arr; +} - TEST(span_ext_test, make_span_from_std_array_constructor) - { - std::array arr = {1, 2, 3, 4}; +TEST(span_ext_test, make_span_from_std_array_constructor) +{ + std::array arr = {1, 2, 3, 4}; - { - auto s = make_span(arr); - EXPECT_TRUE(s.size() == arr.size()); - EXPECT_TRUE(s.data() == arr.data()); - } + { + auto s = make_span(arr); + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); + } - // This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590 - { - span s1 = make_span(arr); + // This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590 + { + span s1 = make_span(arr); - static span s2; - s2 = s1; + static span s2; + s2 = s1; - #if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \ - __GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__) - // Known to be broken in gcc 6.4 and 6.5 with optimizations - // Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116 - EXPECT_TRUE(s1.size() == 4); - EXPECT_TRUE(s2.size() == 0); - #else - EXPECT_TRUE(s1.size() == s2.size()); - #endif - } - } +#if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \ + __GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__) + // Known to be broken in gcc 6.4 and 6.5 with optimizations + // Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116 + EXPECT_TRUE(s1.size() == 4); + EXPECT_TRUE(s2.size() == 0); +#else + EXPECT_TRUE(s1.size() == s2.size()); +#endif + } +} - TEST(span_ext_test, make_span_from_const_std_array_constructor) - { - const std::array arr = {1, 2, 3, 4}; +TEST(span_ext_test, make_span_from_const_std_array_constructor) +{ + const std::array arr = {1, 2, 3, 4}; - { - auto s = make_span(arr); - EXPECT_TRUE(s.size() == arr.size()); - EXPECT_TRUE(s.data() == arr.data()); - } - } + { + auto s = make_span(arr); + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); + } +} - TEST(span_ext_test, make_span_from_std_array_const_constructor) - { - std::array arr = {1, 2, 3, 4}; +TEST(span_ext_test, make_span_from_std_array_const_constructor) +{ + std::array arr = {1, 2, 3, 4}; - { - auto s = make_span(arr); - EXPECT_TRUE(s.size() == arr.size()); - EXPECT_TRUE(s.data() == arr.data()); - } - } + { + auto s = make_span(arr); + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); + } +} - TEST(span_ext_test, make_span_from_container_constructor) - { - std::vector v = {1, 2, 3}; - const std::vector cv = v; +TEST(span_ext_test, make_span_from_container_constructor) +{ + std::vector v = {1, 2, 3}; + const std::vector cv = v; - { - auto s = make_span(v); - EXPECT_TRUE(s.size() == v.size()); - EXPECT_TRUE(s.data() == v.data()); + { + auto s = make_span(v); + EXPECT_TRUE(s.size() == v.size()); + EXPECT_TRUE(s.data() == v.data()); - auto cs = make_span(cv); - EXPECT_TRUE(cs.size() == cv.size()); - EXPECT_TRUE(cs.data() == cv.data()); - } - } + auto cs = make_span(cv); + EXPECT_TRUE(cs.size() == cv.size()); + EXPECT_TRUE(cs.data() == cv.data()); + } +} - TEST(span_test, interop_with_gsl_at) - { - int arr[5] = {1, 2, 3, 4, 5}; - span s{arr}; - EXPECT_TRUE(at(s, 0) == 1); - EXPECT_TRUE(at(s, 1) == 2); - } +TEST(span_test, interop_with_gsl_at) +{ + int arr[5] = {1, 2, 3, 4, 5}; + span s{arr}; + EXPECT_TRUE(at(s, 0) == 1); + EXPECT_TRUE(at(s, 1) == 2); +} - TEST(span_ext_test, iterator_free_functions) - { - int a[] = {1, 2, 3, 4}; - span s{a}; +TEST(span_ext_test, iterator_free_functions) +{ + int a[] = {1, 2, 3, 4}; + span s{a}; - EXPECT_TRUE((std::is_same::value)); - EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); - EXPECT_TRUE((std::is_same::value)); - EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); - EXPECT_TRUE((std::is_same::value)); - EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); - EXPECT_TRUE((std::is_same::value)); - EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); - EXPECT_TRUE(s.begin() == begin(s)); - EXPECT_TRUE(s.end() == end(s)); + EXPECT_TRUE(s.begin() == begin(s)); + EXPECT_TRUE(s.end() == end(s)); - EXPECT_TRUE(s.rbegin() == rbegin(s)); - EXPECT_TRUE(s.rend() == rend(s)); + EXPECT_TRUE(s.rbegin() == rbegin(s)); + EXPECT_TRUE(s.rend() == rend(s)); - EXPECT_TRUE(s.begin() == cbegin(s)); - EXPECT_TRUE(s.end() == cend(s)); + EXPECT_TRUE(s.begin() == cbegin(s)); + EXPECT_TRUE(s.end() == cend(s)); - EXPECT_TRUE(s.rbegin() == crbegin(s)); - EXPECT_TRUE(s.rend() == crend(s)); - } + EXPECT_TRUE(s.rbegin() == crbegin(s)); + EXPECT_TRUE(s.rend() == crend(s)); +} - TEST(span_ext_test, ssize_free_function) - { - int a[] = {1, 2, 3, 4}; - span s{a}; +TEST(span_ext_test, ssize_free_function) +{ + int a[] = {1, 2, 3, 4}; + span s{a}; - EXPECT_FALSE((std::is_same::value)); - EXPECT_TRUE(s.size() == static_cast(ssize(s))); - } + EXPECT_FALSE((std::is_same::value)); + EXPECT_TRUE(s.size() == static_cast(ssize(s))); +} - TEST(span_ext_test, comparison_operators) - { - { - span s1; - span s2; - EXPECT_TRUE(s1 == s2); - EXPECT_FALSE(s1 != s2); - EXPECT_FALSE(s1 < s2); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s1 >= s2); - EXPECT_TRUE(s2 == s1); - EXPECT_FALSE(s2 != s1); - EXPECT_FALSE(s2 != s1); - EXPECT_TRUE(s2 <= s1); - EXPECT_FALSE(s2 > s1); - EXPECT_TRUE(s2 >= s1); - } +#ifndef GSL_KERNEL_MODE +TEST(span_ext_test, comparison_operators) +{ + { + span s1; + span s2; + EXPECT_TRUE(s1 == s2); + EXPECT_FALSE(s1 != s2); + EXPECT_FALSE(s1 < s2); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s1 >= s2); + EXPECT_TRUE(s2 == s1); + EXPECT_FALSE(s2 != s1); + EXPECT_FALSE(s2 != s1); + EXPECT_TRUE(s2 <= s1); + EXPECT_FALSE(s2 > s1); + EXPECT_TRUE(s2 >= s1); + } - { - int arr[] = {2, 1}; - span s1 = arr; - span s2 = arr; + { + int arr[] = {2, 1}; + span s1 = arr; + span s2 = arr; - EXPECT_TRUE(s1 == s2); - EXPECT_FALSE(s1 != s2); - EXPECT_FALSE(s1 < s2); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s1 >= s2); - EXPECT_TRUE(s2 == s1); - EXPECT_FALSE(s2 != s1); - EXPECT_FALSE(s2 < s1); - EXPECT_TRUE(s2 <= s1); - EXPECT_FALSE(s2 > s1); - EXPECT_TRUE(s2 >= s1); - } + EXPECT_TRUE(s1 == s2); + EXPECT_FALSE(s1 != s2); + EXPECT_FALSE(s1 < s2); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s1 >= s2); + EXPECT_TRUE(s2 == s1); + EXPECT_FALSE(s2 != s1); + EXPECT_FALSE(s2 < s1); + EXPECT_TRUE(s2 <= s1); + EXPECT_FALSE(s2 > s1); + EXPECT_TRUE(s2 >= s1); + } - { - int arr[] = {2, 1}; // bigger + { + int arr[] = {2, 1}; // bigger - span s1; - span s2 = arr; + span s1; + span s2 = arr; - EXPECT_TRUE(s1 != s2); - EXPECT_TRUE(s2 != s1); - EXPECT_FALSE(s1 == s2); - EXPECT_FALSE(s2 == s1); - EXPECT_TRUE(s1 < s2); - EXPECT_FALSE(s2 < s1); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s2 <= s1); - EXPECT_TRUE(s2 > s1); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s2 >= s1); - EXPECT_FALSE(s1 >= s2); - } + EXPECT_TRUE(s1 != s2); + EXPECT_TRUE(s2 != s1); + EXPECT_FALSE(s1 == s2); + EXPECT_FALSE(s2 == s1); + EXPECT_TRUE(s1 < s2); + EXPECT_FALSE(s2 < s1); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s2 <= s1); + EXPECT_TRUE(s2 > s1); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s2 >= s1); + EXPECT_FALSE(s1 >= s2); + } - { - int arr1[] = {1, 2}; - int arr2[] = {1, 2}; - span s1 = arr1; - span s2 = arr2; + { + int arr1[] = {1, 2}; + int arr2[] = {1, 2}; + span s1 = arr1; + span s2 = arr2; - EXPECT_TRUE(s1 == s2); - EXPECT_FALSE(s1 != s2); - EXPECT_FALSE(s1 < s2); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s1 >= s2); - EXPECT_TRUE(s2 == s1); - EXPECT_FALSE(s2 != s1); - EXPECT_FALSE(s2 < s1); - EXPECT_TRUE(s2 <= s1); - EXPECT_FALSE(s2 > s1); - EXPECT_TRUE(s2 >= s1); - } + EXPECT_TRUE(s1 == s2); + EXPECT_FALSE(s1 != s2); + EXPECT_FALSE(s1 < s2); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s1 >= s2); + EXPECT_TRUE(s2 == s1); + EXPECT_FALSE(s2 != s1); + EXPECT_FALSE(s2 < s1); + EXPECT_TRUE(s2 <= s1); + EXPECT_FALSE(s2 > s1); + EXPECT_TRUE(s2 >= s1); + } - { - int arr[] = {1, 2, 3}; + { + int arr[] = {1, 2, 3}; - span s1 = {&arr[0], 2}; // shorter - span s2 = arr; // longer + span s1 = {&arr[0], 2}; // shorter + span s2 = arr; // longer - EXPECT_TRUE(s1 != s2); - EXPECT_TRUE(s2 != s1); - EXPECT_FALSE(s1 == s2); - EXPECT_FALSE(s2 == s1); - EXPECT_TRUE(s1 < s2); - EXPECT_FALSE(s2 < s1); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s2 <= s1); - EXPECT_TRUE(s2 > s1); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s2 >= s1); - EXPECT_FALSE(s1 >= s2); - } + EXPECT_TRUE(s1 != s2); + EXPECT_TRUE(s2 != s1); + EXPECT_FALSE(s1 == s2); + EXPECT_FALSE(s2 == s1); + EXPECT_TRUE(s1 < s2); + EXPECT_FALSE(s2 < s1); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s2 <= s1); + EXPECT_TRUE(s2 > s1); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s2 >= s1); + EXPECT_FALSE(s1 >= s2); + } - { - int arr1[] = {1, 2}; // smaller - int arr2[] = {2, 1}; // bigger + { + int arr1[] = {1, 2}; // smaller + int arr2[] = {2, 1}; // bigger - span s1 = arr1; - span s2 = arr2; + span s1 = arr1; + span s2 = arr2; - EXPECT_TRUE(s1 != s2); - EXPECT_TRUE(s2 != s1); - EXPECT_FALSE(s1 == s2); - EXPECT_FALSE(s2 == s1); - EXPECT_TRUE(s1 < s2); - EXPECT_FALSE(s2 < s1); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s2 <= s1); - EXPECT_TRUE(s2 > s1); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s2 >= s1); - EXPECT_FALSE(s1 >= s2); - } - } + EXPECT_TRUE(s1 != s2); + EXPECT_TRUE(s2 != s1); + EXPECT_FALSE(s1 == s2); + EXPECT_FALSE(s2 == s1); + EXPECT_TRUE(s1 < s2); + EXPECT_FALSE(s2 < s1); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s2 <= s1); + EXPECT_TRUE(s2 > s1); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s2 >= s1); + EXPECT_FALSE(s1 >= s2); + } +} +#endif // GSL_KERNEL_MODE diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index b845d07..1e0222e 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -17,19 +17,19 @@ #include #include // for byte +#include // for span, span_iterator, operator==, operator!= #include // for narrow_cast, at -#include // for span, span_iterator, operator==, operator!= #include // for array +#include // for ptrdiff_t #include // for ptrdiff_t #include // for reverse_iterator, operator-, operator== #include // for unique_ptr, shared_ptr, make_unique, allo... #include // for match_results, sub_match, match_results<>... -#include // for ptrdiff_t #include // for string #include // for integral_constant<>::value, is_default_co... -#include // for vector #include +#include // for vector // the string_view include and macro are used in the deduction guide verification #if (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L)) @@ -41,12 +41,13 @@ #endif // __has_include #endif // (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L)) +#include "deathTestCommon.h" + using namespace std; using namespace gsl; namespace { -static constexpr char deathstring[] = "Expected Death"; struct BaseClass { @@ -111,10 +112,12 @@ TEST(span_test, size_optimization) TEST(span_test, from_nullptr_size_constructor) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. from_nullptr_size_constructor"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); + { span s{nullptr, narrow_cast::size_type>(0)}; EXPECT_TRUE(s.size() == 0); @@ -128,21 +131,21 @@ TEST(span_test, from_nullptr_size_constructor) auto workaround_macro = []() { const span s{nullptr, narrow_cast::size_type>(0)}; }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } { auto workaround_macro = []() { const span s{nullptr, 1}; }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); auto const_workaround_macro = []() { const span s{nullptr, 1}; }; - EXPECT_DEATH(const_workaround_macro(), deathstring); + EXPECT_DEATH(const_workaround_macro(), expected); } { auto workaround_macro = []() { const span s{nullptr, 1}; }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); auto const_workaround_macro = []() { const span s{nullptr, 1}; }; - EXPECT_DEATH(const_workaround_macro(), deathstring); + EXPECT_DEATH(const_workaround_macro(), expected); } { span s{nullptr, narrow_cast::size_type>(0)}; @@ -157,10 +160,12 @@ TEST(span_test, from_nullptr_size_constructor) TEST(span_test, from_pointer_length_constructor) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. from_pointer_length_constructor"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); + int arr[4] = {1, 2, 3, 4}; { @@ -171,8 +176,7 @@ TEST(span_test, from_pointer_length_constructor) EXPECT_TRUE(s.size() == narrow_cast(i)); EXPECT_TRUE(s.data() == &arr[0]); EXPECT_TRUE(s.empty() == (i == 0)); - for (int j = 0; j < i; ++j) - EXPECT_TRUE(arr[j] == s[narrow_cast(j)]); + for (int j = 0; j < i; ++j) EXPECT_TRUE(arr[j] == s[narrow_cast(j)]); } { span s = {&arr[i], 4 - narrow_cast(i)}; @@ -204,7 +208,7 @@ TEST(span_test, from_pointer_length_constructor) { int* p = nullptr; auto workaround_macro = [=]() { const span s{p, 2}; }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } } @@ -242,14 +246,14 @@ TEST(span_test, from_pointer_pointer_construction) // this will fail the std::distance() precondition, which asserts on MSVC debug builds //{ // auto workaround_macro = [&]() { span s{&arr[1], &arr[0]}; }; - // EXPECT_DEATH(workaround_macro(), deathstring); + // EXPECT_DEATH(workaround_macro(), expected); //} // this will fail the std::distance() precondition, which asserts on MSVC debug builds //{ // int* p = nullptr; // auto workaround_macro = [&]() { span s{&arr[0], p}; }; - // EXPECT_DEATH(workaround_macro(), deathstring); + // EXPECT_DEATH(workaround_macro(), expected); //} { @@ -270,897 +274,912 @@ TEST(span_test, from_pointer_pointer_construction) //{ // int* p = nullptr; // auto workaround_macro = [&]() { span s{&arr[0], p}; }; - // EXPECT_DEATH(workaround_macro(), deathstring); + // EXPECT_DEATH(workaround_macro(), expected); //} } TEST(span_test, from_array_constructor) - { - int arr[5] = {1, 2, 3, 4, 5}; +{ + int arr[5] = {1, 2, 3, 4, 5}; - { - const span s{arr}; - EXPECT_TRUE(s.size() == 5); - EXPECT_TRUE(s.data() == &arr[0]); - } + { + const span s{arr}; + EXPECT_TRUE(s.size() == 5); + EXPECT_TRUE(s.data() == &arr[0]); + } - { - const span s{arr}; - EXPECT_TRUE(s.size() == 5); - EXPECT_TRUE(s.data() == &arr[0]); - } + { + const span s{arr}; + EXPECT_TRUE(s.size() == 5); + EXPECT_TRUE(s.data() == &arr[0]); + } - int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; + int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; - #ifdef CONFIRM_COMPILATION_ERRORS - { - span s{arr}; - } +#ifdef CONFIRM_COMPILATION_ERRORS + { + span s{arr}; + } - { - span s{arr}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == &arr[0]); - } + { + span s{arr}; + EXPECT_TRUE(s.size() == 0); + EXPECT_TRUE(s.data() == &arr[0]); + } - { - span s{arr2d}; - EXPECT_TRUE(s.size() == 6); - EXPECT_TRUE(s.data() == &arr2d[0][0]); - EXPECT_TRUE(s[0] == 1); - EXPECT_TRUE(s[5] == 6); - } + { + span s{arr2d}; + EXPECT_TRUE(s.size() == 6); + EXPECT_TRUE(s.data() == &arr2d[0][0]); + EXPECT_TRUE(s[0] == 1); + EXPECT_TRUE(s[5] == 6); + } - { - span s{arr2d}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == &arr2d[0][0]); - } + { + span s{arr2d}; + EXPECT_TRUE(s.size() == 0); + EXPECT_TRUE(s.data() == &arr2d[0][0]); + } - { - span s{arr2d}; - } - #endif - { - const span s{std::addressof(arr2d[0]), 1}; - EXPECT_TRUE(s.size() == 1); - EXPECT_TRUE(s.data() == std::addressof(arr2d[0])); - } + { + span s{arr2d}; + } +#endif + { + const span s{std::addressof(arr2d[0]), 1}; + EXPECT_TRUE(s.size() == 1); + EXPECT_TRUE(s.data() == std::addressof(arr2d[0])); + } - int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - #ifdef CONFIRM_COMPILATION_ERRORS - { - span s{arr3d}; - EXPECT_TRUE(s.size() == 12); - EXPECT_TRUE(s.data() == &arr3d[0][0][0]); - EXPECT_TRUE(s[0] == 1); - EXPECT_TRUE(s[11] == 12); - } +#ifdef CONFIRM_COMPILATION_ERRORS + { + span s{arr3d}; + EXPECT_TRUE(s.size() == 12); + EXPECT_TRUE(s.data() == &arr3d[0][0][0]); + EXPECT_TRUE(s[0] == 1); + EXPECT_TRUE(s[11] == 12); + } - { - span s{arr3d}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == &arr3d[0][0][0]); - } + { + span s{arr3d}; + EXPECT_TRUE(s.size() == 0); + EXPECT_TRUE(s.data() == &arr3d[0][0][0]); + } - { - span s{arr3d}; - } + { + span s{arr3d}; + } - { - span s{arr3d}; - EXPECT_TRUE(s.size() == 12); - EXPECT_TRUE(s.data() == &arr3d[0][0][0]); - EXPECT_TRUE(s[0] == 1); - EXPECT_TRUE(s[5] == 6); - } - #endif - { - const span s{std::addressof(arr3d[0]), 1}; - EXPECT_TRUE(s.size() == 1); - } + { + span s{arr3d}; + EXPECT_TRUE(s.size() == 12); + EXPECT_TRUE(s.data() == &arr3d[0][0][0]); + EXPECT_TRUE(s[0] == 1); + EXPECT_TRUE(s[5] == 6); + } +#endif + { + const span s{std::addressof(arr3d[0]), 1}; + EXPECT_TRUE(s.size() == 1); + } - AddressOverloaded ao_arr[5] = {}; + AddressOverloaded ao_arr[5] = {}; - { - const span s{ao_arr}; - EXPECT_TRUE(s.size() == 5); - EXPECT_TRUE(s.data() == std::addressof(ao_arr[0])); - } - } + { + const span s{ao_arr}; + EXPECT_TRUE(s.size() == 5); + EXPECT_TRUE(s.data() == std::addressof(ao_arr[0])); + } +} - TEST(span_test, from_dynamic_array_constructor) - { - double(*arr)[3][4] = new double[100][3][4]; +TEST(span_test, from_dynamic_array_constructor) +{ + double(*arr)[3][4] = new double[100][3][4]; - { - span s(&arr[0][0][0], 10); - EXPECT_TRUE(s.size() == 10); - EXPECT_TRUE(s.data() == &arr[0][0][0]); - } + { + span s(&arr[0][0][0], 10); + EXPECT_TRUE(s.size() == 10); + EXPECT_TRUE(s.data() == &arr[0][0][0]); + } - delete[] arr; - } + delete[] arr; +} - TEST(span_test, from_std_array_constructor) - { - std::array arr = {1, 2, 3, 4}; +TEST(span_test, from_std_array_constructor) +{ + std::array arr = {1, 2, 3, 4}; - { - span s{arr}; - EXPECT_TRUE(s.size() == arr.size()); - EXPECT_TRUE(s.data() == arr.data()); + { + span s{arr}; + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); - span cs{arr}; - EXPECT_TRUE(cs.size() == arr.size()); - EXPECT_TRUE(cs.data() == arr.data()); - } + span cs{arr}; + EXPECT_TRUE(cs.size() == arr.size()); + EXPECT_TRUE(cs.data() == arr.data()); + } - { - span s{arr}; - EXPECT_TRUE(s.size() == arr.size()); - EXPECT_TRUE(s.data() == arr.data()); + { + span s{arr}; + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); - span cs{arr}; - EXPECT_TRUE(cs.size() == arr.size()); - EXPECT_TRUE(cs.data() == arr.data()); - } + span cs{arr}; + EXPECT_TRUE(cs.size() == arr.size()); + EXPECT_TRUE(cs.data() == arr.data()); + } - { - std::array empty_arr{}; - span s{empty_arr}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.empty()); - } + { + std::array empty_arr{}; + span s{empty_arr}; + EXPECT_TRUE(s.size() == 0); + EXPECT_TRUE(s.empty()); + } - std::array ao_arr{}; + std::array ao_arr{}; - { - span fs{ao_arr}; - EXPECT_TRUE(fs.size() == ao_arr.size()); - EXPECT_TRUE(ao_arr.data() == fs.data()); - } + { + span fs{ao_arr}; + EXPECT_TRUE(fs.size() == ao_arr.size()); + EXPECT_TRUE(ao_arr.data() == fs.data()); + } - #ifdef CONFIRM_COMPILATION_ERRORS - { - span s{arr}; - EXPECT_TRUE(s.size() == 2); - EXPECT_TRUE(s.data() == arr.data()); +#ifdef CONFIRM_COMPILATION_ERRORS + { + span s{arr}; + EXPECT_TRUE(s.size() == 2); + EXPECT_TRUE(s.data() == arr.data()); - span cs{arr}; - EXPECT_TRUE(cs.size() == 2); - EXPECT_TRUE(cs.data() == arr.data()); - } + span cs{arr}; + EXPECT_TRUE(cs.size() == 2); + EXPECT_TRUE(cs.data() == arr.data()); + } - { - span s{arr}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == arr.data()); + { + span s{arr}; + EXPECT_TRUE(s.size() == 0); + EXPECT_TRUE(s.data() == arr.data()); - span cs{arr}; - EXPECT_TRUE(cs.size() == 0); - EXPECT_TRUE(cs.data() == arr.data()); - } + span cs{arr}; + EXPECT_TRUE(cs.size() == 0); + EXPECT_TRUE(cs.data() == arr.data()); + } - { - span s{arr}; - } + { + span s{arr}; + } - { - auto get_an_array = []() -> std::array { return {1, 2, 3, 4}; }; - auto take_a_span = [](span s) { static_cast(s); }; - // try to take a temporary std::array - take_a_span(get_an_array()); - } - #endif + { + auto get_an_array = []() -> std::array { return {1, 2, 3, 4}; }; + auto take_a_span = [](span s) { static_cast(s); }; + // try to take a temporary std::array + take_a_span(get_an_array()); + } +#endif - { - auto get_an_array = []() -> std::array { return {1, 2, 3, 4}; }; - auto take_a_span = [](span s) { static_cast(s); }; - // try to take a temporary std::array - take_a_span(get_an_array()); - } - } + { + auto get_an_array = []() -> std::array { return {1, 2, 3, 4}; }; + auto take_a_span = [](span s) { static_cast(s); }; + // try to take a temporary std::array + take_a_span(get_an_array()); + } +} - TEST(span_test, from_const_std_array_constructor) - { - const std::array arr = {1, 2, 3, 4}; +TEST(span_test, from_const_std_array_constructor) +{ + const std::array arr = {1, 2, 3, 4}; - { - span s{arr}; - EXPECT_TRUE(s.size() == arr.size()); - EXPECT_TRUE(s.data() == arr.data()); - } + { + span s{arr}; + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); + } - { - span s{arr}; - EXPECT_TRUE(s.size() == arr.size()); - EXPECT_TRUE(s.data() == arr.data()); - } + { + span s{arr}; + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); + } - const std::array ao_arr{}; + const std::array ao_arr{}; - { - span s{ao_arr}; - EXPECT_TRUE(s.size() == ao_arr.size()); - EXPECT_TRUE(s.data() == ao_arr.data()); - } + { + span s{ao_arr}; + EXPECT_TRUE(s.size() == ao_arr.size()); + EXPECT_TRUE(s.data() == ao_arr.data()); + } - #ifdef CONFIRM_COMPILATION_ERRORS - { - span s{arr}; - EXPECT_TRUE(s.size() == 2); - EXPECT_TRUE(s.data() == arr.data()); - } +#ifdef CONFIRM_COMPILATION_ERRORS + { + span s{arr}; + EXPECT_TRUE(s.size() == 2); + EXPECT_TRUE(s.data() == arr.data()); + } - { - span s{arr}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == arr.data()); - } + { + span s{arr}; + EXPECT_TRUE(s.size() == 0); + EXPECT_TRUE(s.data() == arr.data()); + } - { - span s{arr}; - } - #endif + { + span s{arr}; + } +#endif - { - auto get_an_array = []() -> const std::array { return {1, 2, 3, 4}; }; - auto take_a_span = [](span s) { static_cast(s); }; - // try to take a temporary std::array - take_a_span(get_an_array()); - } - } + { + auto get_an_array = []() -> const std::array { return {1, 2, 3, 4}; }; + auto take_a_span = [](span s) { static_cast(s); }; + // try to take a temporary std::array + take_a_span(get_an_array()); + } +} - TEST(span_test, from_std_array_const_constructor) - { - std::array arr = {1, 2, 3, 4}; +TEST(span_test, from_std_array_const_constructor) +{ + std::array arr = {1, 2, 3, 4}; - { - span s{arr}; - EXPECT_TRUE(s.size() == arr.size()); - EXPECT_TRUE(s.data() == arr.data()); - } + { + span s{arr}; + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); + } - { - span s{arr}; - EXPECT_TRUE(s.size() == arr.size()); - EXPECT_TRUE(s.data() == arr.data()); - } + { + span s{arr}; + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); + } - #ifdef CONFIRM_COMPILATION_ERRORS - { - span s{arr}; - EXPECT_TRUE(s.size() == 2); - EXPECT_TRUE(s.data() == arr.data()); - } +#ifdef CONFIRM_COMPILATION_ERRORS + { + span s{arr}; + EXPECT_TRUE(s.size() == 2); + EXPECT_TRUE(s.data() == arr.data()); + } - { - span s{arr}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == arr.data()); - } + { + span s{arr}; + EXPECT_TRUE(s.size() == 0); + EXPECT_TRUE(s.data() == arr.data()); + } - { - span s{arr}; - } + { + span s{arr}; + } - { - span s{arr}; - } - #endif - } + { + span s{arr}; + } +#endif +} - TEST(span_test, from_container_constructor) - { - std::vector v = {1, 2, 3}; - const std::vector cv = v; +TEST(span_test, from_container_constructor) +{ + std::vector v = {1, 2, 3}; + const std::vector cv = v; - { - span s{v}; - EXPECT_TRUE(s.size() == v.size()); - EXPECT_TRUE(s.data() == v.data()); + { + span s{v}; + EXPECT_TRUE(s.size() == v.size()); + EXPECT_TRUE(s.data() == v.data()); - span cs{v}; - EXPECT_TRUE(cs.size() == v.size()); - EXPECT_TRUE(cs.data() == v.data()); - } + span cs{v}; + EXPECT_TRUE(cs.size() == v.size()); + EXPECT_TRUE(cs.data() == v.data()); + } - std::string str = "hello"; - const std::string cstr = "hello"; + std::string str = "hello"; + const std::string cstr = "hello"; - { - #ifdef CONFIRM_COMPILATION_ERRORS - span s{str}; - EXPECT_TRUE(s.size() == str.size()); + { +#ifdef CONFIRM_COMPILATION_ERRORS + span s{str}; + EXPECT_TRUE(s.size() == str.size()); EXPECT_TRUE(s.data() == str.data())); - #endif +#endif span cs{str}; EXPECT_TRUE(cs.size() == str.size()); EXPECT_TRUE(cs.data() == str.data()); - } + } - { - #ifdef CONFIRM_COMPILATION_ERRORS - span s{cstr}; - #endif - span cs{cstr}; - EXPECT_TRUE(cs.size() == cstr.size()); - EXPECT_TRUE(cs.data() == cstr.data()); - } + { +#ifdef CONFIRM_COMPILATION_ERRORS + span s{cstr}; +#endif + span cs{cstr}; + EXPECT_TRUE(cs.size() == cstr.size()); + EXPECT_TRUE(cs.data() == cstr.data()); + } - { - #ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_vector = []() -> std::vector { return {}; }; - auto use_span = [](span s) { static_cast(s); }; - use_span(get_temp_vector()); - #endif - } + { +#ifdef CONFIRM_COMPILATION_ERRORS + auto get_temp_vector = []() -> std::vector { return {}; }; + auto use_span = [](span s) { static_cast(s); }; + use_span(get_temp_vector()); +#endif + } - { - auto get_temp_vector = []() -> std::vector { return {}; }; - auto use_span = [](span s) { static_cast(s); }; - use_span(get_temp_vector()); - } + { + auto get_temp_vector = []() -> std::vector { return {}; }; + auto use_span = [](span s) { static_cast(s); }; + use_span(get_temp_vector()); + } - { - #ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_string = []() -> std::string { return {}; }; - auto use_span = [](span s) { static_cast(s); }; - use_span(get_temp_string()); - #endif - } + { +#ifdef CONFIRM_COMPILATION_ERRORS + auto get_temp_string = []() -> std::string { return {}; }; + auto use_span = [](span s) { static_cast(s); }; + use_span(get_temp_string()); +#endif + } - { - auto get_temp_string = []() -> std::string { return {}; }; - auto use_span = [](span s) { static_cast(s); }; - use_span(get_temp_string()); - } + { + auto get_temp_string = []() -> std::string { return {}; }; + auto use_span = [](span s) { static_cast(s); }; + use_span(get_temp_string()); + } - { - #ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_vector = []() -> const std::vector { return {}; }; - auto use_span = [](span s) { static_cast(s); }; - use_span(get_temp_vector()); - #endif - } + { +#ifdef CONFIRM_COMPILATION_ERRORS + auto get_temp_vector = []() -> const std::vector { return {}; }; + auto use_span = [](span s) { static_cast(s); }; + use_span(get_temp_vector()); +#endif + } - { - auto get_temp_string = []() -> const std::string { return {}; }; - auto use_span = [](span s) { static_cast(s); }; - use_span(get_temp_string()); - } + { + auto get_temp_string = []() -> const std::string { return {}; }; + auto use_span = [](span s) { static_cast(s); }; + use_span(get_temp_string()); + } - { - #ifdef CONFIRM_COMPILATION_ERRORS - std::map m; - span s{m}; - #endif - } - } + { +#ifdef CONFIRM_COMPILATION_ERRORS + std::map m; + span s{m}; +#endif + } +} - TEST(span_test, from_convertible_span_constructor){{span avd; - span avcd = avd; - static_cast(avcd); - } +TEST(span_test, from_convertible_span_constructor){{span avd; +span avcd = avd; +static_cast(avcd); +} - { - #ifdef CONFIRM_COMPILATION_ERRORS - span avd; - span avb = avd; - static_cast(avb); - #endif - } +{ +#ifdef CONFIRM_COMPILATION_ERRORS + span avd; + span avb = avd; + static_cast(avb); +#endif +} - #ifdef CONFIRM_COMPILATION_ERRORS - { - span s; - span s2 = s; - static_cast(s2); - } +#ifdef CONFIRM_COMPILATION_ERRORS +{ + span s; + span s2 = s; + static_cast(s2); +} - { - span s; - span s2 = s; - static_cast(s2); - } +{ + span s; + span s2 = s; + static_cast(s2); +} - { - span s; - span s2 = s; - static_cast(s2); - } - #endif - } +{ + span s; + span s2 = s; + static_cast(s2); +} +#endif +} - TEST(span_test, copy_move_and_assignment) - { - span s1; - EXPECT_TRUE(s1.empty()); +TEST(span_test, copy_move_and_assignment) +{ + span s1; + EXPECT_TRUE(s1.empty()); - int arr[] = {3, 4, 5}; + int arr[] = {3, 4, 5}; - span s2 = arr; - EXPECT_TRUE(s2.size() == 3); - EXPECT_TRUE(s2.data() == &arr[0]); + span s2 = arr; + EXPECT_TRUE(s2.size() == 3); + EXPECT_TRUE(s2.data() == &arr[0]); - s2 = s1; - EXPECT_TRUE(s2.empty()); + s2 = s1; + EXPECT_TRUE(s2.empty()); - auto get_temp_span = [&]() -> span { return {&arr[1], 2}; }; - auto use_span = [&](span s) { - EXPECT_TRUE(s.size() == 2); - EXPECT_TRUE(s.data() == &arr[1]); - }; use_span(get_temp_span()); + auto get_temp_span = [&]() -> span { return {&arr[1], 2}; }; + auto use_span = [&](span s) { + EXPECT_TRUE(s.size() == 2); + EXPECT_TRUE(s.data() == &arr[1]); + }; + use_span(get_temp_span()); - s1 = get_temp_span(); - EXPECT_TRUE(s1.size() == 2); - EXPECT_TRUE(s1.data() == &arr[1]); - } + s1 = get_temp_span(); + EXPECT_TRUE(s1.size() == 2); + EXPECT_TRUE(s1.data() == &arr[1]); +} - TEST(span_test, first) - { - std::set_terminate([] { +TEST(span_test, first) +{ + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. first"; std::abort(); }); - int arr[5] = {1, 2, 3, 4, 5}; + const auto expected = GetExpectedDeathString(terminateHandler); - { - span av = arr; - EXPECT_TRUE(av.first<2>().size() == 2); - EXPECT_TRUE(av.first(2).size() == 2); - } + int arr[5] = {1, 2, 3, 4, 5}; - { - span av = arr; - EXPECT_TRUE(av.first<0>().size() == 0); - EXPECT_TRUE(av.first(0).size() == 0); - } + { + span av = arr; + EXPECT_TRUE(av.first<2>().size() == 2); + EXPECT_TRUE(av.first(2).size() == 2); + } - { - span av = arr; - EXPECT_TRUE(av.first<5>().size() == 5); - EXPECT_TRUE(av.first(5).size() == 5); - } + { + span av = arr; + EXPECT_TRUE(av.first<0>().size() == 0); + EXPECT_TRUE(av.first(0).size() == 0); + } - { - span av = arr; - #ifdef CONFIRM_COMPILATION_ERRORS - EXPECT_TRUE(av.first<6>().size() == 6); - EXPECT_TRUE(av.first<-1>().size() == -1); - #endif - EXPECT_DEATH(av.first(6).size(), deathstring); - } + { + span av = arr; + EXPECT_TRUE(av.first<5>().size() == 5); + EXPECT_TRUE(av.first(5).size() == 5); + } - { - span av; - EXPECT_TRUE(av.first<0>().size() == 0); - EXPECT_TRUE(av.first(0).size() == 0); - } - } + { + span av = arr; +#ifdef CONFIRM_COMPILATION_ERRORS + EXPECT_TRUE(av.first<6>().size() == 6); + EXPECT_TRUE(av.first<-1>().size() == -1); +#endif + EXPECT_DEATH(av.first(6).size(), expected); + } - TEST(span_test, last) - { - std::set_terminate([] { + { + span av; + EXPECT_TRUE(av.first<0>().size() == 0); + EXPECT_TRUE(av.first(0).size() == 0); + } +} + +TEST(span_test, last) +{ + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. last"; std::abort(); }); - int arr[5] = {1, 2, 3, 4, 5}; + const auto expected = GetExpectedDeathString(terminateHandler); - { - span av = arr; - EXPECT_TRUE(av.last<2>().size() == 2); - EXPECT_TRUE(av.last(2).size() == 2); - } + int arr[5] = {1, 2, 3, 4, 5}; - { - span av = arr; - EXPECT_TRUE(av.last<0>().size() == 0); - EXPECT_TRUE(av.last(0).size() == 0); - } + { + span av = arr; + EXPECT_TRUE(av.last<2>().size() == 2); + EXPECT_TRUE(av.last(2).size() == 2); + } - { - span av = arr; - EXPECT_TRUE(av.last<5>().size() == 5); - EXPECT_TRUE(av.last(5).size() == 5); - } + { + span av = arr; + EXPECT_TRUE(av.last<0>().size() == 0); + EXPECT_TRUE(av.last(0).size() == 0); + } - { - span av = arr; - #ifdef CONFIRM_COMPILATION_ERRORS - EXPECT_TRUE(av.last<6>().size() == 6); - #endif - EXPECT_DEATH(av.last(6).size(), deathstring); - } + { + span av = arr; + EXPECT_TRUE(av.last<5>().size() == 5); + EXPECT_TRUE(av.last(5).size() == 5); + } - { - span av; - EXPECT_TRUE(av.last<0>().size() == 0); - EXPECT_TRUE(av.last(0).size() == 0); - } - } + { + span av = arr; +#ifdef CONFIRM_COMPILATION_ERRORS + EXPECT_TRUE(av.last<6>().size() == 6); +#endif + EXPECT_DEATH(av.last(6).size(), expected); + } - TEST(span_test, subspan) - { - std::set_terminate([] { + { + span av; + EXPECT_TRUE(av.last<0>().size() == 0); + EXPECT_TRUE(av.last(0).size() == 0); + } +} + +TEST(span_test, subspan) +{ + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. subspan"; std::abort(); }); - int arr[5] = {1, 2, 3, 4, 5}; + const auto expected = GetExpectedDeathString(terminateHandler); - { - span av = arr; - EXPECT_TRUE((av.subspan<2, 2>().size()) == 2); - EXPECT_TRUE(decltype(av.subspan<2, 2>())::extent == 2); - EXPECT_TRUE(av.subspan(2, 2).size() == 2); - EXPECT_TRUE(av.subspan(2, 3).size() == 3); - } + int arr[5] = {1, 2, 3, 4, 5}; - { - span av = arr; - EXPECT_TRUE((av.subspan<0, 0>().size()) == 0); - EXPECT_TRUE(decltype(av.subspan<0, 0>())::extent == 0); - EXPECT_TRUE(av.subspan(0, 0).size() == 0); - } + { + span av = arr; + EXPECT_TRUE((av.subspan<2, 2>().size()) == 2); + EXPECT_TRUE(decltype(av.subspan<2, 2>())::extent == 2); + EXPECT_TRUE(av.subspan(2, 2).size() == 2); + EXPECT_TRUE(av.subspan(2, 3).size() == 3); + } - { - span av = arr; - EXPECT_TRUE((av.subspan<0, 5>().size()) == 5); - EXPECT_TRUE(decltype(av.subspan<0, 5>())::extent == 5); - EXPECT_TRUE(av.subspan(0, 5).size() == 5); + { + span av = arr; + EXPECT_TRUE((av.subspan<0, 0>().size()) == 0); + EXPECT_TRUE(decltype(av.subspan<0, 0>())::extent == 0); + EXPECT_TRUE(av.subspan(0, 0).size() == 0); + } - EXPECT_DEATH(av.subspan(0, 6).size(), deathstring); - EXPECT_DEATH(av.subspan(1, 5).size(), deathstring); - } + { + span av = arr; + EXPECT_TRUE((av.subspan<0, 5>().size()) == 5); + EXPECT_TRUE(decltype(av.subspan<0, 5>())::extent == 5); + EXPECT_TRUE(av.subspan(0, 5).size() == 5); - { - span av = arr; - EXPECT_TRUE((av.subspan<4, 0>().size()) == 0); - EXPECT_TRUE(decltype(av.subspan<4, 0>())::extent == 0); - EXPECT_TRUE(av.subspan(4, 0).size() == 0); - EXPECT_TRUE(av.subspan(5, 0).size() == 0); - EXPECT_DEATH(av.subspan(6, 0).size(), deathstring); - } + EXPECT_DEATH(av.subspan(0, 6).size(), expected); + EXPECT_DEATH(av.subspan(1, 5).size(), expected); + } - { - span av = arr; - EXPECT_TRUE(av.subspan<1>().size() == 4); - EXPECT_TRUE(decltype(av.subspan<1>())::extent == 4); - } + { + span av = arr; + EXPECT_TRUE((av.subspan<4, 0>().size()) == 0); + EXPECT_TRUE(decltype(av.subspan<4, 0>())::extent == 0); + EXPECT_TRUE(av.subspan(4, 0).size() == 0); + EXPECT_TRUE(av.subspan(5, 0).size() == 0); + EXPECT_DEATH(av.subspan(6, 0).size(), expected); + } - { - span av; - EXPECT_TRUE((av.subspan<0, 0>().size()) == 0); - EXPECT_TRUE(decltype(av.subspan<0, 0>())::extent == 0); - EXPECT_TRUE(av.subspan(0, 0).size() == 0); - EXPECT_DEATH((av.subspan<1, 0>().size()), deathstring); - } + { + span av = arr; + EXPECT_TRUE(av.subspan<1>().size() == 4); + EXPECT_TRUE(decltype(av.subspan<1>())::extent == 4); + } - { - span av; - EXPECT_TRUE(av.subspan(0).size() == 0); - EXPECT_DEATH(av.subspan(1).size(), deathstring); - } + { + span av; + EXPECT_TRUE((av.subspan<0, 0>().size()) == 0); + EXPECT_TRUE(decltype(av.subspan<0, 0>())::extent == 0); + EXPECT_TRUE(av.subspan(0, 0).size() == 0); + EXPECT_DEATH((av.subspan<1, 0>().size()), expected); + } - { - span av = arr; - EXPECT_TRUE(av.subspan(0).size() == 5); - EXPECT_TRUE(av.subspan(1).size() == 4); - EXPECT_TRUE(av.subspan(4).size() == 1); - EXPECT_TRUE(av.subspan(5).size() == 0); - EXPECT_DEATH(av.subspan(6).size(), deathstring); - const auto av2 = av.subspan(1); - for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast(i) + 2); - } + { + span av; + EXPECT_TRUE(av.subspan(0).size() == 0); + EXPECT_DEATH(av.subspan(1).size(), expected); + } - { - span av = arr; - EXPECT_TRUE(av.subspan(0).size() == 5); - EXPECT_TRUE(av.subspan(1).size() == 4); - EXPECT_TRUE(av.subspan(4).size() == 1); - EXPECT_TRUE(av.subspan(5).size() == 0); - EXPECT_DEATH(av.subspan(6).size(), deathstring); - const auto av2 = av.subspan(1); - for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast(i) + 2); - } - } + { + span av = arr; + EXPECT_TRUE(av.subspan(0).size() == 5); + EXPECT_TRUE(av.subspan(1).size() == 4); + EXPECT_TRUE(av.subspan(4).size() == 1); + EXPECT_TRUE(av.subspan(5).size() == 0); + EXPECT_DEATH(av.subspan(6).size(), expected); + const auto av2 = av.subspan(1); + for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast(i) + 2); + } - TEST(span_test, iterator_default_init) - { - span::iterator it1; - span::iterator it2; - EXPECT_TRUE(it1 == it2); - } + { + span av = arr; + EXPECT_TRUE(av.subspan(0).size() == 5); + EXPECT_TRUE(av.subspan(1).size() == 4); + EXPECT_TRUE(av.subspan(4).size() == 1); + EXPECT_TRUE(av.subspan(5).size() == 0); + EXPECT_DEATH(av.subspan(6).size(), expected); + const auto av2 = av.subspan(1); + for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast(i) + 2); + } +} - TEST(span_test, iterator_comparisons) - { - int a[] = {1, 2, 3, 4}; - { - span s = a; - span::iterator it = s.begin(); - auto it2 = it + 1; +TEST(span_test, iterator_default_init) +{ + span::iterator it1; + span::iterator it2; + EXPECT_TRUE(it1 == it2); +} - EXPECT_TRUE(it == it); - EXPECT_TRUE(it == s.begin()); - EXPECT_TRUE(s.begin() == it); +TEST(span_test, iterator_comparisons) +{ + int a[] = {1, 2, 3, 4}; + { + span s = a; + span::iterator it = s.begin(); + auto it2 = it + 1; - EXPECT_TRUE(it != it2); - EXPECT_TRUE(it2 != it); - EXPECT_TRUE(it != s.end()); - EXPECT_TRUE(it2 != s.end()); - EXPECT_TRUE(s.end() != it); + EXPECT_TRUE(it == it); + EXPECT_TRUE(it == s.begin()); + EXPECT_TRUE(s.begin() == it); - EXPECT_TRUE(it < it2); - EXPECT_TRUE(it <= it2); - EXPECT_TRUE(it2 <= s.end()); - EXPECT_TRUE(it < s.end()); + EXPECT_TRUE(it != it2); + EXPECT_TRUE(it2 != it); + EXPECT_TRUE(it != s.end()); + EXPECT_TRUE(it2 != s.end()); + EXPECT_TRUE(s.end() != it); - EXPECT_TRUE(it2 > it); - EXPECT_TRUE(it2 >= it); - EXPECT_TRUE(s.end() > it2); - EXPECT_TRUE(s.end() >= it2); - } - } + EXPECT_TRUE(it < it2); + EXPECT_TRUE(it <= it2); + EXPECT_TRUE(it2 <= s.end()); + EXPECT_TRUE(it < s.end()); - TEST(span_test, incomparable_iterators) - { - std::set_terminate([] { - std::cerr << "Expected Death. incomparable_iterators"; - std::abort(); - }); + EXPECT_TRUE(it2 > it); + EXPECT_TRUE(it2 >= it); + EXPECT_TRUE(s.end() > it2); + EXPECT_TRUE(s.end() >= it2); + } +} - int a[] = {1, 2, 3, 4}; - int b[] = {1, 2, 3, 4}; - { - span s = a; - span s2 = b; +TEST(span_test, incomparable_iterators) +{ + const auto terminateHandler = std::set_terminate([] { + std::cerr << "Expected Death. incomparable_iterators"; + std::abort(); + }); + const auto expected = GetExpectedDeathString(terminateHandler); + + int a[] = {1, 2, 3, 4}; + int b[] = {1, 2, 3, 4}; + { + span s = a; + span s2 = b; #if (__cplusplus > 201402L) - EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() == s2.begin()), deathstring); - EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() <= s2.begin()), deathstring); + EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() == s2.begin()), expected); + EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() <= s2.begin()), expected); #else - EXPECT_DEATH(bool _ = (s.begin() == s2.begin()), deathstring); - EXPECT_DEATH(bool _ = (s.begin() <= s2.begin()), deathstring); + EXPECT_DEATH(bool _ = (s.begin() == s2.begin()), expected); + EXPECT_DEATH(bool _ = (s.begin() <= s2.begin()), expected); #endif - } - } + } +} - TEST(span_test, begin_end) - { - std::set_terminate([] { +TEST(span_test, begin_end) +{ + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. begin_end"; std::abort(); }); - { - int a[] = {1, 2, 3, 4}; - span s = a; + const auto expected = GetExpectedDeathString(terminateHandler); - span::iterator it = s.begin(); - span::iterator it2 = std::begin(s); - EXPECT_TRUE(it == it2); + { + int a[] = {1, 2, 3, 4}; + span s = a; - it = s.end(); - it2 = std::end(s); - EXPECT_TRUE(it == it2); - } + span::iterator it = s.begin(); + span::iterator it2 = std::begin(s); + EXPECT_TRUE(it == it2); - { - int a[] = {1, 2, 3, 4}; - span s = a; + it = s.end(); + it2 = std::end(s); + EXPECT_TRUE(it == it2); + } - auto it = s.begin(); - auto first = it; - EXPECT_TRUE(it == first); - EXPECT_TRUE(*it == 1); + { + int a[] = {1, 2, 3, 4}; + span s = a; - auto beyond = s.end(); - EXPECT_TRUE(it != beyond); - EXPECT_DEATH(*beyond, deathstring); + auto it = s.begin(); + auto first = it; + EXPECT_TRUE(it == first); + EXPECT_TRUE(*it == 1); - EXPECT_TRUE(beyond - first == 4); - EXPECT_TRUE(first - first == 0); - EXPECT_TRUE(beyond - beyond == 0); + auto beyond = s.end(); + EXPECT_TRUE(it != beyond); + EXPECT_DEATH(*beyond, expected); - ++it; - EXPECT_TRUE(it - first == 1); - EXPECT_TRUE(*it == 2); - *it = 22; - EXPECT_TRUE(*it == 22); - EXPECT_TRUE(beyond - it == 3); + EXPECT_TRUE(beyond - first == 4); + EXPECT_TRUE(first - first == 0); + EXPECT_TRUE(beyond - beyond == 0); - it = first; - EXPECT_TRUE(it == first); - while (it != s.end()) - { - *it = 5; - ++it; - } + ++it; + EXPECT_TRUE(it - first == 1); + EXPECT_TRUE(*it == 2); + *it = 22; + EXPECT_TRUE(*it == 22); + EXPECT_TRUE(beyond - it == 3); - EXPECT_TRUE(it == beyond); - EXPECT_TRUE(it - beyond == 0); + it = first; + EXPECT_TRUE(it == first); + while (it != s.end()) + { + *it = 5; + ++it; + } - for (const auto& n : s) { EXPECT_TRUE(n == 5); } - } - } + EXPECT_TRUE(it == beyond); + EXPECT_TRUE(it - beyond == 0); - TEST(span_test, rbegin_rend) - { - std::set_terminate([] { + for (const auto& n : s) { EXPECT_TRUE(n == 5); } + } +} + +TEST(span_test, rbegin_rend) +{ + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. rbegin_rend"; std::abort(); }); - { - int a[] = {1, 2, 3, 4}; - span s = a; + const auto expected = GetExpectedDeathString(terminateHandler); - auto it = s.rbegin(); - auto first = it; - EXPECT_TRUE(it == first); - EXPECT_TRUE(*it == 4); + { + int a[] = {1, 2, 3, 4}; + span s = a; - auto beyond = s.rend(); - EXPECT_TRUE(it != beyond); + auto it = s.rbegin(); + auto first = it; + EXPECT_TRUE(it == first); + EXPECT_TRUE(*it == 4); + + auto beyond = s.rend(); + EXPECT_TRUE(it != beyond); #if (__cplusplus > 201402L) - EXPECT_DEATH([[maybe_unused]] auto _ = *beyond , deathstring); + EXPECT_DEATH([[maybe_unused]] auto _ = *beyond, expected); #else - EXPECT_DEATH(auto _ = *beyond , deathstring); + EXPECT_DEATH(auto _ = *beyond, expected); #endif - EXPECT_TRUE(beyond - first == 4); - EXPECT_TRUE(first - first == 0); - EXPECT_TRUE(beyond - beyond == 0); + EXPECT_TRUE(beyond - first == 4); + EXPECT_TRUE(first - first == 0); + EXPECT_TRUE(beyond - beyond == 0); - ++it; - EXPECT_TRUE(it - s.rbegin() == 1); - EXPECT_TRUE(*it == 3); - *it = 22; - EXPECT_TRUE(*it == 22); - EXPECT_TRUE(beyond - it == 3); + ++it; + EXPECT_TRUE(it - s.rbegin() == 1); + EXPECT_TRUE(*it == 3); + *it = 22; + EXPECT_TRUE(*it == 22); + EXPECT_TRUE(beyond - it == 3); - it = first; - EXPECT_TRUE(it == first); - while (it != s.rend()) - { - *it = 5; - ++it; - } + it = first; + EXPECT_TRUE(it == first); + while (it != s.rend()) + { + *it = 5; + ++it; + } - EXPECT_TRUE(it == beyond); - EXPECT_TRUE(it - beyond == 0); + EXPECT_TRUE(it == beyond); + EXPECT_TRUE(it - beyond == 0); - for (const auto& n : s) { EXPECT_TRUE(n == 5); } - } - } + for (const auto& n : s) { EXPECT_TRUE(n == 5); } + } +} - TEST(span_test, as_bytes) - { - std::set_terminate([] { - std::cerr << "Expected Death. as_bytes"; - std::abort(); - }); +TEST(span_test, as_bytes) +{ + const auto terminateHandler = std::set_terminate([] { + std::cerr << "Expected Death. as_bytes"; + std::abort(); + }); + const auto expected = GetExpectedDeathString(terminateHandler); - int a[] = {1, 2, 3, 4}; - { - const span s = a; - EXPECT_TRUE(s.size() == 4); - const span bs = as_bytes(s); - EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); - EXPECT_TRUE(bs.size() == s.size_bytes()); - } + int a[] = {1, 2, 3, 4}; + { + const span s = a; + EXPECT_TRUE(s.size() == 4); + const span bs = as_bytes(s); + EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); + EXPECT_TRUE(bs.size() == s.size_bytes()); + } - { - span s; - const auto bs = as_bytes(s); - EXPECT_TRUE(bs.size() == s.size()); - EXPECT_TRUE(bs.size() == 0); - EXPECT_TRUE(bs.size_bytes() == 0); - EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); - EXPECT_TRUE(bs.data() == nullptr); - } + { + span s; + const auto bs = as_bytes(s); + EXPECT_TRUE(bs.size() == s.size()); + EXPECT_TRUE(bs.size() == 0); + EXPECT_TRUE(bs.size_bytes() == 0); + EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); + EXPECT_TRUE(bs.data() == nullptr); + } - { - span s = a; - const auto bs = as_bytes(s); - EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); - EXPECT_TRUE(bs.size() == s.size_bytes()); - } + { + span s = a; + const auto bs = as_bytes(s); + EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); + EXPECT_TRUE(bs.size() == s.size_bytes()); + } - int b[5] = {1, 2, 3, 4, 5}; - { - span sp(begin(b), static_cast(-2)); - EXPECT_DEATH((void) sp.size_bytes(), deathstring); - } - } + int b[5] = {1, 2, 3, 4, 5}; + { + span sp(begin(b), static_cast(-2)); + EXPECT_DEATH((void) sp.size_bytes(), expected); + } +} - TEST(span_test, as_writable_bytes) - { - int a[] = {1, 2, 3, 4}; +TEST(span_test, as_writable_bytes) +{ + int a[] = {1, 2, 3, 4}; - { - #ifdef CONFIRM_COMPILATION_ERRORS - // you should not be able to get writeable bytes for const objects - span s = a; - EXPECT_TRUE(s.size() == 4); - span bs = as_writable_bytes(s); - EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); - EXPECT_TRUE(bs.size() == s.size_bytes()); - #endif - } + { +#ifdef CONFIRM_COMPILATION_ERRORS + // you should not be able to get writeable bytes for const objects + span s = a; + EXPECT_TRUE(s.size() == 4); + span bs = as_writable_bytes(s); + EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); + EXPECT_TRUE(bs.size() == s.size_bytes()); +#endif + } - { - span s; - const auto bs = as_writable_bytes(s); - EXPECT_TRUE(bs.size() == s.size()); - EXPECT_TRUE(bs.size() == 0); - EXPECT_TRUE(bs.size_bytes() == 0); - EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); - EXPECT_TRUE(bs.data() == nullptr); - } + { + span s; + const auto bs = as_writable_bytes(s); + EXPECT_TRUE(bs.size() == s.size()); + EXPECT_TRUE(bs.size() == 0); + EXPECT_TRUE(bs.size_bytes() == 0); + EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); + EXPECT_TRUE(bs.data() == nullptr); + } - { - span s = a; - const auto bs = as_writable_bytes(s); - EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); - EXPECT_TRUE(bs.size() == s.size_bytes()); - } - } + { + span s = a; + const auto bs = as_writable_bytes(s); + EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); + EXPECT_TRUE(bs.size() == s.size_bytes()); + } +} - TEST(span_test, fixed_size_conversions) - { - std::set_terminate([] { +TEST(span_test, fixed_size_conversions) +{ + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. fixed_size_conversions"; std::abort(); }); - int arr[] = {1, 2, 3, 4}; + const auto expected = GetExpectedDeathString(terminateHandler); - // converting to an span from an equal size array is ok - span s4 = arr; - EXPECT_TRUE(s4.size() == 4); + int arr[] = {1, 2, 3, 4}; - // converting to dynamic_range is always ok - { - span s = s4; - EXPECT_TRUE(s.size() == s4.size()); - static_cast(s); - } + // converting to an span from an equal size array is ok + span s4 = arr; + EXPECT_TRUE(s4.size() == 4); - // initialization or assignment to static span that REDUCES size is NOT ok - #ifdef CONFIRM_COMPILATION_ERRORS - { - span s = arr; - } - { - span s2 = s4; - static_cast(s2); - } - #endif + // converting to dynamic_range is always ok + { + span s = s4; + EXPECT_TRUE(s.size() == s4.size()); + static_cast(s); + } - // even when done dynamically - { - /* - // this now results in a compile-time error, rather than runtime. - // There is no suitable conversion from dynamic span to fixed span. - span s = arr; - auto f = [&]() { - const span s2 = s; - static_cast(s2); - }; - EXPECT_DEATH(f(), deathstring); - */ - } +// initialization or assignment to static span that REDUCES size is NOT ok +#ifdef CONFIRM_COMPILATION_ERRORS + { + span s = arr; + } + { + span s2 = s4; + static_cast(s2); + } +#endif - // but doing so explicitly is ok + // even when done dynamically + { + /* + // this now results in a compile-time error, rather than runtime. + // There is no suitable conversion from dynamic span to fixed span. + span s = arr; + auto f = [&]() { + const span s2 = s; + static_cast(s2); + }; + EXPECT_DEATH(f(), expected); + */ + } - // you can convert statically - { - const span s2{&arr[0], 2}; - static_cast(s2); - } - { - const span s1 = s4.first<1>(); - static_cast(s1); - } + // but doing so explicitly is ok + + // you can convert statically + { + const span s2{&arr[0], 2}; + static_cast(s2); + } + { + const span s1 = s4.first<1>(); + static_cast(s1); + } /* // this is not a legal operation in std::span, so we are no longer supporting it @@ -1176,73 +1195,74 @@ TEST(span_test, from_array_constructor) } */ - // initialization or assignment to static span that requires size INCREASE is not ok. - int arr2[2] = {1, 2}; + // initialization or assignment to static span that requires size INCREASE is not ok. + int arr2[2] = {1, 2}; - #ifdef CONFIRM_COMPILATION_ERRORS - { - span s3 = arr2; - } - { - span s2 = arr2; - span s4a = s2; - } - #endif - { - auto f = [&]() { - const span _s4{arr2, 2}; - static_cast(_s4); - }; - EXPECT_DEATH(f(), deathstring); - } +#ifdef CONFIRM_COMPILATION_ERRORS + { + span s3 = arr2; + } + { + span s2 = arr2; + span s4a = s2; + } +#endif + { + auto f = [&]() { + const span _s4{arr2, 2}; + static_cast(_s4); + }; + EXPECT_DEATH(f(), expected); + } /* - // This no longer compiles. There is no suitable conversion from dynamic span to a fixed size span. + // This no longer compiles. There is no suitable conversion from dynamic span to a fixed size + span. // this should fail - we are trying to assign a small dynamic span to a fixed_size larger one span av = arr2; auto f = [&]() { const span _s4 = av; static_cast(_s4); }; - EXPECT_DEATH(f(), deathstring); + EXPECT_DEATH(f(), expected); */ - } +} - TEST(span_test, interop_with_std_regex) - { - char lat[] = {'1', '2', '3', '4', '5', '6', 'E', 'F', 'G'}; - span s = lat; - const auto f_it = s.begin() + 7; +TEST(span_test, interop_with_std_regex) +{ + char lat[] = {'1', '2', '3', '4', '5', '6', 'E', 'F', 'G'}; + span s = lat; + const auto f_it = s.begin() + 7; - std::match_results::iterator> match; + std::match_results::iterator> match; - std::regex_match(s.begin(), s.end(), match, std::regex(".*")); - EXPECT_TRUE(match.ready()); - EXPECT_FALSE(match.empty()); - EXPECT_TRUE(match[0].matched); - EXPECT_TRUE(match[0].first == s.begin()); - EXPECT_TRUE(match[0].second == s.end()); + std::regex_match(s.begin(), s.end(), match, std::regex(".*")); + EXPECT_TRUE(match.ready()); + EXPECT_FALSE(match.empty()); + EXPECT_TRUE(match[0].matched); + EXPECT_TRUE(match[0].first == s.begin()); + EXPECT_TRUE(match[0].second == s.end()); - std::regex_search(s.begin(), s.end(), match, std::regex("F")); - EXPECT_TRUE(match.ready()); - EXPECT_FALSE(match.empty()); - EXPECT_TRUE(match[0].matched); - EXPECT_TRUE(match[0].first == f_it); - EXPECT_TRUE(match[0].second == (f_it + 1)); - } + std::regex_search(s.begin(), s.end(), match, std::regex("F")); + EXPECT_TRUE(match.ready()); + EXPECT_FALSE(match.empty()); + EXPECT_TRUE(match[0].matched); + EXPECT_TRUE(match[0].first == f_it); + EXPECT_TRUE(match[0].second == (f_it + 1)); +} - TEST(span_test, default_constructible) - { - EXPECT_TRUE((std::is_default_constructible>::value)); - EXPECT_TRUE((std::is_default_constructible>::value)); - EXPECT_FALSE((std::is_default_constructible>::value)); - } +TEST(span_test, default_constructible) +{ + EXPECT_TRUE((std::is_default_constructible>::value)); + EXPECT_TRUE((std::is_default_constructible>::value)); + EXPECT_FALSE((std::is_default_constructible>::value)); +} - TEST(span_test, std_container_ctad) - { +TEST(span_test, std_container_ctad) +{ #if (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L)) // this test is just to verify that these compile { - std::vector v{1,2,3,4}; + std::vector v{1, 2, 3, 4}; gsl::span sp{v}; static_assert(std::is_same>::value); } @@ -1259,20 +1279,22 @@ TEST(span_test, from_array_constructor) } #endif #endif - } +} - TEST(span_test, front_back) - { - int arr[5] = {1,2,3,4,5}; +TEST(span_test, front_back) +{ + int arr[5] = {1, 2, 3, 4, 5}; span s{arr}; EXPECT_TRUE(s.front() == 1); EXPECT_TRUE(s.back() == 5); - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. front_back"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); + span s2; - EXPECT_DEATH(s2.front(), deathstring); - EXPECT_DEATH(s2.back(), deathstring); - } + EXPECT_DEATH(s2.front(), expected); + EXPECT_DEATH(s2.back(), expected); +} diff --git a/tests/strict_notnull_tests.cpp b/tests/strict_notnull_tests.cpp index 9de2760..7edef43 100644 --- a/tests/strict_notnull_tests.cpp +++ b/tests/strict_notnull_tests.cpp @@ -14,23 +14,33 @@ // /////////////////////////////////////////////////////////////////////////////// +#include // for not_null, operator<, operator<=, operator> #include -#include // for not_null, operator<, operator<=, operator> + +#include "deathTestCommon.h" using namespace gsl; namespace { -GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +// clang-format off +GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +// clang-format on bool helper(not_null p) { return *p == 12; } +// clang-format off GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +// clang-format on bool helper_const(not_null p) { return *p == 12; } +// clang-format off GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +// clang-format on bool strict_helper(strict_not_null p) { return *p == 12; } +// clang-format off GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +// clang-format on bool strict_helper_const(strict_not_null p) { return *p == 12; } #ifdef CONFIRM_COMPILATION_ERRORS @@ -123,17 +133,14 @@ TEST(strict_notnull_tests, TestStrictNotNull) } #if defined(__cplusplus) && (__cplusplus >= 201703L) -namespace -{ -static constexpr char deathstring[] = "Expected Death"; -} TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. TestStrictNotNullConstructorTypeDeduction"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); { int i = 42; @@ -161,7 +168,7 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction) int* p1 = nullptr; const strict_not_null x{p1}; }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } { @@ -169,14 +176,14 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction) const int* p1 = nullptr; const strict_not_null x{p1}; }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } { int* p = nullptr; - EXPECT_DEATH(helper(strict_not_null{p}), deathstring); - EXPECT_DEATH(helper_const(strict_not_null{p}), deathstring); + EXPECT_DEATH(helper(strict_not_null{p}), expected); + EXPECT_DEATH(helper_const(strict_not_null{p}), expected); } #ifdef CONFIRM_COMPILATION_ERRORS diff --git a/tests/string_span_tests.cpp b/tests/string_span_tests.cpp index 3c919d0..8cc45c6 100644 --- a/tests/string_span_tests.cpp +++ b/tests/string_span_tests.cpp @@ -16,7 +16,7 @@ #include -#include // for Expects, fail_fast (ptr only) +#include // for Expects, fail_fast (ptr only) #include // for owner #include // for span, dynamic_extent #include // for basic_string_span, operator==, ensure_z @@ -28,13 +28,11 @@ #include // for remove_reference<>::type #include // for vector, allocator +#include "deathTestCommon.h" + using namespace std; using namespace gsl; -namespace -{ -static constexpr char deathstring[] = "Expected Death"; -} // Generic string functions namespace generic @@ -76,8 +74,7 @@ T create() template void use(basic_string_span) -{ -} +{} #endif czstring_span<> CreateTempName(string_span<> span) @@ -85,7 +82,8 @@ czstring_span<> CreateTempName(string_span<> span) Expects(span.size() > 1); std::size_t last = 0; - if (span.size() > 4) { + if (span.size() > 4) + { span[0] = 't'; span[1] = 'm'; span[2] = 'p'; @@ -102,7 +100,8 @@ cwzstring_span<> CreateTempNameW(wstring_span<> span) Expects(span.size() > 1); std::size_t last = 0; - if (span.size() > 4) { + if (span.size() > 4) + { span[0] = L't'; span[1] = L'm'; span[2] = L'p'; @@ -119,7 +118,8 @@ cu16zstring_span<> CreateTempNameU16(u16string_span<> span) Expects(span.size() > 1); std::size_t last = 0; - if (span.size() > 4) { + if (span.size() > 4) + { span[0] = u't'; span[1] = u'm'; span[2] = u'p'; @@ -136,7 +136,8 @@ cu32zstring_span<> CreateTempNameU32(u32string_span<> span) Expects(span.size() > 1); std::size_t last = 0; - if (span.size() > 4) { + if (span.size() > 4) + { span[0] = U't'; span[1] = U'm'; span[2] = U'p'; @@ -950,10 +951,11 @@ TEST(string_span_tests, Conversion) TEST(string_span_tests, zstring) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. zstring"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); // create zspan from zero terminated string { @@ -973,7 +975,7 @@ TEST(string_span_tests, zstring) buf[0] = 'a'; auto workaround_macro = [&]() { const zstring_span<> zspan({buf, 1}); }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } // usage scenario: create zero-terminated temp file name and pass to a legacy API @@ -981,7 +983,8 @@ TEST(string_span_tests, zstring) char buf[10]; auto name = CreateTempName({buf, 10}); - if (!name.empty()) { + if (!name.empty()) + { czstring<> str = name.assume_z(); EXPECT_TRUE(generic::strlen(str) == 3); EXPECT_TRUE(*(str + 3) == '\0'); @@ -991,10 +994,11 @@ TEST(string_span_tests, zstring) TEST(string_span_tests, wzstring) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. wzstring"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); // create zspan from zero terminated string { @@ -1014,7 +1018,7 @@ TEST(string_span_tests, wzstring) buf[0] = L'a'; const auto workaround_macro = [&]() { const wzstring_span<> zspan({buf, 1}); }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } // usage scenario: create zero-terminated temp file name and pass to a legacy API @@ -1022,7 +1026,8 @@ TEST(string_span_tests, wzstring) wchar_t buf[10]; const auto name = CreateTempNameW({buf, 10}); - if (!name.empty()) { + if (!name.empty()) + { cwzstring<> str = name.assume_z(); EXPECT_TRUE(generic::strnlen(str, 10) == 3); EXPECT_TRUE(*(str + 3) == L'\0'); @@ -1032,10 +1037,11 @@ TEST(string_span_tests, wzstring) TEST(string_span_tests, u16zstring) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. u16zstring"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); // create zspan from zero terminated string { @@ -1055,7 +1061,7 @@ TEST(string_span_tests, u16zstring) buf[0] = u'a'; const auto workaround_macro = [&]() { const u16zstring_span<> zspan({buf, 1}); }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } // usage scenario: create zero-terminated temp file name and pass to a legacy API @@ -1063,7 +1069,8 @@ TEST(string_span_tests, u16zstring) char16_t buf[10]; const auto name = CreateTempNameU16({buf, 10}); - if (!name.empty()) { + if (!name.empty()) + { cu16zstring<> str = name.assume_z(); EXPECT_TRUE(generic::strnlen(str, 10) == 3); EXPECT_TRUE(*(str + 3) == L'\0'); @@ -1073,10 +1080,11 @@ TEST(string_span_tests, u16zstring) TEST(string_span_tests, u32zstring) { - std::set_terminate([] { + const auto terminateHandler = std::set_terminate([] { std::cerr << "Expected Death. u31zstring"; std::abort(); }); + const auto expected = GetExpectedDeathString(terminateHandler); // create zspan from zero terminated string { @@ -1096,7 +1104,7 @@ TEST(string_span_tests, u32zstring) buf[0] = u'a'; const auto workaround_macro = [&]() { const u32zstring_span<> zspan({buf, 1}); }; - EXPECT_DEATH(workaround_macro(), deathstring); + EXPECT_DEATH(workaround_macro(), expected); } // usage scenario: create zero-terminated temp file name and pass to a legacy API @@ -1104,7 +1112,8 @@ TEST(string_span_tests, u32zstring) char32_t buf[10]; const auto name = CreateTempNameU32({buf, 10}); - if (!name.empty()) { + if (!name.empty()) + { cu32zstring<> str = name.assume_z(); EXPECT_TRUE(generic::strnlen(str, 10) == 3); EXPECT_TRUE(*(str + 3) == L'\0'); diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp index 74dc990..0585c79 100644 --- a/tests/utils_tests.cpp +++ b/tests/utils_tests.cpp @@ -16,14 +16,14 @@ #include -#include // finally, narrow_cast -#include // for narrow, narrowing_error #include // for move +#include // for std::ptrdiff_t #include // for reference_wrapper, _Bind_helper<>::type +#include // for narrow, narrowing_error +#include // finally, narrow_cast #include // for numeric_limits #include // for uint32_t, int32_t #include // for is_same -#include // for std::ptrdiff_t using namespace gsl; @@ -32,8 +32,7 @@ namespace void f(int& i) { i += 1; } static int j = 0; void g() { j += 1; } -} - +} // namespace TEST(utils_tests, sanity_check_for_gsl_index_typedef) { @@ -123,6 +122,7 @@ TEST(utils_tests, narrow_cast) EXPECT_TRUE(uc == 44); } +#ifndef GSL_KERNEL_MODE TEST(utils_tests, narrow) { int n = 120; @@ -145,3 +145,4 @@ TEST(utils_tests, narrow) n = -42; EXPECT_THROW(narrow(n), narrowing_error); } +#endif // GSL_KERNEL_MODE