diff options
author | Neil MacIntosh <neilmac@microsoft.com> | 2017-07-13 23:53:56 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-13 23:53:56 +0300 |
commit | b2ee48433448556a7be63074f8aaf45ab47a95c1 (patch) | |
tree | df94d91f17334f50c33dfea4763f3b4b282f5f85 /tests | |
parent | 1f87ef73f1477e8adafa8b10ccee042897612a20 (diff) |
Move from unittest-cpp to catch for unit testing. (#533)
Many thanks to @rianquinn. This should fix #495, #494 and #529.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/CMakeLists.txt | 41 | ||||
-rw-r--r-- | tests/algorithm_tests.cpp | 258 | ||||
-rw-r--r-- | tests/assertion_tests.cpp | 45 | ||||
-rw-r--r-- | tests/at_tests.cpp | 101 | ||||
-rw-r--r-- | tests/bounds_tests.cpp | 99 | ||||
-rw-r--r-- | tests/byte_tests.cpp | 156 | ||||
-rw-r--r-- | tests/multi_span_tests.cpp | 1999 | ||||
-rw-r--r-- | tests/notnull_tests.cpp | 290 | ||||
-rw-r--r-- | tests/owner_tests.cpp | 37 | ||||
-rw-r--r-- | tests/span_tests.cpp | 1180 | ||||
-rw-r--r-- | tests/strided_span_tests.cpp | 1133 | ||||
-rw-r--r-- | tests/string_span_tests.cpp | 1414 | ||||
-rw-r--r-- | tests/test.cpp | 18 | ||||
m--------- | tests/unittest-cpp | 0 | ||||
-rw-r--r-- | tests/utils_tests.cpp | 125 |
15 files changed, 3432 insertions, 3464 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index eb08360..5306e85 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,15 +5,21 @@ project(GSLTests CXX) # will make visual studio generated project group files set_property(GLOBAL PROPERTY USE_FOLDERS ON) -if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/unittest-cpp/CMakeLists.txt) - find_package(Git) - execute_process( - COMMAND ${GIT_EXECUTABLE} submodule update --init - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - ) -endif() +list(APPEND CATCH_CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX=${CMAKE_SOURCE_DIR}" + "-DNO_SELFTEST=true" +) -add_subdirectory(unittest-cpp) +# add catch +ExternalProject_Add( + catch + PREFIX ${CMAKE_BINARY_DIR}/catch + GIT_REPOSITORY https://github.com/philsquared/Catch.git + GIT_TAG v1.9.6 + CMAKE_ARGS ${CATCH_CMAKE_ARGS} + LOG_DOWNLOAD 1 + UPDATE_DISCONNECTED 1 +) # this interface adds compile options to how the tests are run # please try to keep entries ordered =) @@ -42,24 +48,29 @@ target_compile_options(gsl_tests_config INTERFACE > ) -# set test to include the unittest-cpp headers -# this shiuld be removed when UnitTest++ has the proper headers -target_include_directories(gsl_tests_config INTERFACE - ./unittest-cpp -) - # 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") + function(add_gsl_test name) add_executable(${name} ${name}.cpp) target_link_libraries(${name} - UnitTest++ GSL + test_catch gsl_tests_config ) + add_dependencies(${name} catch) add_test( ${name} ${name} diff --git a/tests/algorithm_tests.cpp b/tests/algorithm_tests.cpp index 7b5f429..045fd3e 100644 --- a/tests/algorithm_tests.cpp +++ b/tests/algorithm_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/gsl_algorithm> @@ -23,188 +23,182 @@ using namespace std; using namespace gsl; -SUITE(copy_tests) +TEST_CASE("same_type") { - - TEST(same_type) + // dynamic source and destination span { - // dynamic source and destination span - { - std::array<int, 5> src{1, 2, 3, 4, 5}; - std::array<int, 10> dst{}; + std::array<int, 5> src{1, 2, 3, 4, 5}; + std::array<int, 10> dst{}; - span<int> src_span(src); - span<int> dst_span(dst); + span<int> src_span(src); + span<int> dst_span(dst); - copy(src_span, dst_span); - copy(src_span, dst_span.subspan(src_span.size())); + copy(src_span, dst_span); + 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]); - } + for (std::size_t i = 0; i < src.size(); ++i) { + CHECK(dst[i] == src[i]); + CHECK(dst[i + src.size()] == src[i]); } + } - // static source and dynamic destination span - { - std::array<int, 5> src{1, 2, 3, 4, 5}; - std::array<int, 10> dst{}; + // static source and dynamic destination span + { + std::array<int, 5> src{1, 2, 3, 4, 5}; + std::array<int, 10> dst{}; - span<int, 5> src_span(src); - span<int> dst_span(dst); + span<int, 5> src_span(src); + span<int> dst_span(dst); - copy(src_span, dst_span); - copy(src_span, dst_span.subspan(src_span.size())); + copy(src_span, dst_span); + 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]); - } + for (std::size_t i = 0; i < src.size(); ++i) { + CHECK(dst[i] == src[i]); + CHECK(dst[i + src.size()] == src[i]); } + } - // dynamic source and static destination span - { - std::array<int, 5> src{1, 2, 3, 4, 5}; - std::array<int, 10> dst{}; + // dynamic source and static destination span + { + std::array<int, 5> src{1, 2, 3, 4, 5}; + std::array<int, 10> dst{}; - span<int> src_span(src); - span<int, 10> dst_span(dst); + span<int> src_span(src); + span<int, 10> dst_span(dst); - copy(src_span, dst_span); - copy(src_span, dst_span.subspan(src_span.size())); + copy(src_span, dst_span); + 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]); - } + for (std::size_t i = 0; i < src.size(); ++i) { + CHECK(dst[i] == src[i]); + CHECK(dst[i + src.size()] == src[i]); } + } - // static source and destination span - { - std::array<int, 5> src{1, 2, 3, 4, 5}; - std::array<int, 10> dst{}; + // static source and destination span + { + std::array<int, 5> src{1, 2, 3, 4, 5}; + std::array<int, 10> dst{}; - span<int, 5> src_span(src); - span<int, 10> dst_span(dst); + span<int, 5> src_span(src); + span<int, 10> dst_span(dst); - copy(src_span, dst_span); - copy(src_span, dst_span.subspan(src_span.size())); + copy(src_span, dst_span); + 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]); - } + for (std::size_t i = 0; i < src.size(); ++i) { + CHECK(dst[i] == src[i]); + CHECK(dst[i + src.size()] == src[i]); } } +} - TEST(compatible_type) +TEST_CASE("compatible_type") +{ + // dynamic source and destination span { - // dynamic source and destination span - { - std::array<short, 5> src{1, 2, 3, 4, 5}; - std::array<int, 10> dst{}; + std::array<short, 5> src{1, 2, 3, 4, 5}; + std::array<int, 10> dst{}; - span<short> src_span(src); - span<int> dst_span(dst); + span<short> src_span(src); + span<int> dst_span(dst); - copy(src_span, dst_span); - copy(src_span, dst_span.subspan(src_span.size())); + copy(src_span, dst_span); + 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]); - } + for (std::size_t i = 0; i < src.size(); ++i) { + CHECK(dst[i] == src[i]); + CHECK(dst[i + src.size()] == src[i]); } + } - // static source and dynamic destination span - { - std::array<short, 5> src{1, 2, 3, 4, 5}; - std::array<int, 10> dst{}; + // static source and dynamic destination span + { + std::array<short, 5> src{1, 2, 3, 4, 5}; + std::array<int, 10> dst{}; - span<short, 5> src_span(src); - span<int> dst_span(dst); + span<short, 5> src_span(src); + span<int> dst_span(dst); - copy(src_span, dst_span); - copy(src_span, dst_span.subspan(src_span.size())); + copy(src_span, dst_span); + 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]); - } + for (std::size_t i = 0; i < src.size(); ++i) { + CHECK(dst[i] == src[i]); + CHECK(dst[i + src.size()] == src[i]); } + } - // dynamic source and static destination span - { - std::array<short, 5> src{1, 2, 3, 4, 5}; - std::array<int, 10> dst{}; + // dynamic source and static destination span + { + std::array<short, 5> src{1, 2, 3, 4, 5}; + std::array<int, 10> dst{}; - span<short> src_span(src); - span<int, 10> dst_span(dst); + span<short> src_span(src); + span<int, 10> dst_span(dst); - copy(src_span, dst_span); - copy(src_span, dst_span.subspan(src_span.size())); + copy(src_span, dst_span); + 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]); - } + for (std::size_t i = 0; i < src.size(); ++i) { + CHECK(dst[i] == src[i]); + CHECK(dst[i + src.size()] == src[i]); } + } - // static source and destination span - { - std::array<short, 5> src{1, 2, 3, 4, 5}; - std::array<int, 10> dst{}; + // static source and destination span + { + std::array<short, 5> src{1, 2, 3, 4, 5}; + std::array<int, 10> dst{}; - span<short, 5> src_span(src); - span<int, 10> dst_span(dst); + span<short, 5> src_span(src); + span<int, 10> dst_span(dst); - copy(src_span, dst_span); - copy(src_span, dst_span.subspan(src_span.size())); + copy(src_span, dst_span); + 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]); - } + for (std::size_t i = 0; i < src.size(); ++i) { + CHECK(dst[i] == src[i]); + CHECK(dst[i + src.size()] == src[i]); } } +} #ifdef CONFIRM_COMPILATION_ERRORS - TEST(incompatible_type) - { - std::array<int, 4> src{1, 2, 3, 4}; - std::array<int*, 12> dst{}; - - span<int> src_span_dyn(src); - span<int, 4> src_span_static(src); - span<int*> dst_span_dyn(dst); - span<int*, 4> dst_span_static(dst); - - // every line should produce a compilation error - copy(src_span_dyn, dst_span_dyn); - copy(src_span_dyn, dst_span_static); - copy(src_span_static, dst_span_dyn); - copy(src_span_static, dst_span_static); - } +TEST_CASE("incompatible_type") +{ + std::array<int, 4> src{1, 2, 3, 4}; + std::array<int*, 12> dst{}; + + span<int> src_span_dyn(src); + span<int, 4> src_span_static(src); + span<int*> dst_span_dyn(dst); + span<int*, 4> dst_span_static(dst); + + // every line should produce a compilation error + copy(src_span_dyn, dst_span_dyn); + copy(src_span_dyn, dst_span_static); + copy(src_span_static, dst_span_dyn); + copy(src_span_static, dst_span_static); +} #endif - TEST(small_destination_span) - { - std::array<int, 12> src{1, 2, 3, 4}; - std::array<int, 4> dst{}; +TEST_CASE("small_destination_span") +{ + std::array<int, 12> src{1, 2, 3, 4}; + std::array<int, 4> dst{}; - span<int> src_span_dyn(src); - span<int, 12> src_span_static(src); - span<int> dst_span_dyn(dst); - span<int, 4> dst_span_static(dst); + span<int> src_span_dyn(src); + span<int, 12> src_span_static(src); + span<int> dst_span_dyn(dst); + span<int, 4> dst_span_static(dst); - CHECK_THROW(copy(src_span_dyn, dst_span_dyn), fail_fast); - CHECK_THROW(copy(src_span_dyn, dst_span_static), fail_fast); - CHECK_THROW(copy(src_span_static, dst_span_dyn), fail_fast); + 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); #ifdef CONFIRM_COMPILATION_ERRORS - copy(src_span_static, dst_span_static); + copy(src_span_static, dst_span_static); #endif - } } - -int main() { return UnitTest::RunAllTests(); } diff --git a/tests/assertion_tests.cpp b/tests/assertion_tests.cpp index b817a6d..42966d1 100644 --- a/tests/assertion_tests.cpp +++ b/tests/assertion_tests.cpp @@ -14,38 +14,33 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/gsl> using namespace gsl; -SUITE(assertion_tests) +int f(int i) { - int f(int i) - { - Expects(i > 0 && i < 10); - return i; - } - - TEST(expects) - { - CHECK(f(2) == 2); - CHECK_THROW(f(10), fail_fast); - } + Expects(i > 0 && i < 10); + return i; +} - int g(int i) - { - i++; - Ensures(i > 0 && i < 10); - return i; - } +TEST_CASE("expects") +{ + CHECK(f(2) == 2); + CHECK_THROWS_AS(f(10), fail_fast); +} - TEST(ensures) - { - CHECK(g(2) == 3); - CHECK_THROW(g(9), fail_fast); - } +int g(int i) +{ + i++; + Ensures(i > 0 && i < 10); + return i; } -int main(int, const char* []) { return UnitTest::RunAllTests(); } +TEST_CASE("ensures") +{ + CHECK(g(2) == 3); + CHECK_THROWS_AS(g(9), fail_fast); +} diff --git a/tests/at_tests.cpp b/tests/at_tests.cpp index 96e00f3..78e8e3d 100644 --- a/tests/at_tests.cpp +++ b/tests/at_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/gsl> @@ -23,70 +23,67 @@ using gsl::fail_fast; -SUITE(at_tests) +TEST_CASE("static_array") { - TEST(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]); - } - - CHECK_THROW(gsl::at(a, -1), fail_fast); - CHECK_THROW(gsl::at(a, 4), fail_fast); - CHECK_THROW(gsl::at(c_a, -1), fail_fast); - CHECK_THROW(gsl::at(c_a, 4), fail_fast); + 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]); } - TEST(std_array) - { - std::array<int, 4> a = {1, 2, 3, 4}; - const std::array<int, 4>& c_a = a; + 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); +} - 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)]); - } +TEST_CASE("std_array") +{ + std::array<int, 4> a = {1, 2, 3, 4}; + const std::array<int, 4>& c_a = a; - CHECK_THROW(gsl::at(a, -1), fail_fast); - CHECK_THROW(gsl::at(a, 4), fail_fast); - CHECK_THROW(gsl::at(c_a, -1), fail_fast); - CHECK_THROW(gsl::at(c_a, 4), fail_fast); + 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)]); } - TEST(StdVector) - { - std::vector<int> a = {1, 2, 3, 4}; - const std::vector<int>& c_a = a; + 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); +} - 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)]); - } +TEST_CASE("StdVector") +{ + std::vector<int> a = {1, 2, 3, 4}; + const std::vector<int>& c_a = a; - CHECK_THROW(gsl::at(a, -1), fail_fast); - CHECK_THROW(gsl::at(a, 4), fail_fast); - CHECK_THROW(gsl::at(c_a, -1), fail_fast); - CHECK_THROW(gsl::at(c_a, 4), fail_fast); + 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)]); } - TEST(InitializerList) - { - std::initializer_list<int> a = {1, 2, 3, 4}; + 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); +} - for (int i = 0; i < 4; ++i) { - CHECK(gsl::at(a, i) == i + 1); - CHECK(gsl::at({1, 2, 3, 4}, i) == i + 1); - } +TEST_CASE("InitializerList") +{ + std::initializer_list<int> a = {1, 2, 3, 4}; - CHECK_THROW(gsl::at(a, -1), fail_fast); - CHECK_THROW(gsl::at(a, 4), fail_fast); - CHECK_THROW(gsl::at({1, 2, 3, 4}, -1), fail_fast); - CHECK_THROW(gsl::at({1, 2, 3, 4}, 4), fail_fast); + for (int i = 0; i < 4; ++i) { + CHECK(gsl::at(a, i) == i + 1); + CHECK(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); } #if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910 @@ -111,5 +108,3 @@ static constexpr bool test_constexpr() static_assert(test_constexpr(), "FAIL"); #endif - -int main() { return UnitTest::RunAllTests(); } diff --git a/tests/bounds_tests.cpp b/tests/bounds_tests.cpp index b010c3b..51b5393 100644 --- a/tests/bounds_tests.cpp +++ b/tests/bounds_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/multi_span> @@ -28,73 +28,68 @@ namespace void use(std::ptrdiff_t&) {} } -SUITE(bounds_test) +TEST_CASE("basic_bounds") { - TEST(basic_bounds) - { - for (auto point : static_bounds<dynamic_range, 3, 4>{2}) { - for (decltype(point)::size_type j = 0; - j < static_cast<decltype(point)::size_type>(decltype(point)::rank); j++) - { - use(j); - use(point[static_cast<std::size_t>(j)]); - } + for (auto point : static_bounds<dynamic_range, 3, 4>{2}) { + for (decltype(point)::size_type j = 0; + j < static_cast<decltype(point)::size_type>(decltype(point)::rank); j++) + { + use(j); + use(point[static_cast<std::size_t>(j)]); } } +} - TEST(bounds_basic) - { - static_bounds<3, 4, 5> b; - const auto a = b.slice(); - (void) a; - static_bounds<4, dynamic_range, 2> x{4}; - x.slice().slice(); - } +TEST_CASE("bounds_basic") +{ + static_bounds<3, 4, 5> b; + const auto a = b.slice(); + (void) a; + static_bounds<4, dynamic_range, 2> x{4}; + x.slice().slice(); +} - TEST(arrayview_iterator) - { - static_bounds<4, dynamic_range, 2> bounds{3}; +TEST_CASE("arrayview_iterator") +{ + static_bounds<4, dynamic_range, 2> bounds{3}; - const auto itr = bounds.begin(); - (void) itr; + const auto itr = bounds.begin(); + (void) itr; #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 4, dynamic_range, 2> av(nullptr, bounds); + multi_span<int, 4, dynamic_range, 2> av(nullptr, bounds); - auto itr2 = av.cbegin(); + auto itr2 = av.cbegin(); - for (auto& v : av) { - v = 4; - } - fill(av.begin(), av.end(), 0); -#endif + for (auto& v : av) { + v = 4; } + fill(av.begin(), av.end(), 0); +#endif +} - TEST(bounds_convertible) - { - static_bounds<7, 4, 2> b1; - static_bounds<7, dynamic_range, 2> b2 = b1; - (void) b2; +TEST_CASE("bounds_convertible") +{ + static_bounds<7, 4, 2> b1; + static_bounds<7, dynamic_range, 2> b2 = b1; + (void) b2; #ifdef CONFIRM_COMPILATION_ERRORS - static_bounds<7, dynamic_range, 1> b4 = b2; + static_bounds<7, dynamic_range, 1> b4 = b2; #endif - static_bounds<dynamic_range, dynamic_range, dynamic_range> b3 = b1; - static_bounds<7, 4, 2> b4 = b3; - (void) b4; + static_bounds<dynamic_range, dynamic_range, dynamic_range> b3 = b1; + static_bounds<7, 4, 2> b4 = b3; + (void) b4; - static_bounds<dynamic_range> b11; + static_bounds<dynamic_range> b11; - static_bounds<dynamic_range> b5; - static_bounds<34> b6; + static_bounds<dynamic_range> b5; + static_bounds<34> b6; - b5 = static_bounds<20>(); - CHECK_THROW(b6 = b5, fail_fast); - b5 = static_bounds<34>(); - b6 = b5; + b5 = static_bounds<20>(); + CHECK_THROWS_AS(b6 = b5, fail_fast); + b5 = static_bounds<34>(); + b6 = b5; - CHECK(b5 == b6); - CHECK(b5.size() == b6.size()); - } + CHECK(b5 == b6); + CHECK(b5.size() == b6.size()); } - -int main(int, const char* []) { return UnitTest::RunAllTests(); } diff --git a/tests/byte_tests.cpp b/tests/byte_tests.cpp index 753936e..2c6259d 100644 --- a/tests/byte_tests.cpp +++ b/tests/byte_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/gsl_byte> @@ -31,105 +31,101 @@ using namespace gsl; namespace { -SUITE(byte_tests) +TEST_CASE("construction") { - TEST(construction) { - { - const byte b = static_cast<byte>(4); - CHECK(static_cast<unsigned char>(b) == 4); - } - - { - 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); - } - - // waiting for C++17 enum class direct initializer support - //{ - // byte b { 14 }; - // CHECK(static_cast<unsigned char>(b) == 14); - //} + const byte b = static_cast<byte>(4); + CHECK(static_cast<unsigned char>(b) == 4); } - TEST(bitwise_operations) { - const byte b = to_byte<0xFF>(); + const byte b = byte(12); + CHECK(static_cast<unsigned char>(b) == 12); + } - byte a = to_byte<0x00>(); - CHECK((b | a) == to_byte<0xFF>()); - CHECK(a == to_byte<0x00>()); + { + 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); + } - a |= b; - CHECK(a == to_byte<0xFF>()); + // waiting for C++17 enum class direct initializer support + //{ + // byte b { 14 }; + // CHECK(static_cast<unsigned char>(b) == 14); + //} +} - a = to_byte<0x01>(); - CHECK((b & a) == to_byte<0x01>()); +TEST_CASE("bitwise_operations") +{ + const byte b = to_byte<0xFF>(); - a &= b; - CHECK(a == to_byte<0x01>()); + byte a = to_byte<0x00>(); + CHECK((b | a) == to_byte<0xFF>()); + CHECK(a == to_byte<0x00>()); - CHECK((b ^ a) == to_byte<0xFE>()); + a |= b; + CHECK(a == to_byte<0xFF>()); - CHECK(a == to_byte<0x01>()); - a ^= b; - CHECK(a == to_byte<0xFE>()); + a = to_byte<0x01>(); + CHECK((b & a) == to_byte<0x01>()); - a = to_byte<0x01>(); - CHECK(~a == to_byte<0xFE>()); + a &= b; + CHECK(a == to_byte<0x01>()); - a = to_byte<0xFF>(); - CHECK((a << 4) == to_byte<0xF0>()); - CHECK((a >> 4) == to_byte<0x0F>()); + CHECK((b ^ a) == to_byte<0xFE>()); - a <<= 4; - CHECK(a == to_byte<0xF0>()); - a >>= 4; - CHECK(a == to_byte<0x0F>()); - } + CHECK(a == to_byte<0x01>()); + a ^= b; + CHECK(a == to_byte<0xFE>()); - TEST(to_integer) - { - const byte b = to_byte<0x12>(); + a = to_byte<0x01>(); + CHECK(~a == to_byte<0xFE>()); - 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)); + a = to_byte<0xFF>(); + CHECK((a << 4) == to_byte<0xF0>()); + CHECK((a >> 4) == to_byte<0x0F>()); - 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)); + a <<= 4; + CHECK(a == to_byte<0xF0>()); + a >>= 4; + CHECK(a == to_byte<0x0F>()); +} - // CHECK(0x12 == gsl::to_integer<float>(b)); // expect compile-time error - // CHECK(0x12 == gsl::to_integer<double>(b)); // expect compile-time error - } +TEST_CASE("to_integer") +{ + const byte b = to_byte<0x12>(); - int modify_both(gsl::byte & b, int& i) - { - i = 10; - b = to_byte<5>(); - return i; - } + 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)); - TEST(aliasing) - { - int i{0}; - const int res = modify_both(reinterpret_cast<byte&>(i), i); - CHECK(res == i); - } + 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) +{ + i = 10; + b = to_byte<5>(); + return i; } -int main(int, const char* []) { return UnitTest::RunAllTests(); } +TEST_CASE("aliasing") +{ + int i{0}; + const int res = modify_both(reinterpret_cast<byte&>(i), i); + CHECK(res == i); +} + +} diff --git a/tests/multi_span_tests.cpp b/tests/multi_span_tests.cpp index 5f829e1..af58d76 100644 --- a/tests/multi_span_tests.cpp +++ b/tests/multi_span_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/multi_span> @@ -38,1324 +38,1324 @@ struct DerivedClass : BaseClass }; } -SUITE(multi_span_tests) +TEST_CASE("default_constructor") { - - TEST(default_constructor) { - { - multi_span<int> s; - CHECK(s.length() == 0 && s.data() == nullptr); + multi_span<int> s; + CHECK((s.length() == 0 && s.data() == nullptr)); - multi_span<const int> cs; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + multi_span<const int> cs; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { - multi_span<int, 0> s; - CHECK(s.length() == 0 && s.data() == nullptr); + { + multi_span<int, 0> s; + CHECK((s.length() == 0 && s.data() == nullptr)); - multi_span<const int, 0> cs; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + multi_span<const int, 0> cs; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 1> s; - CHECK(s.length() == 1 && s.data() == nullptr); // explains why it can't compile + multi_span<int, 1> s; + CHECK((s.length() == 1 && s.data() == nullptr)); // explains why it can't compile #endif - } + } - { - multi_span<int> s{}; - CHECK(s.length() == 0 && s.data() == nullptr); + { + multi_span<int> s{}; + CHECK((s.length() == 0 && s.data() == nullptr)); - multi_span<const int> cs{}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + multi_span<const int> cs{}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); } +} - TEST(from_nullptr_constructor) +TEST_CASE("from_nullptr_constructor") +{ { - { - multi_span<int> s = nullptr; - CHECK(s.length() == 0 && s.data() == nullptr); + multi_span<int> s = nullptr; + CHECK((s.length() == 0 && s.data() == nullptr)); - multi_span<const int> cs = nullptr; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + multi_span<const int> cs = nullptr; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { - multi_span<int, 0> s = nullptr; - CHECK(s.length() == 0 && s.data() == nullptr); + { + multi_span<int, 0> s = nullptr; + CHECK((s.length() == 0 && s.data() == nullptr)); - multi_span<const int, 0> cs = nullptr; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + multi_span<const int, 0> cs = nullptr; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 1> s = nullptr; - CHECK(s.length() == 1 && s.data() == nullptr); // explains why it can't compile + multi_span<int, 1> s = nullptr; + CHECK((s.length() == 1 && s.data() == nullptr)); // explains why it can't compile #endif - } + } - { - multi_span<int> s{nullptr}; - CHECK(s.length() == 0 && s.data() == nullptr); + { + multi_span<int> s{nullptr}; + CHECK((s.length() == 0 && s.data() == nullptr)); - multi_span<const int> cs{nullptr}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + multi_span<const int> cs{nullptr}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { - multi_span<int*> s{nullptr}; - CHECK(s.length() == 0 && s.data() == nullptr); + { + multi_span<int*> s{nullptr}; + CHECK((s.length() == 0 && s.data() == nullptr)); - multi_span<const int*> cs{nullptr}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + multi_span<const int*> cs{nullptr}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); } +} - TEST(from_nullptr_length_constructor) +TEST_CASE("from_nullptr_length_constructor") +{ { - { - multi_span<int> s{nullptr, 0}; - CHECK(s.length() == 0 && s.data() == nullptr); + multi_span<int> s{nullptr, 0}; + CHECK((s.length() == 0 && s.data() == nullptr)); - multi_span<const int> cs{nullptr, 0}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + multi_span<const int> cs{nullptr, 0}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { - multi_span<int, 0> s{nullptr, 0}; - CHECK(s.length() == 0 && s.data() == nullptr); + { + multi_span<int, 0> s{nullptr, 0}; + CHECK((s.length() == 0 && s.data() == nullptr)); - multi_span<const int, 0> cs{nullptr, 0}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + multi_span<const int, 0> cs{nullptr, 0}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 1> s{nullptr, 0}; - CHECK(s.length() == 1 && s.data() == nullptr); // explains why it can't compile + multi_span<int, 1> s{nullptr, 0}; + CHECK((s.length() == 1 && s.data() == nullptr)); // explains why it can't compile #endif - } + } - { - auto workaround_macro = []() { multi_span<int> s{nullptr, 1}; }; - CHECK_THROW(workaround_macro(), fail_fast); + { + auto workaround_macro = []() { multi_span<int> s{nullptr, 1}; }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); - auto const_workaround_macro = []() { multi_span<const int> cs{nullptr, 1}; }; - CHECK_THROW(const_workaround_macro(), fail_fast); - } + auto const_workaround_macro = []() { multi_span<const int> cs{nullptr, 1}; }; + CHECK_THROWS_AS(const_workaround_macro(), fail_fast); + } - { - auto workaround_macro = []() { multi_span<int, 0> s{nullptr, 1}; }; - CHECK_THROW(workaround_macro(), fail_fast); + { + auto workaround_macro = []() { multi_span<int, 0> s{nullptr, 1}; }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); - auto const_workaround_macro = []() { multi_span<const int, 0> s{nullptr, 1}; }; - CHECK_THROW(const_workaround_macro(), fail_fast); - } + auto const_workaround_macro = []() { multi_span<const int, 0> s{nullptr, 1}; }; + CHECK_THROWS_AS(const_workaround_macro(), fail_fast); + } - { - multi_span<int*> s{nullptr, 0}; - CHECK(s.length() == 0 && s.data() == nullptr); + { + multi_span<int*> s{nullptr, 0}; + CHECK((s.length() == 0 && s.data() == nullptr)); - multi_span<const int*> cs{nullptr, 0}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + multi_span<const int*> cs{nullptr, 0}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); } +} - TEST(from_element_constructor) - { - int i = 5; +TEST_CASE("from_element_constructor") +{ + int i = 5; - { - multi_span<int> s = i; - CHECK(s.length() == 1 && s.data() == &i); - CHECK(s[0] == 5); + { + multi_span<int> s = i; + CHECK((s.length() == 1 && s.data() == &i)); + CHECK(s[0] == 5); - multi_span<const int> cs = i; - CHECK(cs.length() == 1 && cs.data() == &i); - CHECK(cs[0] == 5); - } + multi_span<const int> cs = i; + CHECK((cs.length() == 1 && cs.data() == &i)); + CHECK(cs[0] == 5); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - const j = 1; - multi_span<int, 0> s = j; + const j = 1; + multi_span<int, 0> s = j; #endif - } + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 0> s = i; - CHECK(s.length() == 0 && s.data() == &i); + multi_span<int, 0> s = i; + CHECK((s.length() == 0 && s.data() == &i)); #endif - } + } - { - multi_span<int, 1> s = i; - CHECK(s.length() == 1 && s.data() == &i); - CHECK(s[0] == 5); - } + { + multi_span<int, 1> s = i; + CHECK((s.length() == 1 && s.data() == &i)); + CHECK(s[0] == 5); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 2> s = i; - CHECK(s.length() == 2 && s.data() == &i); + multi_span<int, 2> s = i; + CHECK((s.length() == 2 && s.data() == &i)); #endif - } + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - auto get_a_temp = []() -> int { return 4; }; - auto use_a_span = [](multi_span<int> s) { (void) s; }; - use_a_span(get_a_temp()); + auto get_a_temp = []() -> int { return 4; }; + auto use_a_span = [](multi_span<int> s) { (void) s; }; + use_a_span(get_a_temp()); #endif - } } +} - TEST(from_pointer_length_constructor) - { - int arr[4] = {1, 2, 3, 4}; - - { - multi_span<int> s{&arr[0], 2}; - CHECK(s.length() == 2 && s.data() == &arr[0]); - CHECK(s[0] == 1 && s[1] == 2); - } +TEST_CASE("from_pointer_length_constructor") +{ + int arr[4] = {1, 2, 3, 4}; - { - multi_span<int, 2> s{&arr[0], 2}; - CHECK(s.length() == 2 && s.data() == &arr[0]); - CHECK(s[0] == 1 && s[1] == 2); - } + { + multi_span<int> s{&arr[0], 2}; + CHECK((s.length() == 2 && s.data() == &arr[0])); + CHECK((s[0] == 1 && s[1] == 2)); + } - { - int* p = nullptr; - multi_span<int> s{p, 0}; - CHECK(s.length() == 0 && s.data() == nullptr); - } + { + multi_span<int, 2> s{&arr[0], 2}; + CHECK((s.length() == 2 && s.data() == &arr[0])); + CHECK((s[0] == 1 && s[1] == 2)); + } - { - int* p = nullptr; - auto workaround_macro = [=]() { multi_span<int> s{p, 2}; }; - CHECK_THROW(workaround_macro(), fail_fast); - } + { + int* p = nullptr; + multi_span<int> s{p, 0}; + CHECK((s.length() == 0 && s.data() == nullptr)); } - TEST(from_pointer_pointer_constructor) { - int arr[4] = {1, 2, 3, 4}; + int* p = nullptr; + auto workaround_macro = [=]() { multi_span<int> s{p, 2}; }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } +} - { - multi_span<int> s{&arr[0], &arr[2]}; - CHECK(s.length() == 2 && s.data() == &arr[0]); - CHECK(s[0] == 1 && s[1] == 2); - } +TEST_CASE("from_pointer_pointer_constructor") +{ + int arr[4] = {1, 2, 3, 4}; - { - multi_span<int, 2> s{&arr[0], &arr[2]}; - CHECK(s.length() == 2 && s.data() == &arr[0]); - CHECK(s[0] == 1 && s[1] == 2); - } + { + multi_span<int> s{&arr[0], &arr[2]}; + CHECK((s.length() == 2 && s.data() == &arr[0])); + CHECK((s[0] == 1 && s[1] == 2)); + } - { - multi_span<int> s{&arr[0], &arr[0]}; - CHECK(s.length() == 0 && s.data() == &arr[0]); - } + { + multi_span<int, 2> s{&arr[0], &arr[2]}; + CHECK((s.length() == 2 && s.data() == &arr[0])); + CHECK((s[0] == 1 && s[1] == 2)); + } - { - multi_span<int, 0> s{&arr[0], &arr[0]}; - CHECK(s.length() == 0 && s.data() == &arr[0]); - } + { + multi_span<int> s{&arr[0], &arr[0]}; + CHECK((s.length() == 0 && s.data() == &arr[0])); + } - { - auto workaround_macro = [&]() { multi_span<int> s{&arr[1], &arr[0]}; }; - CHECK_THROW(workaround_macro(), fail_fast); - } + { + multi_span<int, 0> s{&arr[0], &arr[0]}; + CHECK((s.length() == 0 && s.data() == &arr[0])); + } - { - int* p = nullptr; - auto workaround_macro = [&]() { multi_span<int> s{&arr[0], p}; }; - CHECK_THROW(workaround_macro(), fail_fast); - } + { + auto workaround_macro = [&]() { multi_span<int> s{&arr[1], &arr[0]}; }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } - { - int* p = nullptr; - auto workaround_macro = [&]() { multi_span<int> s{p, p}; }; - CHECK_THROW(workaround_macro(), fail_fast); - } + { + int* p = nullptr; + auto workaround_macro = [&]() { multi_span<int> s{&arr[0], p}; }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } - { - int* p = nullptr; - auto workaround_macro = [&]() { multi_span<int> s{&arr[0], p}; }; - CHECK_THROW(workaround_macro(), fail_fast); - } + { + int* p = nullptr; + auto workaround_macro = [&]() { multi_span<int> s{p, p}; }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); } - TEST(from_array_constructor) { - int arr[5] = {1, 2, 3, 4, 5}; + int* p = nullptr; + auto workaround_macro = [&]() { multi_span<int> s{&arr[0], p}; }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } +} - { - multi_span<int> s{arr}; - CHECK(s.length() == 5 && s.data() == &arr[0]); - } +TEST_CASE("from_array_constructor") +{ + int arr[5] = {1, 2, 3, 4, 5}; - { - multi_span<int, 5> s{arr}; - CHECK(s.length() == 5 && s.data() == &arr[0]); - } + { + multi_span<int> s{arr}; + CHECK((s.length() == 5 && s.data() == &arr[0])); + } - { + { + multi_span<int, 5> s{arr}; + CHECK((s.length() == 5 && s.data() == &arr[0])); + } + + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 6> s{arr}; + multi_span<int, 6> s{arr}; #endif - } + } - { - multi_span<int, 0> s{arr}; - CHECK(s.length() == 0 && s.data() == &arr[0]); - } + { + multi_span<int, 0> s{arr}; + CHECK((s.length() == 0 && s.data() == &arr[0])); + } - int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; + int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; - { - multi_span<int> s{arr2d}; - CHECK(s.length() == 6 && s.data() == &arr2d[0][0]); - CHECK(s[0] == 1 && s[5] == 6); - } + { + multi_span<int> s{arr2d}; + CHECK((s.length() == 6 && s.data() == &arr2d[0][0])); + CHECK((s[0] == 1 && s[5] == 6)); + } - { - multi_span<int, 0> s{arr2d}; - CHECK(s.length() == 0 && s.data() == &arr2d[0][0]); - } + { + multi_span<int, 0> s{arr2d}; + CHECK((s.length() == 0 && s.data() == &arr2d[0][0])); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 5> s{arr2d}; + multi_span<int, 5> s{arr2d}; #endif - } + } - { - multi_span<int, 6> s{arr2d}; - CHECK(s.length() == 6 && s.data() == &arr2d[0][0]); - CHECK(s[0] == 1 && s[5] == 6); - } + { + multi_span<int, 6> s{arr2d}; + CHECK((s.length() == 6 && s.data() == &arr2d[0][0])); + CHECK((s[0] == 1 && s[5] == 6)); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 7> s{arr2d}; + multi_span<int, 7> s{arr2d}; #endif - } + } - { - multi_span<int[3]> s{arr2d[0]}; - CHECK(s.length() == 1 && s.data() == &arr2d[0]); - } + { + multi_span<int[3]> s{arr2d[0]}; + CHECK((s.length() == 1 && s.data() == &arr2d[0])); + } - { - multi_span<int, 2, 3> s{arr2d}; - CHECK(s.length() == 6 && s.data() == &arr2d[0][0]); - auto workaround_macro = [&]() { return s[{1, 2}] == 6; }; - CHECK(workaround_macro()); - } + { + multi_span<int, 2, 3> s{arr2d}; + CHECK((s.length() == 6 && s.data() == &arr2d[0][0])); + auto workaround_macro = [&]() { return s[{1, 2}] == 6; }; + CHECK(workaround_macro()); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 3, 3> s{arr2d}; + multi_span<int, 3, 3> s{arr2d}; #endif - } + } - 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}; - { - multi_span<int> s{arr3d}; - CHECK(s.length() == 12 && s.data() == &arr3d[0][0][0]); - CHECK(s[0] == 1 && s[11] == 12); - } + { + multi_span<int> s{arr3d}; + CHECK((s.length() == 12 && s.data() == &arr3d[0][0][0])); + CHECK((s[0] == 1 && s[11] == 12)); + } - { - multi_span<int, 0> s{arr3d}; - CHECK(s.length() == 0 && s.data() == &arr3d[0][0][0]); - } + { + multi_span<int, 0> s{arr3d}; + CHECK((s.length() == 0 && s.data() == &arr3d[0][0][0])); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 11> s{arr3d}; + multi_span<int, 11> s{arr3d}; #endif - } + } - { - multi_span<int, 12> s{arr3d}; - CHECK(s.length() == 12 && s.data() == &arr3d[0][0][0]); - CHECK(s[0] == 1 && s[5] == 6); - } + { + multi_span<int, 12> s{arr3d}; + CHECK((s.length() == 12 && s.data() == &arr3d[0][0][0])); + CHECK((s[0] == 1 && s[5] == 6)); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 13> s{arr3d}; + multi_span<int, 13> s{arr3d}; #endif - } + } - { - multi_span<int[3][2]> s{arr3d[0]}; - CHECK(s.length() == 1 && s.data() == &arr3d[0]); - } + { + multi_span<int[3][2]> s{arr3d[0]}; + CHECK((s.length() == 1 && s.data() == &arr3d[0])); + } - { - multi_span<int, 3, 2, 2> s{arr3d}; - CHECK(s.length() == 12 && s.data() == &arr3d[0][0][0]); - auto workaround_macro = [&]() { return s[{2, 1, 0}] == 11; }; - CHECK(workaround_macro()); - } + { + multi_span<int, 3, 2, 2> s{arr3d}; + CHECK((s.length() == 12 && s.data() == &arr3d[0][0][0])); + auto workaround_macro = [&]() { return s[{2, 1, 0}] == 11; }; + CHECK(workaround_macro()); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 3, 3, 3> s{arr3d}; + multi_span<int, 3, 3, 3> s{arr3d}; #endif - } } +} + +TEST_CASE("from_dynamic_array_constructor") +{ + double(*arr)[3][4] = new double[100][3][4]; - TEST(from_dynamic_array_constructor) { - double(*arr)[3][4] = new double[100][3][4]; + multi_span<double, dynamic_range, 3, 4> s(arr, 10); + CHECK((s.length() == 120 && s.data() == &arr[0][0][0])); + CHECK_THROWS_AS(s[10][3][4], fail_fast); + } - { - multi_span<double, dynamic_range, 3, 4> s(arr, 10); - CHECK(s.length() == 120 && s.data() == &arr[0][0][0]); - CHECK_THROW(s[10][3][4], fail_fast); - } + { + multi_span<double, dynamic_range, 4, 3> s(arr, 10); + CHECK((s.length() == 120 && s.data() == &arr[0][0][0])); + } - { - multi_span<double, dynamic_range, 4, 3> s(arr, 10); - CHECK(s.length() == 120 && s.data() == &arr[0][0][0]); - } + { + multi_span<double> s(arr, 10); + CHECK((s.length() == 120 && s.data() == &arr[0][0][0])); + } - { - multi_span<double> s(arr, 10); - CHECK(s.length() == 120 && s.data() == &arr[0][0][0]); - } + { + multi_span<double, dynamic_range, 3, 4> s(arr, 0); + CHECK((s.length() == 0 && s.data() == &arr[0][0][0])); + } - { - multi_span<double, dynamic_range, 3, 4> s(arr, 0); - CHECK(s.length() == 0 && s.data() == &arr[0][0][0]); - } + delete[] arr; +} - delete[] arr; - } +TEST_CASE("from_std_array_constructor") +{ + std::array<int, 4> arr = {1, 2, 3, 4}; - TEST(from_std_array_constructor) { - std::array<int, 4> arr = {1, 2, 3, 4}; + multi_span<int> s{arr}; + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); - { - multi_span<int> s{arr}; - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - - multi_span<const int> cs{arr}; - CHECK(cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()); - } + multi_span<const int> cs{arr}; + CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data())); + } - { - multi_span<int, 4> s{arr}; - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); + { + multi_span<int, 4> s{arr}; + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); - multi_span<const int, 4> cs{arr}; - CHECK(cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()); - } + multi_span<const int, 4> cs{arr}; + CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data())); + } - { - multi_span<int, 2> s{arr}; - CHECK(s.size() == 2 && s.data() == arr.data()); + { + multi_span<int, 2> s{arr}; + CHECK((s.size() == 2 && s.data() == arr.data())); - multi_span<const int, 2> cs{arr}; - CHECK(cs.size() == 2 && cs.data() == arr.data()); - } + multi_span<const int, 2> cs{arr}; + CHECK((cs.size() == 2 && cs.data() == arr.data())); + } - { - multi_span<int, 0> s{arr}; - CHECK(s.size() == 0 && s.data() == arr.data()); + { + multi_span<int, 0> s{arr}; + CHECK((s.size() == 0 && s.data() == arr.data())); - multi_span<const int, 0> cs{arr}; - CHECK(cs.size() == 0 && cs.data() == arr.data()); - } + multi_span<const int, 0> cs{arr}; + CHECK((cs.size() == 0 && cs.data() == arr.data())); + } - // TODO This is currently an unsupported scenario. We will come back to it as we revise - // the multidimensional interface and what transformations between dimensionality look like - //{ - // multi_span<int, 2, 2> s{arr}; - // CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - //} + // TODO This is currently an unsupported scenario. We will come back to it as we revise + // the multidimensional interface and what transformations between dimensionality look like + //{ + // multi_span<int, 2, 2> s{arr}; + // CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); + //} - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 5> s{arr}; + multi_span<int, 5> s{arr}; #endif - } + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - auto get_an_array = []() { return std::array<int, 4>{1, 2, 3, 4}; }; - auto take_a_span = [](multi_span<int> s) { (void) s; }; - // try to take a temporary std::array - take_a_span(get_an_array()); + auto get_an_array = []() { return std::array<int, 4>{1, 2, 3, 4}; }; + auto take_a_span = [](multi_span<int> s) { (void) s; }; + // try to take a temporary std::array + take_a_span(get_an_array()); #endif - } } +} - TEST(from_const_std_array_constructor) - { - const std::array<int, 4> arr = {1, 2, 3, 4}; +TEST_CASE("from_const_std_array_constructor") +{ + const std::array<int, 4> arr = {1, 2, 3, 4}; - { - multi_span<const int> s{arr}; - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - } + { + multi_span<const int> s{arr}; + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); + } - { - multi_span<const int, 4> s{arr}; - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - } + { + multi_span<const int, 4> s{arr}; + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); + } - { - multi_span<const int, 2> s{arr}; - CHECK(s.size() == 2 && s.data() == arr.data()); - } + { + multi_span<const int, 2> s{arr}; + CHECK((s.size() == 2 && s.data() == arr.data())); + } - { - multi_span<const int, 0> s{arr}; - CHECK(s.size() == 0 && s.data() == arr.data()); - } + { + multi_span<const int, 0> s{arr}; + CHECK((s.size() == 0 && s.data() == arr.data())); + } - // TODO This is currently an unsupported scenario. We will come back to it as we revise - // the multidimensional interface and what transformations between dimensionality look like - //{ - // multi_span<int, 2, 2> s{arr}; - // CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - //} + // TODO This is currently an unsupported scenario. We will come back to it as we revise + // the multidimensional interface and what transformations between dimensionality look like + //{ + // multi_span<int, 2, 2> s{arr}; + // CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); + //} - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<const int, 5> s{arr}; + multi_span<const int, 5> s{arr}; #endif - } + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - auto get_an_array = []() -> const std::array<int, 4> { return {1, 2, 3, 4}; }; - auto take_a_span = [](multi_span<const int> s) { (void) s; }; - // try to take a temporary std::array - take_a_span(get_an_array()); + auto get_an_array = []() -> const std::array<int, 4> { return {1, 2, 3, 4}; }; + auto take_a_span = [](multi_span<const int> s) { (void) s; }; + // try to take a temporary std::array + take_a_span(get_an_array()); #endif - } } +} - TEST(from_container_constructor) - { - std::vector<int> v = {1, 2, 3}; - const std::vector<int> cv = v; +TEST_CASE("from_container_constructor") +{ + std::vector<int> v = {1, 2, 3}; + const std::vector<int> cv = v; - { - multi_span<int> s{v}; - CHECK(s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data()); + { + multi_span<int> s{v}; + CHECK((s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data())); - multi_span<const int> cs{v}; - CHECK(cs.size() == narrow_cast<std::ptrdiff_t>(v.size()) && cs.data() == v.data()); - } + multi_span<const int> cs{v}; + CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(v.size()) && 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 - multi_span<char> s{str}; - CHECK(s.size() == narrow_cast<std::ptrdiff_t>(str.size()) && s.data() == str.data()); + multi_span<char> s{str}; + CHECK((s.size() == narrow_cast<std::ptrdiff_t>(str.size()) && s.data() == str.data())); #endif - multi_span<const char> cs{str}; - CHECK(cs.size() == narrow_cast<std::ptrdiff_t>(str.size()) && cs.data() == str.data()); - } + multi_span<const char> cs{str}; + CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(str.size()) && cs.data() == str.data())); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<char> s{cstr}; + multi_span<char> s{cstr}; #endif - multi_span<const char> cs{cstr}; - CHECK(cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size()) && - cs.data() == cstr.data()); - } + multi_span<const char> cs{cstr}; + CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size()) && + cs.data() == cstr.data())); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_vector = []() -> std::vector<int> { return {}; }; - auto use_span = [](multi_span<int> s) { (void) s; }; - use_span(get_temp_vector()); + auto get_temp_vector = []() -> std::vector<int> { return {}; }; + auto use_span = [](multi_span<int> s) { (void) s; }; + use_span(get_temp_vector()); #endif - } + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_string = []() -> std::string { return {}; }; - auto use_span = [](multi_span<char> s) { (void) s; }; - use_span(get_temp_string()); + auto get_temp_string = []() -> std::string { return {}; }; + auto use_span = [](multi_span<char> s) { (void) s; }; + use_span(get_temp_string()); #endif - } + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_vector = []() -> const std::vector<int> { return {}; }; - auto use_span = [](multi_span<const char> s) { (void) s; }; - use_span(get_temp_vector()); + auto get_temp_vector = []() -> const std::vector<int> { return {}; }; + auto use_span = [](multi_span<const char> s) { (void) s; }; + use_span(get_temp_vector()); #endif - } + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_string = []() -> const std::string { return {}; }; - auto use_span = [](multi_span<const char> s) { (void) s; }; - use_span(get_temp_string()); + auto get_temp_string = []() -> const std::string { return {}; }; + auto use_span = [](multi_span<const char> s) { (void) s; }; + use_span(get_temp_string()); #endif - } + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - std::map<int, int> m; - multi_span<int> s{m}; + std::map<int, int> m; + multi_span<int> s{m}; #endif - } } +} - TEST(from_convertible_span_constructor) - { +TEST_CASE("from_convertible_span_constructor") +{ #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<int, 7, 4, 2> av1(nullptr, b1); + multi_span<int, 7, 4, 2> av1(nullptr, b1); - auto f = [&]() { multi_span<int, 7, 4, 2> av1(nullptr); }; - CHECK_THROW(f(), fail_fast); + auto f = [&]() { multi_span<int, 7, 4, 2> av1(nullptr); }; + CHECK_THROWS_AS(f(), fail_fast); #endif #ifdef CONFIRM_COMPILATION_ERRORS - static_bounds<std::size_t, 7, dynamic_range, 2> b12(b11); - b12 = b11; - b11 = b12; + static_bounds<std::size_t, 7, dynamic_range, 2> b12(b11); + b12 = b11; + b11 = b12; - multi_span<int, dynamic_range> av1 = nullptr; - multi_span<int, 7, dynamic_range, 2> av2(av1); - multi_span<int, 7, 4, 2> av2(av1); + multi_span<int, dynamic_range> av1 = nullptr; + multi_span<int, 7, dynamic_range, 2> av2(av1); + multi_span<int, 7, 4, 2> av2(av1); #endif - multi_span<DerivedClass> avd; + multi_span<DerivedClass> avd; #ifdef CONFIRM_COMPILATION_ERRORS - multi_span<BaseClass> avb = avd; + multi_span<BaseClass> avb = avd; #endif - multi_span<const DerivedClass> avcd = avd; - (void) avcd; - } + multi_span<const DerivedClass> avcd = avd; + (void) avcd; +} - TEST(copy_move_and_assignment) - { - multi_span<int> s1; - CHECK(s1.empty()); +TEST_CASE("copy_move_and_assignment") +{ + multi_span<int> s1; + CHECK(s1.empty()); - int arr[] = {3, 4, 5}; + int arr[] = {3, 4, 5}; - multi_span<const int> s2 = arr; - CHECK(s2.length() == 3 && s2.data() == &arr[0]); + multi_span<const int> s2 = arr; + CHECK((s2.length() == 3 && s2.data() == &arr[0])); - s2 = s1; - CHECK(s2.empty()); + s2 = s1; + CHECK(s2.empty()); - auto get_temp_span = [&]() -> multi_span<int> { return {&arr[1], 2}; }; - auto use_span = [&](multi_span<const int> s) { - CHECK(s.length() == 2 && s.data() == &arr[1]); - }; - use_span(get_temp_span()); + auto get_temp_span = [&]() -> multi_span<int> { return {&arr[1], 2}; }; + auto use_span = [&](multi_span<const int> s) { + CHECK((s.length() == 2 && s.data() == &arr[1])); + }; + use_span(get_temp_span()); - s1 = get_temp_span(); - CHECK(s1.length() == 2 && s1.data() == &arr[1]); - } + s1 = get_temp_span(); + CHECK((s1.length() == 2 && s1.data() == &arr[1])); +} - template <class Bounds> - void fn(const Bounds&) - { - static_assert(Bounds::static_size == 60, "static bounds is wrong size"); - } - TEST(as_multi_span_reshape) - { - int a[3][4][5]; - auto av = as_multi_span(a); - fn(av.bounds()); - auto av2 = as_multi_span(av, dim<60>()); - auto av3 = as_multi_span(av2, dim<3>(), dim<4>(), dim<5>()); - auto av4 = as_multi_span(av3, dim<4>(), dim(3), dim<5>()); - auto av5 = as_multi_span(av4, dim<3>(), dim<4>(), dim<5>()); - auto av6 = as_multi_span(av5, dim<12>(), dim(5)); +template <class Bounds> +void fn(const Bounds&) +{ + static_assert(Bounds::static_size == 60, "static bounds is wrong size"); +} +TEST_CASE("as_multi_span_reshape") +{ + int a[3][4][5]; + auto av = as_multi_span(a); + fn(av.bounds()); + auto av2 = as_multi_span(av, dim<60>()); + auto av3 = as_multi_span(av2, dim<3>(), dim<4>(), dim<5>()); + auto av4 = as_multi_span(av3, dim<4>(), dim(3), dim<5>()); + auto av5 = as_multi_span(av4, dim<3>(), dim<4>(), dim<5>()); + auto av6 = as_multi_span(av5, dim<12>(), dim(5)); - fill(av6.begin(), av6.end(), 1); + fill(av6.begin(), av6.end(), 1); - auto av7 = as_bytes(av6); + auto av7 = as_bytes(av6); - auto av8 = as_multi_span<int>(av7); + auto av8 = as_multi_span<int>(av7); - CHECK(av8.size() == av6.size()); - for (auto i = 0; i < av8.size(); i++) { - CHECK(av8[i] == 1); - } + CHECK(av8.size() == av6.size()); + for (auto i = 0; i < av8.size(); i++) { + CHECK(av8[i] == 1); } +} - TEST(first) - { - int arr[5] = {1, 2, 3, 4, 5}; +TEST_CASE("first") +{ + int arr[5] = {1, 2, 3, 4, 5}; - { - multi_span<int, 5> av = arr; - CHECK((av.first<2>().bounds() == static_bounds<2>())); - CHECK(av.first<2>().length() == 2); - CHECK(av.first(2).length() == 2); - } + { + multi_span<int, 5> av = arr; + CHECK((av.first<2>().bounds() == static_bounds<2>())); + CHECK(av.first<2>().length() == 2); + CHECK(av.first(2).length() == 2); + } - { - multi_span<int, 5> av = arr; - CHECK((av.first<0>().bounds() == static_bounds<0>())); - CHECK(av.first<0>().length() == 0); - CHECK(av.first(0).length() == 0); - } + { + multi_span<int, 5> av = arr; + CHECK((av.first<0>().bounds() == static_bounds<0>())); + CHECK(av.first<0>().length() == 0); + CHECK(av.first(0).length() == 0); + } - { - multi_span<int, 5> av = arr; - CHECK((av.first<5>().bounds() == static_bounds<5>())); - CHECK(av.first<5>().length() == 5); - CHECK(av.first(5).length() == 5); - } + { + multi_span<int, 5> av = arr; + CHECK((av.first<5>().bounds() == static_bounds<5>())); + CHECK(av.first<5>().length() == 5); + CHECK(av.first(5).length() == 5); + } - { - multi_span<int, 5> av = arr; + { + multi_span<int, 5> av = arr; #ifdef CONFIRM_COMPILATION_ERRORS - CHECK(av.first<6>().bounds() == static_bounds<6>()); - CHECK(av.first<6>().length() == 6); - CHECK(av.first<-1>().length() == -1); + CHECK(av.first<6>().bounds() == static_bounds<6>()); + CHECK(av.first<6>().length() == 6); + CHECK(av.first<-1>().length() == -1); #endif - CHECK_THROW(av.first(6).length(), fail_fast); - } - - { - multi_span<int, dynamic_range> av; - CHECK((av.first<0>().bounds() == static_bounds<0>())); - CHECK(av.first<0>().length() == 0); - CHECK(av.first(0).length() == 0); - } + CHECK_THROWS_AS(av.first(6).length(), fail_fast); } - TEST(last) { - int arr[5] = {1, 2, 3, 4, 5}; + multi_span<int, dynamic_range> av; + CHECK((av.first<0>().bounds() == static_bounds<0>())); + CHECK(av.first<0>().length() == 0); + CHECK(av.first(0).length() == 0); + } +} - { - multi_span<int, 5> av = arr; - CHECK((av.last<2>().bounds() == static_bounds<2>())); - CHECK(av.last<2>().length() == 2); - CHECK(av.last(2).length() == 2); - } +TEST_CASE("last") +{ + int arr[5] = {1, 2, 3, 4, 5}; - { - multi_span<int, 5> av = arr; - CHECK((av.last<0>().bounds() == static_bounds<0>())); - CHECK(av.last<0>().length() == 0); - CHECK(av.last(0).length() == 0); - } + { + multi_span<int, 5> av = arr; + CHECK((av.last<2>().bounds() == static_bounds<2>())); + CHECK(av.last<2>().length() == 2); + CHECK(av.last(2).length() == 2); + } - { - multi_span<int, 5> av = arr; - CHECK((av.last<5>().bounds() == static_bounds<5>())); - CHECK(av.last<5>().length() == 5); - CHECK(av.last(5).length() == 5); - } + { + multi_span<int, 5> av = arr; + CHECK((av.last<0>().bounds() == static_bounds<0>())); + CHECK(av.last<0>().length() == 0); + CHECK(av.last(0).length() == 0); + } + + { + multi_span<int, 5> av = arr; + CHECK((av.last<5>().bounds() == static_bounds<5>())); + CHECK(av.last<5>().length() == 5); + CHECK(av.last(5).length() == 5); + } - { - multi_span<int, 5> av = arr; + { + multi_span<int, 5> av = arr; #ifdef CONFIRM_COMPILATION_ERRORS - CHECK((av.last<6>().bounds() == static_bounds<6>())); - CHECK(av.last<6>().length() == 6); + CHECK((av.last<6>().bounds() == static_bounds<6>())); + CHECK(av.last<6>().length() == 6); #endif - CHECK_THROW(av.last(6).length(), fail_fast); - } - - { - multi_span<int, dynamic_range> av; - CHECK((av.last<0>().bounds() == static_bounds<0>())); - CHECK(av.last<0>().length() == 0); - CHECK(av.last(0).length() == 0); - } + CHECK_THROWS_AS(av.last(6).length(), fail_fast); } - TEST(subspan) { - int arr[5] = {1, 2, 3, 4, 5}; + multi_span<int, dynamic_range> av; + CHECK((av.last<0>().bounds() == static_bounds<0>())); + CHECK(av.last<0>().length() == 0); + CHECK(av.last(0).length() == 0); + } +} - { - multi_span<int, 5> av = arr; - CHECK((av.subspan<2, 2>().bounds() == static_bounds<2>())); - CHECK((av.subspan<2, 2>().length() == 2)); - CHECK(av.subspan(2, 2).length() == 2); - CHECK(av.subspan(2, 3).length() == 3); - } +TEST_CASE("subspan") +{ + int arr[5] = {1, 2, 3, 4, 5}; - { - multi_span<int, 5> av = arr; - CHECK((av.subspan<0, 0>().bounds() == static_bounds<0>())); - CHECK((av.subspan<0, 0>().length() == 0)); - CHECK(av.subspan(0, 0).length() == 0); - } + { + multi_span<int, 5> av = arr; + CHECK((av.subspan<2, 2>().bounds() == static_bounds<2>())); + CHECK((av.subspan<2, 2>().length() == 2)); + CHECK(av.subspan(2, 2).length() == 2); + CHECK(av.subspan(2, 3).length() == 3); + } - { - multi_span<int, 5> av = arr; - CHECK((av.subspan<0, 5>().bounds() == static_bounds<5>())); - CHECK((av.subspan<0, 5>().length() == 5)); - CHECK(av.subspan(0, 5).length() == 5); - CHECK_THROW(av.subspan(0, 6).length(), fail_fast); - CHECK_THROW(av.subspan(1, 5).length(), fail_fast); - } + { + multi_span<int, 5> av = arr; + CHECK((av.subspan<0, 0>().bounds() == static_bounds<0>())); + CHECK((av.subspan<0, 0>().length() == 0)); + CHECK(av.subspan(0, 0).length() == 0); + } - { - multi_span<int, 5> av = arr; - CHECK((av.subspan<5, 0>().bounds() == static_bounds<0>())); - CHECK((av.subspan<5, 0>().length() == 0)); - CHECK(av.subspan(5, 0).length() == 0); - CHECK_THROW(av.subspan(6, 0).length(), fail_fast); - } + { + multi_span<int, 5> av = arr; + CHECK((av.subspan<0, 5>().bounds() == static_bounds<5>())); + CHECK((av.subspan<0, 5>().length() == 5)); + CHECK(av.subspan(0, 5).length() == 5); + CHECK_THROWS_AS(av.subspan(0, 6).length(), fail_fast); + CHECK_THROWS_AS(av.subspan(1, 5).length(), fail_fast); + } - { - multi_span<int, dynamic_range> av; - CHECK((av.subspan<0, 0>().bounds() == static_bounds<0>())); - CHECK((av.subspan<0, 0>().length() == 0)); - CHECK(av.subspan(0, 0).length() == 0); - CHECK_THROW((av.subspan<1, 0>().length()), fail_fast); - } + { + multi_span<int, 5> av = arr; + CHECK((av.subspan<5, 0>().bounds() == static_bounds<0>())); + CHECK((av.subspan<5, 0>().length() == 0)); + CHECK(av.subspan(5, 0).length() == 0); + CHECK_THROWS_AS(av.subspan(6, 0).length(), fail_fast); + } - { - multi_span<int> av; - CHECK(av.subspan(0).length() == 0); - CHECK_THROW(av.subspan(1).length(), fail_fast); - } + { + multi_span<int, dynamic_range> av; + CHECK((av.subspan<0, 0>().bounds() == static_bounds<0>())); + CHECK((av.subspan<0, 0>().length() == 0)); + CHECK(av.subspan(0, 0).length() == 0); + CHECK_THROWS_AS((av.subspan<1, 0>().length()), fail_fast); + } - { - multi_span<int> av = arr; - CHECK(av.subspan(0).length() == 5); - CHECK(av.subspan(1).length() == 4); - CHECK(av.subspan(4).length() == 1); - CHECK(av.subspan(5).length() == 0); - CHECK_THROW(av.subspan(6).length(), fail_fast); - auto av2 = av.subspan(1); - for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2); - } + { + multi_span<int> av; + CHECK(av.subspan(0).length() == 0); + CHECK_THROWS_AS(av.subspan(1).length(), fail_fast); + } - { - multi_span<int, 5> av = arr; - CHECK(av.subspan(0).length() == 5); - CHECK(av.subspan(1).length() == 4); - CHECK(av.subspan(4).length() == 1); - CHECK(av.subspan(5).length() == 0); - CHECK_THROW(av.subspan(6).length(), fail_fast); - auto av2 = av.subspan(1); - for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2); - } + { + multi_span<int> av = arr; + CHECK(av.subspan(0).length() == 5); + CHECK(av.subspan(1).length() == 4); + CHECK(av.subspan(4).length() == 1); + CHECK(av.subspan(5).length() == 0); + CHECK_THROWS_AS(av.subspan(6).length(), fail_fast); + auto av2 = av.subspan(1); + for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2); } - TEST(rank) { - int arr[2] = {1, 2}; + multi_span<int, 5> av = arr; + CHECK(av.subspan(0).length() == 5); + CHECK(av.subspan(1).length() == 4); + CHECK(av.subspan(4).length() == 1); + CHECK(av.subspan(5).length() == 0); + CHECK_THROWS_AS(av.subspan(6).length(), fail_fast); + auto av2 = av.subspan(1); + for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2); + } +} - { - multi_span<int> s; - CHECK(s.rank() == 1); - } +TEST_CASE("rank") +{ + int arr[2] = {1, 2}; - { - multi_span<int, 2> s = arr; - CHECK(s.rank() == 1); - } + { + multi_span<int> s; + CHECK(s.rank() == 1); + } - int arr2d[1][1] = {}; - { - multi_span<int, 1, 1> s = arr2d; - CHECK(s.rank() == 2); - } + { + multi_span<int, 2> s = arr; + CHECK(s.rank() == 1); } - TEST(extent) + int arr2d[1][1] = {}; { - { - multi_span<int> s; - CHECK(s.extent() == 0); - CHECK(s.extent(0) == 0); - CHECK_THROW(s.extent(1), fail_fast); + multi_span<int, 1, 1> s = arr2d; + CHECK(s.rank() == 2); + } +} + +TEST_CASE("extent") +{ + { + multi_span<int> s; + CHECK(s.extent() == 0); + CHECK(s.extent(0) == 0); + CHECK_THROWS_AS(s.extent(1), fail_fast); #ifdef CONFIRM_COMPILATION_ERRORS - CHECK(s.extent<1>() == 0); + CHECK(s.extent<1>() == 0); #endif - } - - { - multi_span<int, 0> s; - CHECK(s.extent() == 0); - CHECK(s.extent(0) == 0); - CHECK_THROW(s.extent(1), fail_fast); - } - - { - int arr2d[1][2] = {}; - - multi_span<int, 1, 2> s = arr2d; - CHECK(s.extent() == 1); - CHECK(s.extent<0>() == 1); - CHECK(s.extent<1>() == 2); - CHECK(s.extent(0) == 1); - CHECK(s.extent(1) == 2); - CHECK_THROW(s.extent(3), fail_fast); - } - - { - int arr2d[1][2] = {}; - - multi_span<int, 0, 2> s = arr2d; - CHECK(s.extent() == 0); - CHECK(s.extent<0>() == 0); - CHECK(s.extent<1>() == 2); - CHECK(s.extent(0) == 0); - CHECK(s.extent(1) == 2); - CHECK_THROW(s.extent(3), fail_fast); - } } - TEST(operator_function_call) { - int arr[4] = {1, 2, 3, 4}; - - { - multi_span<int> s = arr; - CHECK(s(0) == 1); - CHECK_THROW(s(5), fail_fast); - } - - int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; - - { - multi_span<int, 2, 3> s = arr2d; - CHECK(s(0, 0) == 1); - CHECK(s(0, 1) == 2); - CHECK(s(1, 2) == 6); - } + multi_span<int, 0> s; + CHECK(s.extent() == 0); + CHECK(s.extent(0) == 0); + CHECK_THROWS_AS(s.extent(1), fail_fast); + } - int arr3d[2][2][2] = {1, 2, 3, 4, 5, 6, 7, 8}; + { + int arr2d[1][2] = {}; - { - multi_span<int, 2, 2, 2> s = arr3d; - CHECK(s(0, 0, 0) == 1); - CHECK(s(1, 1, 1) == 8); - } + multi_span<int, 1, 2> s = arr2d; + CHECK(s.extent() == 1); + CHECK(s.extent<0>() == 1); + CHECK(s.extent<1>() == 2); + CHECK(s.extent(0) == 1); + CHECK(s.extent(1) == 2); + CHECK_THROWS_AS(s.extent(3), fail_fast); } - TEST(comparison_operators) { - { - int arr[10][2]; - auto s1 = as_multi_span(arr); - multi_span<const int, dynamic_range, 2> s2 = s1; + int arr2d[1][2] = {}; - CHECK(s1 == s2); + multi_span<int, 0, 2> s = arr2d; + CHECK(s.extent() == 0); + CHECK(s.extent<0>() == 0); + CHECK(s.extent<1>() == 2); + CHECK(s.extent(0) == 0); + CHECK(s.extent(1) == 2); + CHECK_THROWS_AS(s.extent(3), fail_fast); + } +} - multi_span<int, 20> s3 = as_multi_span(s1, dim(20)); - CHECK(s3 == s2 && s3 == s1); - } +TEST_CASE("operator_function_call") +{ + int arr[4] = {1, 2, 3, 4}; - { - multi_span<int> s1 = nullptr; - multi_span<int> s2 = nullptr; - CHECK(s1 == s2); - CHECK(!(s1 != s2)); - CHECK(!(s1 < s2)); - CHECK(s1 <= s2); - CHECK(!(s1 > s2)); - CHECK(s1 >= s2); - CHECK(s2 == s1); - CHECK(!(s2 != s1)); - CHECK(!(s2 < s1)); - CHECK(s2 <= s1); - CHECK(!(s2 > s1)); - CHECK(s2 >= s1); - } + { + multi_span<int> s = arr; + CHECK(s(0) == 1); + CHECK_THROWS_AS(s(5), fail_fast); + } - { - int arr[] = {2, 1}; // bigger - - multi_span<int> s1 = nullptr; - multi_span<int> s2 = arr; - - CHECK(s1 != s2); - CHECK(s2 != s1); - CHECK(!(s1 == s2)); - CHECK(!(s2 == s1)); - CHECK(s1 < s2); - CHECK(!(s2 < s1)); - CHECK(s1 <= s2); - CHECK(!(s2 <= s1)); - CHECK(s2 > s1); - CHECK(!(s1 > s2)); - CHECK(s2 >= s1); - CHECK(!(s1 >= s2)); - } + int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; - { - int arr1[] = {1, 2}; - int arr2[] = {1, 2}; - multi_span<int> s1 = arr1; - multi_span<int> s2 = arr2; - - CHECK(s1 == s2); - CHECK(!(s1 != s2)); - CHECK(!(s1 < s2)); - CHECK(s1 <= s2); - CHECK(!(s1 > s2)); - CHECK(s1 >= s2); - CHECK(s2 == s1); - CHECK(!(s2 != s1)); - CHECK(!(s2 < s1)); - CHECK(s2 <= s1); - CHECK(!(s2 > s1)); - CHECK(s2 >= s1); - } + { + multi_span<int, 2, 3> s = arr2d; + CHECK(s(0, 0) == 1); + CHECK(s(0, 1) == 2); + CHECK(s(1, 2) == 6); + } - { - int arr[] = {1, 2, 3}; - - multi_span<int> s1 = {&arr[0], 2}; // shorter - multi_span<int> s2 = arr; // longer - - CHECK(s1 != s2); - CHECK(s2 != s1); - CHECK(!(s1 == s2)); - CHECK(!(s2 == s1)); - CHECK(s1 < s2); - CHECK(!(s2 < s1)); - CHECK(s1 <= s2); - CHECK(!(s2 <= s1)); - CHECK(s2 > s1); - CHECK(!(s1 > s2)); - CHECK(s2 >= s1); - CHECK(!(s1 >= s2)); - } + int arr3d[2][2][2] = {1, 2, 3, 4, 5, 6, 7, 8}; - { - int arr1[] = {1, 2}; // smaller - int arr2[] = {2, 1}; // bigger - - multi_span<int> s1 = arr1; - multi_span<int> s2 = arr2; - - CHECK(s1 != s2); - CHECK(s2 != s1); - CHECK(!(s1 == s2)); - CHECK(!(s2 == s1)); - CHECK(s1 < s2); - CHECK(!(s2 < s1)); - CHECK(s1 <= s2); - CHECK(!(s2 <= s1)); - CHECK(s2 > s1); - CHECK(!(s1 > s2)); - CHECK(s2 >= s1); - CHECK(!(s1 >= s2)); - } + { + multi_span<int, 2, 2, 2> s = arr3d; + CHECK(s(0, 0, 0) == 1); + CHECK(s(1, 1, 1) == 8); } +} - TEST(basics) +TEST_CASE("comparison_operators") +{ { - auto ptr = as_multi_span(new int[10], 10); - fill(ptr.begin(), ptr.end(), 99); - for (int num : ptr) { - CHECK(num == 99); - } + int arr[10][2]; + auto s1 = as_multi_span(arr); + multi_span<const int, dynamic_range, 2> s2 = s1; + + CHECK(s1 == s2); + + multi_span<int, 20> s3 = as_multi_span(s1, dim(20)); + CHECK((s3 == s2 && s3 == s1)); + } + + { + multi_span<int> s1 = nullptr; + multi_span<int> s2 = nullptr; + CHECK(s1 == s2); + CHECK(!(s1 != s2)); + CHECK(!(s1 < s2)); + CHECK(s1 <= s2); + CHECK(!(s1 > s2)); + CHECK(s1 >= s2); + CHECK(s2 == s1); + CHECK(!(s2 != s1)); + CHECK(!(s2 < s1)); + CHECK(s2 <= s1); + CHECK(!(s2 > s1)); + CHECK(s2 >= s1); + } + + { + int arr[] = {2, 1}; // bigger + + multi_span<int> s1 = nullptr; + multi_span<int> s2 = arr; + + CHECK(s1 != s2); + CHECK(s2 != s1); + CHECK(!(s1 == s2)); + CHECK(!(s2 == s1)); + CHECK(s1 < s2); + CHECK(!(s2 < s1)); + CHECK(s1 <= s2); + CHECK(!(s2 <= s1)); + CHECK(s2 > s1); + CHECK(!(s1 > s2)); + CHECK(s2 >= s1); + CHECK(!(s1 >= s2)); + } + + { + int arr1[] = {1, 2}; + int arr2[] = {1, 2}; + multi_span<int> s1 = arr1; + multi_span<int> s2 = arr2; + + CHECK(s1 == s2); + CHECK(!(s1 != s2)); + CHECK(!(s1 < s2)); + CHECK(s1 <= s2); + CHECK(!(s1 > s2)); + CHECK(s1 >= s2); + CHECK(s2 == s1); + CHECK(!(s2 != s1)); + CHECK(!(s2 < s1)); + CHECK(s2 <= s1); + CHECK(!(s2 > s1)); + CHECK(s2 >= s1); + } + + { + int arr[] = {1, 2, 3}; + + multi_span<int> s1 = {&arr[0], 2}; // shorter + multi_span<int> s2 = arr; // longer + + CHECK(s1 != s2); + CHECK(s2 != s1); + CHECK(!(s1 == s2)); + CHECK(!(s2 == s1)); + CHECK(s1 < s2); + CHECK(!(s2 < s1)); + CHECK(s1 <= s2); + CHECK(!(s2 <= s1)); + CHECK(s2 > s1); + CHECK(!(s1 > s2)); + CHECK(s2 >= s1); + CHECK(!(s1 >= s2)); + } + + { + int arr1[] = {1, 2}; // smaller + int arr2[] = {2, 1}; // bigger + + multi_span<int> s1 = arr1; + multi_span<int> s2 = arr2; + + CHECK(s1 != s2); + CHECK(s2 != s1); + CHECK(!(s1 == s2)); + CHECK(!(s2 == s1)); + CHECK(s1 < s2); + CHECK(!(s2 < s1)); + CHECK(s1 <= s2); + CHECK(!(s2 <= s1)); + CHECK(s2 > s1); + CHECK(!(s1 > s2)); + CHECK(s2 >= s1); + CHECK(!(s1 >= s2)); + } +} - delete[] ptr.data(); +TEST_CASE("basics") +{ + auto ptr = as_multi_span(new int[10], 10); + fill(ptr.begin(), ptr.end(), 99); + for (int num : ptr) { + CHECK(num == 99); } - TEST(bounds_checks) - { - int arr[10][2]; - auto av = as_multi_span(arr); + delete[] ptr.data(); +} - fill(begin(av), end(av), 0); +TEST_CASE("bounds_checks") +{ + int arr[10][2]; + auto av = as_multi_span(arr); - av[2][0] = 1; - av[1][1] = 3; + fill(begin(av), end(av), 0); - // out of bounds - CHECK_THROW(av[1][3] = 3, fail_fast); - CHECK_THROW((av[{1, 3}] = 3), fail_fast); + av[2][0] = 1; + av[1][1] = 3; - CHECK_THROW(av[10][2], fail_fast); - CHECK_THROW((av[{10, 2}]), fail_fast); + // out of bounds + CHECK_THROWS_AS(av[1][3] = 3, fail_fast); + CHECK_THROWS_AS((av[{1, 3}] = 3), fail_fast); - CHECK_THROW(av[-1][0], fail_fast); - CHECK_THROW((av[{-1, 0}]), fail_fast); + CHECK_THROWS_AS(av[10][2], fail_fast); + CHECK_THROWS_AS((av[{10, 2}]), fail_fast); - CHECK_THROW(av[0][-1], fail_fast); - CHECK_THROW((av[{0, -1}]), fail_fast); - } + CHECK_THROWS_AS(av[-1][0], fail_fast); + CHECK_THROWS_AS((av[{-1, 0}]), fail_fast); - void overloaded_func(multi_span<const int, dynamic_range, 3, 5> exp, int expected_value) - { - for (auto val : exp) { - CHECK(val == expected_value); - } + CHECK_THROWS_AS(av[0][-1], fail_fast); + CHECK_THROWS_AS((av[{0, -1}]), fail_fast); +} + +void overloaded_func(multi_span<const int, dynamic_range, 3, 5> exp, int expected_value) +{ + for (auto val : exp) { + CHECK(val == expected_value); } +} - void overloaded_func(multi_span<const char, dynamic_range, 3, 5> exp, char expected_value) - { - for (auto val : exp) { - CHECK(val == expected_value); - } +void overloaded_func(multi_span<const char, dynamic_range, 3, 5> exp, char expected_value) +{ + for (auto val : exp) { + CHECK(val == expected_value); } +} - void fixed_func(multi_span<int, 3, 3, 5> exp, int expected_value) - { - for (auto val : exp) { - CHECK(val == expected_value); - } +void fixed_func(multi_span<int, 3, 3, 5> exp, int expected_value) +{ + for (auto val : exp) { + CHECK(val == expected_value); } +} - TEST(span_parameter_test) - { - auto data = new int[4][3][5]; +TEST_CASE("span_parameter_test") +{ + auto data = new int[4][3][5]; - auto av = as_multi_span(data, 4); + auto av = as_multi_span(data, 4); - CHECK(av.size() == 60); + CHECK(av.size() == 60); - fill(av.begin(), av.end(), 34); + fill(av.begin(), av.end(), 34); - int count = 0; - for_each(av.rbegin(), av.rend(), [&](int val) { count += val; }); - CHECK(count == 34 * 60); - overloaded_func(av, 34); + int count = 0; + for_each(av.rbegin(), av.rend(), [&](int val) { count += val; }); + CHECK(count == 34 * 60); + overloaded_func(av, 34); - overloaded_func(as_multi_span(av, dim(4), dim(3), dim(5)), 34); + overloaded_func(as_multi_span(av, dim(4), dim(3), dim(5)), 34); - // fixed_func(av, 34); - delete[] data; - } + // fixed_func(av, 34); + delete[] data; +} - TEST(md_access) - { - auto width = 5, height = 20; +TEST_CASE("md_access") +{ + auto width = 5, height = 20; - auto imgSize = width * height; - auto image_ptr = new int[static_cast<std::size_t>(imgSize)][3]; + auto imgSize = width * height; + auto image_ptr = new int[static_cast<std::size_t>(imgSize)][3]; - // size check will be done - auto image_view = - as_multi_span(as_multi_span(image_ptr, imgSize), dim(height), dim(width), dim<3>()); + // size check will be done + auto image_view = + as_multi_span(as_multi_span(image_ptr, imgSize), dim(height), dim(width), dim<3>()); - iota(image_view.begin(), image_view.end(), 1); + iota(image_view.begin(), image_view.end(), 1); - int expected = 0; - for (auto i = 0; i < height; i++) { - for (auto j = 0; j < width; j++) { - CHECK(expected + 1 == image_view[i][j][0]); - CHECK(expected + 2 == image_view[i][j][1]); - CHECK(expected + 3 == image_view[i][j][2]); + int expected = 0; + for (auto i = 0; i < height; i++) { + for (auto j = 0; j < width; j++) { + CHECK(expected + 1 == image_view[i][j][0]); + CHECK(expected + 2 == image_view[i][j][1]); + CHECK(expected + 3 == image_view[i][j][2]); - auto val = image_view[{i, j, 0}]; - CHECK(expected + 1 == val); - val = image_view[{i, j, 1}]; - CHECK(expected + 2 == val); - val = image_view[{i, j, 2}]; - CHECK(expected + 3 == val); + auto val = image_view[{i, j, 0}]; + CHECK(expected + 1 == val); + val = image_view[{i, j, 1}]; + CHECK(expected + 2 == val); + val = image_view[{i, j, 2}]; + CHECK(expected + 3 == val); - expected += 3; - } + expected += 3; } } +} - TEST(as_multi_span) +TEST_CASE("as_multi_span") +{ { - { - int* arr = new int[150]; + int* arr = new int[150]; - auto av = as_multi_span(arr, dim<10>(), dim(3), dim<5>()); + auto av = as_multi_span(arr, dim<10>(), dim(3), dim<5>()); - fill(av.begin(), av.end(), 24); - overloaded_func(av, 24); + fill(av.begin(), av.end(), 24); + overloaded_func(av, 24); - delete[] arr; + delete[] arr; - array<int, 15> stdarr{0}; - auto av2 = as_multi_span(stdarr); - overloaded_func(as_multi_span(av2, dim(1), dim<3>(), dim<5>()), 0); + array<int, 15> stdarr{0}; + auto av2 = as_multi_span(stdarr); + overloaded_func(as_multi_span(av2, dim(1), dim<3>(), dim<5>()), 0); - string str = "ttttttttttttttt"; // size = 15 - auto t = str.data(); - (void) t; - auto av3 = as_multi_span(str); - overloaded_func(as_multi_span(av3, dim(1), dim<3>(), dim<5>()), 't'); - } + string str = "ttttttttttttttt"; // size = 15 + auto t = str.data(); + (void) t; + auto av3 = as_multi_span(str); + overloaded_func(as_multi_span(av3, dim(1), dim<3>(), dim<5>()), 't'); + } - { - string str; - multi_span<char> strspan = as_multi_span(str); - (void) strspan; - const string cstr; - multi_span<const char> cstrspan = as_multi_span(cstr); - (void) cstrspan; - } + { + string str; + multi_span<char> strspan = as_multi_span(str); + (void) strspan; + const string cstr; + multi_span<const char> cstrspan = as_multi_span(cstr); + (void) cstrspan; + } - { - int a[3][4][5]; - auto av = as_multi_span(a); - const int(*b)[4][5]; - b = a; - auto bv = as_multi_span(b, 3); + { + int a[3][4][5]; + auto av = as_multi_span(a); + const int(*b)[4][5]; + b = a; + auto bv = as_multi_span(b, 3); - CHECK(av == bv); + CHECK(av == bv); - const std::array<double, 3> arr = {0.0, 0.0, 0.0}; - auto cv = as_multi_span(arr); - (void) cv; + const std::array<double, 3> arr = {0.0, 0.0, 0.0}; + auto cv = as_multi_span(arr); + (void) cv; - vector<float> vec(3); - auto dv = as_multi_span(vec); - (void) dv; + vector<float> vec(3); + auto dv = as_multi_span(vec); + (void) dv; #ifdef CONFIRM_COMPILATION_ERRORS - auto dv2 = as_multi_span(std::move(vec)); + auto dv2 = as_multi_span(std::move(vec)); #endif - } } +} - TEST(empty_spans) +TEST_CASE("empty_spans") +{ { - { - multi_span<int, 0> empty_av(nullptr); + multi_span<int, 0> empty_av(nullptr); - CHECK(empty_av.bounds().index_bounds() == index<1>{0}); - CHECK_THROW(empty_av[0], fail_fast); - CHECK_THROW(empty_av.begin()[0], fail_fast); - CHECK_THROW(empty_av.cbegin()[0], fail_fast); - for (auto& v : empty_av) { - (void) v; - CHECK(false); - } - } - - { - multi_span<int> empty_av = {}; - CHECK(empty_av.bounds().index_bounds() == index<1>{0}); - CHECK_THROW(empty_av[0], fail_fast); - CHECK_THROW(empty_av.begin()[0], fail_fast); - CHECK_THROW(empty_av.cbegin()[0], fail_fast); - for (auto& v : empty_av) { - (void) v; - CHECK(false); - } + CHECK(empty_av.bounds().index_bounds() == index<1>{0}); + CHECK_THROWS_AS(empty_av[0], fail_fast); + CHECK_THROWS_AS(empty_av.begin()[0], fail_fast); + CHECK_THROWS_AS(empty_av.cbegin()[0], fail_fast); + for (auto& v : empty_av) { + (void) v; + CHECK(false); } } - TEST(index_constructor) { - auto arr = new int[8]; - for (int i = 0; i < 4; ++i) { - arr[2 * i] = 4 + i; - arr[2 * i + 1] = i; + multi_span<int> empty_av = {}; + CHECK(empty_av.bounds().index_bounds() == index<1>{0}); + CHECK_THROWS_AS(empty_av[0], fail_fast); + CHECK_THROWS_AS(empty_av.begin()[0], fail_fast); + CHECK_THROWS_AS(empty_av.cbegin()[0], fail_fast); + for (auto& v : empty_av) { + (void) v; + CHECK(false); } + } +} - multi_span<int, dynamic_range> av(arr, 8); +TEST_CASE("index_constructor") +{ + auto arr = new int[8]; + for (int i = 0; i < 4; ++i) { + arr[2 * i] = 4 + i; + arr[2 * i + 1] = i; + } - ptrdiff_t a[1] = {0}; - index<1> i = a; + multi_span<int, dynamic_range> av(arr, 8); - CHECK(av[i] == 4); + ptrdiff_t a[1] = {0}; + index<1> i = a; - auto av2 = as_multi_span(av, dim<4>(), dim(2)); - ptrdiff_t a2[2] = {0, 1}; - index<2> i2 = a2; + CHECK(av[i] == 4); - CHECK(av2[i2] == 0); - CHECK(av2[0][i] == 4); + auto av2 = as_multi_span(av, dim<4>(), dim(2)); + ptrdiff_t a2[2] = {0, 1}; + index<2> i2 = a2; - delete[] arr; + CHECK(av2[i2] == 0); + CHECK(av2[0][i] == 4); + + delete[] arr; +} + +TEST_CASE("index_constructors") +{ + { + // components of the same type + index<3> i1(0, 1, 2); + CHECK(i1[0] == 0); + + // components of different types + std::size_t c0 = 0; + std::size_t c1 = 1; + index<3> i2(c0, c1, 2); + CHECK(i2[0] == 0); + + // from array + index<3> i3 = {0, 1, 2}; + CHECK(i3[0] == 0); + + // from other index of the same size type + index<3> i4 = i3; + CHECK(i4[0] == 0); + + // default + index<3> i7; + CHECK(i7[0] == 0); + + // default + index<3> i9 = {}; + CHECK(i9[0] == 0); } - TEST(index_constructors){{// components of the same type - index<3> i1(0, 1, 2); - CHECK(i1[0] == 0); + { + // components of the same type + index<1> i1(0); + CHECK(i1[0] == 0); - // components of different types - std::size_t c0 = 0; - std::size_t c1 = 1; - index<3> i2(c0, c1, 2); - CHECK(i2[0] == 0); + // components of different types + std::size_t c0 = 0; + index<1> i2(c0); + CHECK(i2[0] == 0); - // from array - index<3> i3 = {0, 1, 2}; - CHECK(i3[0] == 0); + // from array + index<1> i3 = {0}; + CHECK(i3[0] == 0); - // from other index of the same size type - index<3> i4 = i3; - CHECK(i4[0] == 0); + // from int + index<1> i4 = 0; + CHECK(i4[0] == 0); - // default - index<3> i7; - CHECK(i7[0] == 0); + // from other index of the same size type + index<1> i5 = i3; + CHECK(i5[0] == 0); - // default - index<3> i9 = {}; - CHECK(i9[0] == 0); -} + // default + index<1> i8; + CHECK(i8[0] == 0); -{ - // components of the same type - index<1> i1(0); - CHECK(i1[0] == 0); - - // components of different types - std::size_t c0 = 0; - index<1> i2(c0); - CHECK(i2[0] == 0); - - // from array - index<1> i3 = {0}; - CHECK(i3[0] == 0); - - // from int - index<1> i4 = 0; - CHECK(i4[0] == 0); - - // from other index of the same size type - index<1> i5 = i3; - CHECK(i5[0] == 0); - - // default - index<1> i8; - CHECK(i8[0] == 0); - - // default - index<1> i9 = {}; - CHECK(i9[0] == 0); -} + // default + index<1> i9 = {}; + CHECK(i9[0] == 0); + } -#ifdef CONFIRM_COMPILATION_ERRORS -{ + #ifdef CONFIRM_COMPILATION_ERRORS + { index<3> i1(0, 1); index<3> i2(0, 1, 2, 3); index<3> i3 = {0}; index<3> i4 = {0, 1, 2, 3}; index<1> i5 = {0, 1}; -} -#endif + } + #endif } -TEST(index_operations) +TEST_CASE("index_operations") { ptrdiff_t a[3] = {0, 1, 2}; ptrdiff_t b[3] = {3, 4, 5}; @@ -1465,7 +1465,7 @@ void iterate_second_column(multi_span<int, dynamic_range, dynamic_range> av) } } -TEST(span_section_iteration) +TEST_CASE("span_section_iteration") { int arr[4][2] = {{4, 0}, {5, 1}, {6, 2}, {7, 3}}; @@ -1491,7 +1491,7 @@ TEST(span_section_iteration) } } -TEST(dynamic_span_section_iteration) +TEST_CASE("dynamic_span_section_iteration") { auto height = 4, width = 2; auto size = height * width; @@ -1523,7 +1523,7 @@ TEST(dynamic_span_section_iteration) delete[] arr; } -TEST(span_structure_size) +TEST_CASE("span_structure_size") { double(*arr)[3][4] = new double[100][3][4]; multi_span<double, dynamic_range, 3, 4> av1(arr, 10); @@ -1535,14 +1535,14 @@ TEST(span_structure_size) }; CHECK(sizeof(av1) == sizeof(EffectiveStructure)); - CHECK_THROW(av1[10][3][4], fail_fast); + CHECK_THROWS_AS(av1[10][3][4], fail_fast); multi_span<const double, dynamic_range, 6, 4> av2 = as_multi_span(av1, dim(5), dim<6>(), dim<4>()); (void) av2; } -TEST(fixed_size_conversions) +TEST_CASE("fixed_size_conversions") { int arr[] = {1, 2, 3, 4}; @@ -1626,7 +1626,7 @@ TEST(fixed_size_conversions) multi_span<int, 4> av9 = {arr2, 2}; (void) av9; }; - CHECK_THROW(f(), fail_fast); + CHECK_THROWS_AS(f(), fail_fast); } // this should fail - we are trying to assign a small dynamic a_v to a fixed_size larger one @@ -1635,10 +1635,10 @@ TEST(fixed_size_conversions) multi_span<int, 4> av2 = av; (void) av2; }; - CHECK_THROW(f(), fail_fast); + CHECK_THROWS_AS(f(), fail_fast); } -TEST(as_writeable_bytes) +TEST_CASE("as_writeable_bytes") { int a[] = {1, 2, 3, 4}; @@ -1666,7 +1666,7 @@ TEST(as_writeable_bytes) } } -TEST(iterator) +TEST_CASE("iterator") { int a[] = {1, 2, 3, 4}; @@ -1691,6 +1691,3 @@ TEST(iterator) } } } -} - -int main(int, const char* []) { return UnitTest::RunAllTests(); } diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index caab476..62f1e57 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/gsl> @@ -104,192 +104,182 @@ struct NonCopyableNonMovable NonCopyableNonMovable& operator=(NonCopyableNonMovable&&) = delete; }; +bool helper(not_null<int*> p) { return *p == 12; } -SUITE(NotNullTests) +TEST_CASE("TestNotNullConstructors") { - - bool helper(not_null<int*> p) { return *p == 12; } - - TEST(TestNotNullConstructors) - { #ifdef CONFIRM_COMPILATION_ERRORS - not_null<int*> p = nullptr; // yay...does not compile! - not_null<std::vector<char>*> p = 0; // yay...does not compile! - not_null<int*> p; // yay...does not compile! - std::unique_ptr<int> up = std::make_unique<int>(120); - not_null<int*> p = up; - - // Forbid non-nullptr assignable types - not_null<std::vector<int>> f(std::vector<int>{1}); - not_null<int> z(10); - not_null<std::vector<int>> y({1, 2}); + not_null<int*> p = nullptr; // yay...does not compile! + not_null<std::vector<char>*> p = 0; // yay...does not compile! + not_null<int*> p; // yay...does not compile! + std::unique_ptr<int> up = std::make_unique<int>(120); + not_null<int*> p = up; + + // Forbid non-nullptr assignable types + not_null<std::vector<int>> f(std::vector<int>{1}); + not_null<int> z(10); + not_null<std::vector<int>> y({1, 2}); #endif - int i = 12; - auto rp = RefCounted<int>(&i); - not_null<int*> p(rp); - CHECK(p.get() == &i); + int i = 12; + auto rp = RefCounted<int>(&i); + not_null<int*> p(rp); + CHECK(p.get() == &i); - not_null<std::shared_ptr<int>> x( - std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable - } + not_null<std::shared_ptr<int>> x( + std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable +} - TEST(TestNotNullCasting) - { - MyBase base; - MyDerived derived; - Unrelated unrelated; - not_null<Unrelated*> u = &unrelated; - (void) u; - not_null<MyDerived*> p = &derived; - not_null<MyBase*> q = &base; - q = p; // allowed with heterogeneous copy ctor - CHECK(q == p); +TEST_CASE("TestNotNullCasting") +{ + MyBase base; + MyDerived derived; + Unrelated unrelated; + not_null<Unrelated*> u = &unrelated; + (void) u; + not_null<MyDerived*> p = &derived; + not_null<MyBase*> q = &base; + q = p; // allowed with heterogeneous copy ctor + CHECK(q == p); #ifdef CONFIRM_COMPILATION_ERRORS - q = u; // no viable conversion possible between MyBase* and Unrelated* - p = q; // not possible to implicitly convert MyBase* to MyDerived* + q = u; // no viable conversion possible between MyBase* and Unrelated* + p = q; // not possible to implicitly convert MyBase* to MyDerived* - not_null<Unrelated*> r = p; - not_null<Unrelated*> s = reinterpret_cast<Unrelated*>(p); + not_null<Unrelated*> r = p; + 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())); - } + not_null<Unrelated*> t = reinterpret_cast<Unrelated*>(p.get()); + CHECK(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get())); +} - TEST(TestNotNullAssignment) - { - int i = 12; - not_null<int*> p = &i; - CHECK(helper(p)); +TEST_CASE("TestNotNullAssignment") +{ + int i = 12; + not_null<int*> p = &i; + CHECK(helper(p)); - int* q = nullptr; - CHECK_THROW(p = q, fail_fast); - } + int* q = nullptr; + CHECK_THROWS_AS(p = q, fail_fast); +} - TEST(TestNotNullRawPointerComparison) - { - int ints[2] = {42, 43}; - int* p1 = &ints[0]; - const int* p2 = &ints[1]; +TEST_CASE("TestNotNullRawPointerComparison") +{ + int ints[2] = {42, 43}; + int* p1 = &ints[0]; + const int* p2 = &ints[1]; - using NotNull1 = not_null<decltype(p1)>; - using NotNull2 = not_null<decltype(p2)>; + using NotNull1 = not_null<decltype(p1)>; + using NotNull2 = not_null<decltype(p2)>; - CHECK((NotNull1(p1) == NotNull1(p1)) == true); - CHECK((NotNull1(p1) == NotNull2(p2)) == false); + CHECK((NotNull1(p1) == NotNull1(p1)) == true); + CHECK((NotNull1(p1) == NotNull2(p2)) == false); - CHECK((NotNull1(p1) != NotNull1(p1)) == false); - CHECK((NotNull1(p1) != NotNull2(p2)) == true); + CHECK((NotNull1(p1) != NotNull1(p1)) == false); + CHECK((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)); + CHECK((NotNull1(p1) < NotNull1(p1)) == false); + CHECK((NotNull1(p1) < NotNull2(p2)) == (p1 < p2)); + CHECK((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)); + CHECK((NotNull1(p1) > NotNull1(p1)) == false); + CHECK((NotNull1(p1) > NotNull2(p2)) == (p1 > p2)); + CHECK((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)); + CHECK((NotNull1(p1) <= NotNull1(p1)) == true); + CHECK((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2)); + CHECK((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)); - } +} - TEST(TestNotNullSharedPtrComparison) +TEST_CASE("TestNotNullDereferenceOperator") +{ { - auto sp1 = std::make_shared<int>(42); - auto sp2 = std::make_shared<const int>(43); + auto sp1 = std::make_shared<NonCopyableNonMovable>(); using NotNullSp1 = not_null<decltype(sp1)>; - using NotNullSp2 = not_null<decltype(sp2)>; + CHECK(typeid(*sp1) == typeid(*NotNullSp1(sp1))); + CHECK(std::addressof(*NotNullSp1(sp1)) == std::addressof(*sp1)); + } - CHECK((NotNullSp1(sp1) == NotNullSp1(sp1)) == true); - CHECK((NotNullSp1(sp1) == NotNullSp2(sp2)) == false); + { + int ints[1] = { 42 }; + CustomPtr<int> p1(&ints[0]); - CHECK((NotNullSp1(sp1) != NotNullSp1(sp1)) == false); - CHECK((NotNullSp1(sp1) != NotNullSp2(sp2)) == true); + using NotNull1 = not_null<decltype(p1)>; + CHECK(typeid(*NotNull1(p1)) == typeid(*p1)); + CHECK(*NotNull1(p1) == 42); + *NotNull1(p1) = 43; + CHECK(ints[0] == 43); + } - CHECK((NotNullSp1(sp1) < NotNullSp1(sp1)) == false); - CHECK((NotNullSp1(sp1) < NotNullSp2(sp2)) == (sp1 < sp2)); - CHECK((NotNullSp2(sp2) < NotNullSp1(sp1)) == (sp2 < sp1)); + { + int v = 42; + gsl::not_null<int*> p(&v); + CHECK(typeid(*p) == typeid(*(&v))); + *p = 43; + CHECK(v == 43); + } +} - CHECK((NotNullSp1(sp1) > NotNullSp1(sp1)) == false); - CHECK((NotNullSp1(sp1) > NotNullSp2(sp2)) == (sp1 > sp2)); - CHECK((NotNullSp2(sp2) > NotNullSp1(sp1)) == (sp2 > sp1)); +TEST_CASE("TestNotNullSharedPtrComparison") +{ + auto sp1 = std::make_shared<int>(42); + auto sp2 = std::make_shared<const int>(43); - CHECK((NotNullSp1(sp1) <= NotNullSp1(sp1)) == true); - CHECK((NotNullSp1(sp1) <= NotNullSp2(sp2)) == (sp1 <= sp2)); - CHECK((NotNullSp2(sp2) <= NotNullSp1(sp1)) == (sp2 <= sp1)); + using NotNullSp1 = not_null<decltype(sp1)>; + using NotNullSp2 = not_null<decltype(sp2)>; - CHECK((NotNullSp1(sp1) >= NotNullSp1(sp1)) == true); - CHECK((NotNullSp1(sp1) >= NotNullSp2(sp2)) == (sp1 >= sp2)); - CHECK((NotNullSp2(sp2) >= NotNullSp1(sp1)) == (sp2 >= sp1)); - } + CHECK((NotNullSp1(sp1) == NotNullSp1(sp1)) == true); + CHECK((NotNullSp1(sp1) == NotNullSp2(sp2)) == false); - TEST(TestNotNullCustomPtrComparison) - { - int ints[2] = {42, 43}; - CustomPtr<int> p1(&ints[0]); - CustomPtr<const int> p2(&ints[1]); + CHECK((NotNullSp1(sp1) != NotNullSp1(sp1)) == false); + CHECK((NotNullSp1(sp1) != NotNullSp2(sp2)) == true); - using NotNull1 = not_null<decltype(p1)>; - using NotNull2 = not_null<decltype(p2)>; + CHECK((NotNullSp1(sp1) < NotNullSp1(sp1)) == false); + CHECK((NotNullSp1(sp1) < NotNullSp2(sp2)) == (sp1 < sp2)); + CHECK((NotNullSp2(sp2) < NotNullSp1(sp1)) == (sp2 < sp1)); - CHECK((NotNull1(p1) == NotNull1(p1)) == "true"); - CHECK((NotNull1(p1) == NotNull2(p2)) == "false"); + CHECK((NotNullSp1(sp1) > NotNullSp1(sp1)) == false); + CHECK((NotNullSp1(sp1) > NotNullSp2(sp2)) == (sp1 > sp2)); + CHECK((NotNullSp2(sp2) > NotNullSp1(sp1)) == (sp2 > sp1)); - CHECK((NotNull1(p1) != NotNull1(p1)) == "false"); - CHECK((NotNull1(p1) != NotNull2(p2)) == "true"); + CHECK((NotNullSp1(sp1) <= NotNullSp1(sp1)) == true); + CHECK((NotNullSp1(sp1) <= NotNullSp2(sp2)) == (sp1 <= sp2)); + CHECK((NotNullSp2(sp2) <= NotNullSp1(sp1)) == (sp2 <= sp1)); - CHECK((NotNull1(p1) < NotNull1(p1)) == "false"); - CHECK((NotNull1(p1) < NotNull2(p2)) == (p1 < p2)); - CHECK((NotNull2(p2) < NotNull1(p1)) == (p2 < p1)); + CHECK((NotNullSp1(sp1) >= NotNullSp1(sp1)) == true); + CHECK((NotNullSp1(sp1) >= NotNullSp2(sp2)) == (sp1 >= sp2)); + CHECK((NotNullSp2(sp2) >= NotNullSp1(sp1)) == (sp2 >= sp1)); +} - CHECK((NotNull1(p1) > NotNull1(p1)) == "false"); - CHECK((NotNull1(p1) > NotNull2(p2)) == (p1 > p2)); - CHECK((NotNull2(p2) > NotNull1(p1)) == (p2 > p1)); +TEST_CASE("TestNotNullCustomPtrComparison") +{ + int ints[2] = {42, 43}; + CustomPtr<int> p1(&ints[0]); + CustomPtr<const int> p2(&ints[1]); - CHECK((NotNull1(p1) <= NotNull1(p1)) == "true"); - CHECK((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2)); - CHECK((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1)); + using NotNull1 = not_null<decltype(p1)>; + using NotNull2 = not_null<decltype(p2)>; - CHECK((NotNull1(p1) >= NotNull1(p1)) == "true"); - CHECK((NotNull1(p1) >= NotNull2(p2)) == (p1 >= p2)); - CHECK((NotNull2(p2) >= NotNull1(p1)) == (p2 >= p1)); - } + CHECK((NotNull1(p1) == NotNull1(p1)) == "true"); + CHECK((NotNull1(p1) == NotNull2(p2)) == "false"); - TEST(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)); - } - - { - int ints[1] = { 42 }; - CustomPtr<int> p1(&ints[0]); - - using NotNull1 = not_null<decltype(p1)>; - CHECK(typeid(*NotNull1(p1)) == typeid(*p1)); - CHECK(*NotNull1(p1) == 42); - *NotNull1(p1) = 43; - CHECK(ints[0] == 43); - } - - { - int v = 42; - gsl::not_null<int*> p(&v); - CHECK(typeid(*p) == typeid(*(&v))); - *p = 43; - CHECK(v == 43); - } - } -} + CHECK((NotNull1(p1) != NotNull1(p1)) == "false"); + CHECK((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)); + + CHECK((NotNull1(p1) > NotNull1(p1)) == "false"); + CHECK((NotNull1(p1) > NotNull2(p2)) == (p1 > p2)); + CHECK((NotNull2(p2) > NotNull1(p1)) == (p2 > p1)); -int main(int, const char* []) { return UnitTest::RunAllTests(); } + CHECK((NotNull1(p1) <= NotNull1(p1)) == "true"); + CHECK((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2)); + CHECK((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)); +} diff --git a/tests/owner_tests.cpp b/tests/owner_tests.cpp index 459c646..9885a68 100644 --- a/tests/owner_tests.cpp +++ b/tests/owner_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/gsl> @@ -24,28 +24,23 @@ using namespace gsl; -SUITE(owner_tests) -{ - void f(int* i) { *i += 1; } +void f(int* i) { *i += 1; } - TEST(basic_test) - { - owner<int*> p = new int(120); - CHECK(*p == 120); - f(p); - CHECK(*p == 121); - delete p; - } +TEST_CASE("basic_test") +{ + owner<int*> p = new int(120); + CHECK(*p == 120); + f(p); + CHECK(*p == 121); + delete p; +} - TEST(check_pointer_constraint) +TEST_CASE("check_pointer_constraint") +{ + #ifdef CONFIRM_COMPILATION_ERRORS { - #ifdef CONFIRM_COMPILATION_ERRORS - { - owner<int> integerTest = 10; - owner<std::shared_ptr<int>> sharedPtrTest(new int(10)); - } - #endif + owner<int> integerTest = 10; + owner<std::shared_ptr<int>> sharedPtrTest(new int(10)); } + #endif } - -int main(int, const char* []) { return UnitTest::RunAllTests(); } diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 6af41c6..69a7923 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/span> @@ -39,748 +39,749 @@ struct DerivedClass : BaseClass }; } -SUITE(span_tests) +TEST_CASE("default_constructor") { - TEST(default_constructor) { - { - span<int> s; - CHECK(s.length() == 0 && s.data() == nullptr); + span<int> s; + CHECK((s.length() == 0 && s.data() == nullptr)); - span<const int> cs; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + span<const int> cs; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { - span<int, 0> s; - CHECK(s.length() == 0 && s.data() == nullptr); + { + span<int, 0> s; + CHECK((s.length() == 0 && s.data() == nullptr)); - span<const int, 0> cs; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + span<const int, 0> cs; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - span<int, 1> s; - CHECK(s.length() == 1 && s.data() == nullptr); // explains why it can't compile + span<int, 1> s; + CHECK((s.length() == 1 && s.data() == nullptr)); // explains why it can't compile #endif - } + } - { - span<int> s{}; - CHECK(s.length() == 0 && s.data() == nullptr); + { + span<int> s{}; + CHECK((s.length() == 0 && s.data() == nullptr)); - span<const int> cs{}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + span<const int> cs{}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); } +} - TEST(size_optimization) +TEST_CASE("size_optimization") +{ { - { - span<int> s; - CHECK(sizeof(s) == sizeof(int*) + sizeof(ptrdiff_t)); - } + span<int> s; + CHECK(sizeof(s) == sizeof(int*) + sizeof(ptrdiff_t)); + } - { - span<int, 0> s; - CHECK(sizeof(s) == sizeof(int*)); - } + { + span<int, 0> s; + CHECK(sizeof(s) == sizeof(int*)); } +} - TEST(from_nullptr_constructor) +TEST_CASE("from_nullptr_constructor") +{ { - { - span<int> s = nullptr; - CHECK(s.length() == 0 && s.data() == nullptr); + span<int> s = nullptr; + CHECK((s.length() == 0 && s.data() == nullptr)); - span<const int> cs = nullptr; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + span<const int> cs = nullptr; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { - span<int, 0> s = nullptr; - CHECK(s.length() == 0 && s.data() == nullptr); + { + span<int, 0> s = nullptr; + CHECK((s.length() == 0 && s.data() == nullptr)); - span<const int, 0> cs = nullptr; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + span<const int, 0> cs = nullptr; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - span<int, 1> s = nullptr; - CHECK(s.length() == 1 && s.data() == nullptr); // explains why it can't compile + span<int, 1> s = nullptr; + CHECK((s.length() == 1 && s.data() == nullptr)); // explains why it can't compile #endif - } - - { - span<int> s{nullptr}; - CHECK(s.length() == 0 && s.data() == nullptr); - - span<const int> cs{nullptr}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + } - { - span<int*> s{nullptr}; - CHECK(s.length() == 0 && s.data() == nullptr); + { + span<int> s{nullptr}; + CHECK((s.length() == 0 && s.data() == nullptr)); - span<const int*> cs{nullptr}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + span<const int> cs{nullptr}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); } - TEST(from_nullptr_length_constructor) { - { - span<int> s{nullptr, static_cast<span<int>::index_type>(0)}; - CHECK(s.length() == 0 && s.data() == nullptr); + span<int*> s{nullptr}; + CHECK((s.length() == 0 && s.data() == nullptr)); - span<const int> cs{nullptr, static_cast<span<int>::index_type>(0)}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + span<const int*> cs{nullptr}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } +} - { - span<int, 0> s{nullptr, static_cast<span<int>::index_type>(0)}; - CHECK(s.length() == 0 && s.data() == nullptr); +TEST_CASE("from_nullptr_length_constructor") +{ + { + span<int> s{nullptr, static_cast<span<int>::index_type>(0)}; + CHECK((s.length() == 0 && s.data() == nullptr)); - span<const int, 0> cs{nullptr, static_cast<span<int>::index_type>(0)}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + span<const int> cs{nullptr, static_cast<span<int>::index_type>(0)}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - { - auto workaround_macro = []() { - span<int, 1> s{nullptr, static_cast<span<int>::index_type>(0)}; - }; - CHECK_THROW(workaround_macro(), fail_fast); - } + { + span<int, 0> s{nullptr, static_cast<span<int>::index_type>(0)}; + CHECK((s.length() == 0 && s.data() == nullptr)); - { - auto workaround_macro = []() { span<int> s{nullptr, 1}; }; - CHECK_THROW(workaround_macro(), fail_fast); + span<const int, 0> cs{nullptr, static_cast<span<int>::index_type>(0)}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } - auto const_workaround_macro = []() { span<const int> cs{nullptr, 1}; }; - CHECK_THROW(const_workaround_macro(), fail_fast); - } + { + auto workaround_macro = []() { + span<int, 1> s{nullptr, static_cast<span<int>::index_type>(0)}; + }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } - { - auto workaround_macro = []() { span<int, 0> s{nullptr, 1}; }; - CHECK_THROW(workaround_macro(), fail_fast); + { + auto workaround_macro = []() { span<int> s{nullptr, 1}; }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); - auto const_workaround_macro = []() { span<const int, 0> s{nullptr, 1}; }; - CHECK_THROW(const_workaround_macro(), fail_fast); - } + auto const_workaround_macro = []() { span<const int> cs{nullptr, 1}; }; + CHECK_THROWS_AS(const_workaround_macro(), fail_fast); + } - { - span<int*> s{nullptr, static_cast<span<int>::index_type>(0)}; - CHECK(s.length() == 0 && s.data() == nullptr); + { + auto workaround_macro = []() { span<int, 0> s{nullptr, 1}; }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); - span<const int*> cs{nullptr, static_cast<span<int>::index_type>(0)}; - CHECK(cs.length() == 0 && cs.data() == nullptr); - } + auto const_workaround_macro = []() { span<const int, 0> s{nullptr, 1}; }; + CHECK_THROWS_AS(const_workaround_macro(), fail_fast); } - TEST(from_pointer_length_constructor) { - int arr[4] = {1, 2, 3, 4}; + span<int*> s{nullptr, static_cast<span<int>::index_type>(0)}; + CHECK((s.length() == 0 && s.data() == nullptr)); - { - span<int> s{&arr[0], 2}; - CHECK(s.length() == 2 && s.data() == &arr[0]); - CHECK(s[0] == 1 && s[1] == 2); - } + span<const int*> cs{nullptr, static_cast<span<int>::index_type>(0)}; + CHECK((cs.length() == 0 && cs.data() == nullptr)); + } +} - { - span<int, 2> s{&arr[0], 2}; - CHECK(s.length() == 2 && s.data() == &arr[0]); - CHECK(s[0] == 1 && s[1] == 2); - } +TEST_CASE("from_pointer_length_constructor") +{ + int arr[4] = {1, 2, 3, 4}; - { - int* p = nullptr; - span<int> s{p, static_cast<span<int>::index_type>(0)}; - CHECK(s.length() == 0 && s.data() == nullptr); - } + { + span<int> s{&arr[0], 2}; + CHECK((s.length() == 2 && s.data() == &arr[0])); + CHECK((s[0] == 1 && s[1] == 2)); + } - { - int* p = nullptr; - auto workaround_macro = [=]() { span<int> s{p, 2}; }; - CHECK_THROW(workaround_macro(), fail_fast); - } + { + span<int, 2> s{&arr[0], 2}; + CHECK((s.length() == 2 && s.data() == &arr[0])); + CHECK((s[0] == 1 && s[1] == 2)); + } - { - auto s = make_span(&arr[0], 2); - CHECK(s.length() == 2 && s.data() == &arr[0]); - CHECK(s[0] == 1 && s[1] == 2); - } + { + int* p = nullptr; + span<int> s{p, static_cast<span<int>::index_type>(0)}; + CHECK((s.length() == 0 && s.data() == nullptr)); + } - { - int* p = nullptr; - auto s = make_span(p, static_cast<span<int>::index_type>(0)); - CHECK(s.length() == 0 && s.data() == nullptr); - } + { + int* p = nullptr; + auto workaround_macro = [=]() { span<int> s{p, 2}; }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } - { - int* p = nullptr; - auto workaround_macro = [=]() { make_span(p, 2); }; - CHECK_THROW(workaround_macro(), fail_fast); - } + { + auto s = make_span(&arr[0], 2); + CHECK((s.length() == 2 && s.data() == &arr[0])); + CHECK((s[0] == 1 && s[1] == 2)); } - TEST(from_pointer_pointer_constructor) { - int arr[4] = {1, 2, 3, 4}; + int* p = nullptr; + auto s = make_span(p, static_cast<span<int>::index_type>(0)); + CHECK((s.length() == 0 && s.data() == nullptr)); + } - { - span<int> s{&arr[0], &arr[2]}; - CHECK(s.length() == 2 && s.data() == &arr[0]); - CHECK(s[0] == 1 && s[1] == 2); - } + { + int* p = nullptr; + auto workaround_macro = [=]() { make_span(p, 2); }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } +} - { - span<int, 2> s{&arr[0], &arr[2]}; - CHECK(s.length() == 2 && s.data() == &arr[0]); - CHECK(s[0] == 1 && s[1] == 2); - } +TEST_CASE("from_pointer_pointer_constructor") +{ + int arr[4] = {1, 2, 3, 4}; - { - span<int> s{&arr[0], &arr[0]}; - CHECK(s.length() == 0 && s.data() == &arr[0]); - } + { + span<int> s{&arr[0], &arr[2]}; + CHECK((s.length() == 2 && s.data() == &arr[0])); + CHECK((s[0] == 1 && s[1] == 2)); + } - { - span<int, 0> s{&arr[0], &arr[0]}; - CHECK(s.length() == 0 && s.data() == &arr[0]); - } + { + span<int, 2> s{&arr[0], &arr[2]}; + CHECK((s.length() == 2 && s.data() == &arr[0])); + CHECK((s[0] == 1 && s[1] == 2)); + } - // this will fail the std::distance() precondition, which asserts on MSVC debug builds - //{ - // auto workaround_macro = [&]() { span<int> s{&arr[1], &arr[0]}; }; - // CHECK_THROW(workaround_macro(), fail_fast); - //} + { + span<int> s{&arr[0], &arr[0]}; + CHECK((s.length() == 0 && s.data() == &arr[0])); + } - // this will fail the std::distance() precondition, which asserts on MSVC debug builds - //{ - // int* p = nullptr; - // auto workaround_macro = [&]() { span<int> s{&arr[0], p}; }; - // CHECK_THROW(workaround_macro(), fail_fast); - //} + { + span<int, 0> s{&arr[0], &arr[0]}; + CHECK((s.length() == 0 && s.data() == &arr[0])); + } - { - int* p = nullptr; - span<int> s{p, p}; - CHECK(s.length() == 0 && s.data() == nullptr); - } + // this will fail the std::distance() precondition, which asserts on MSVC debug builds + //{ + // auto workaround_macro = [&]() { span<int> s{&arr[1], &arr[0]}; }; + // CHECK_THROWS_AS(workaround_macro(), fail_fast); + //} - { - int* p = nullptr; - span<int, 0> s{p, p}; - CHECK(s.length() == 0 && s.data() == nullptr); - } + // this will fail the std::distance() precondition, which asserts on MSVC debug builds + //{ + // int* p = nullptr; + // auto workaround_macro = [&]() { span<int> s{&arr[0], p}; }; + // CHECK_THROWS_AS(workaround_macro(), fail_fast); + //} - // this will fail the std::distance() precondition, which asserts on MSVC debug builds - //{ - // int* p = nullptr; - // auto workaround_macro = [&]() { span<int> s{&arr[0], p}; }; - // CHECK_THROW(workaround_macro(), fail_fast); - //} + { + int* p = nullptr; + span<int> s{p, p}; + CHECK((s.length() == 0 && s.data() == nullptr)); + } - { - auto s = make_span(&arr[0], &arr[2]); - CHECK(s.length() == 2 && s.data() == &arr[0]); - CHECK(s[0] == 1 && s[1] == 2); - } + { + int* p = nullptr; + span<int, 0> s{p, p}; + CHECK((s.length() == 0 && s.data() == nullptr)); + } - { - auto s = make_span(&arr[0], &arr[0]); - CHECK(s.length() == 0 && s.data() == &arr[0]); - } + // this will fail the std::distance() precondition, which asserts on MSVC debug builds + //{ + // int* p = nullptr; + // auto workaround_macro = [&]() { span<int> s{&arr[0], p}; }; + // CHECK_THROWS_AS(workaround_macro(), fail_fast); + //} - { - int* p = nullptr; - auto s = make_span(p, p); - CHECK(s.length() == 0 && s.data() == nullptr); - } + { + auto s = make_span(&arr[0], &arr[2]); + CHECK((s.length() == 2 && s.data() == &arr[0])); + CHECK((s[0] == 1 && s[1] == 2)); } - TEST(from_array_constructor) { - int arr[5] = {1, 2, 3, 4, 5}; + auto s = make_span(&arr[0], &arr[0]); + CHECK((s.length() == 0 && s.data() == &arr[0])); + } - { - span<int> s{arr}; - CHECK(s.length() == 5 && s.data() == &arr[0]); - } + { + int* p = nullptr; + auto s = make_span(p, p); + CHECK((s.length() == 0 && s.data() == nullptr)); + } +} - { - span<int, 5> s{arr}; - CHECK(s.length() == 5 && s.data() == &arr[0]); - } +TEST_CASE("from_array_constructor") +{ + int arr[5] = {1, 2, 3, 4, 5}; + + { + span<int> s{arr}; + CHECK((s.length() == 5 && s.data() == &arr[0])); + } + + { + span<int, 5> s{arr}; + CHECK((s.length() == 5 && 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<int, 6> s{arr}; - } + { + span<int, 6> s{arr}; + } - { - span<int, 0> s{arr}; - CHECK(s.length() == 0 && s.data() == &arr[0]); - } + { + span<int, 0> s{arr}; + CHECK((s.length() == 0 && s.data() == &arr[0])); + } - { - span<int> s{arr2d}; - CHECK(s.length() == 6 && s.data() == &arr2d[0][0]); - CHECK(s[0] == 1 && s[5] == 6); - } + { + span<int> s{arr2d}; + CHECK((s.length() == 6 && s.data() == &arr2d[0][0])); + CHECK((s[0] == 1 && s[5] == 6)); + } - { - span<int, 0> s{arr2d}; - CHECK(s.length() == 0 && s.data() == &arr2d[0][0]); - } + { + span<int, 0> s{arr2d}; + CHECK((s.length() == 0 && s.data() == &arr2d[0][0])); + } - { - span<int, 6> s{arr2d}; - } + { + span<int, 6> s{arr2d}; + } #endif - { - span<int[3]> s{&(arr2d[0]), 1}; - CHECK(s.length() == 1 && s.data() == &arr2d[0]); - } + { + span<int[3]> s{&(arr2d[0]), 1}; + CHECK((s.length() == 1 && s.data() == &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<int> s{arr3d}; - CHECK(s.length() == 12 && s.data() == &arr3d[0][0][0]); - CHECK(s[0] == 1 && s[11] == 12); - } + { + span<int> s{arr3d}; + CHECK((s.length() == 12 && s.data() == &arr3d[0][0][0])); + CHECK((s[0] == 1 && s[11] == 12)); + } - { - span<int, 0> s{arr3d}; - CHECK(s.length() == 0 && s.data() == &arr3d[0][0][0]); - } + { + span<int, 0> s{arr3d}; + CHECK((s.length() == 0 && s.data() == &arr3d[0][0][0])); + } - { - span<int, 11> s{arr3d}; - } + { + span<int, 11> s{arr3d}; + } - { - span<int, 12> s{arr3d}; - CHECK(s.length() == 12 && s.data() == &arr3d[0][0][0]); - CHECK(s[0] == 1 && s[5] == 6); - } + { + span<int, 12> s{arr3d}; + CHECK((s.length() == 12 && s.data() == &arr3d[0][0][0])); + CHECK((s[0] == 1 && s[5] == 6)); + } #endif - { - span<int[3][2]> s{&arr3d[0], 1}; - CHECK(s.length() == 1 && s.data() == &arr3d[0]); - } - - { - auto s = make_span(arr); - CHECK(s.length() == 5 && s.data() == &arr[0]); - } - - { - auto s = make_span(&(arr2d[0]), 1); - CHECK(s.length() == 1 && s.data() == &arr2d[0]); - } + { + span<int[3][2]> s{&arr3d[0], 1}; + CHECK((s.length() == 1 && s.data() == &arr3d[0])); + } - { - auto s = make_span(&arr3d[0], 1); - CHECK(s.length() == 1 && s.data() == &arr3d[0]); - } + { + auto s = make_span(arr); + CHECK((s.length() == 5 && s.data() == &arr[0])); } - TEST(from_dynamic_array_constructor) { - double(*arr)[3][4] = new double[100][3][4]; + auto s = make_span(&(arr2d[0]), 1); + CHECK((s.length() == 1 && s.data() == &arr2d[0])); + } - { - span<double> s(&arr[0][0][0], 10); - CHECK(s.length() == 10 && s.data() == &arr[0][0][0]); - } + { + auto s = make_span(&arr3d[0], 1); + CHECK((s.length() == 1 && s.data() == &arr3d[0])); + } +} - { - auto s = make_span(&arr[0][0][0], 10); - CHECK(s.length() == 10 && s.data() == &arr[0][0][0]); - } +TEST_CASE("from_dynamic_array_constructor") +{ + double(*arr)[3][4] = new double[100][3][4]; - delete[] arr; + { + span<double> s(&arr[0][0][0], 10); + CHECK((s.length() == 10 && s.data() == &arr[0][0][0])); } - TEST(from_std_array_constructor) { - std::array<int, 4> arr = {1, 2, 3, 4}; + auto s = make_span(&arr[0][0][0], 10); + CHECK((s.length() == 10 && s.data() == &arr[0][0][0])); + } - { - span<int> s{arr}; - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); + delete[] arr; +} - span<const int> cs{arr}; - CHECK(cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()); - } +TEST_CASE("from_std_array_constructor") +{ + std::array<int, 4> arr = {1, 2, 3, 4}; - { - span<int, 4> s{arr}; - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); + { + span<int> s{arr}; + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); - span<const int, 4> cs{arr}; - CHECK(cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()); - } + span<const int> cs{arr}; + CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data())); + } + + { + span<int, 4> s{arr}; + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); + + span<const int, 4> cs{arr}; + CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data())); + } #ifdef CONFIRM_COMPILATION_ERRORS - { - span<int, 2> s{arr}; - CHECK(s.size() == 2 && s.data() == arr.data()); + { + span<int, 2> s{arr}; + CHECK((s.size() == 2 && s.data() == arr.data())); - span<const int, 2> cs{arr}; - CHECK(cs.size() == 2 && cs.data() == arr.data()); - } + span<const int, 2> cs{arr}; + CHECK((cs.size() == 2 && cs.data() == arr.data())); + } - { - span<int, 0> s{arr}; - CHECK(s.size() == 0 && s.data() == arr.data()); + { + span<int, 0> s{arr}; + CHECK((s.size() == 0 && s.data() == arr.data())); - span<const int, 0> cs{arr}; - CHECK(cs.size() == 0 && cs.data() == arr.data()); - } + span<const int, 0> cs{arr}; + CHECK((cs.size() == 0 && cs.data() == arr.data())); + } - { - span<int, 5> s{arr}; - } + { + span<int, 5> s{arr}; + } - { - auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; }; - auto take_a_span = [](span<int> s) { static_cast<void>(s); }; - // try to take a temporary std::array - take_a_span(get_an_array()); - } + { + auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; }; + auto take_a_span = [](span<int> s) { static_cast<void>(s); }; + // try to take a temporary std::array + take_a_span(get_an_array()); + } #endif - { - auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; }; - auto take_a_span = [](span<const int> s) { static_cast<void>(s); }; - // try to take a temporary std::array - take_a_span(get_an_array()); - } - - { - auto s = make_span(arr); - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - } + { + auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; }; + auto take_a_span = [](span<const int> s) { static_cast<void>(s); }; + // try to take a temporary std::array + take_a_span(get_an_array()); } - TEST(from_const_std_array_constructor) { - const std::array<int, 4> arr = {1, 2, 3, 4}; + auto s = make_span(arr); + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); + } +} - { - span<const int> s{arr}; - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - } +TEST_CASE("from_const_std_array_constructor") +{ + const std::array<int, 4> arr = {1, 2, 3, 4}; - { - span<const int, 4> s{arr}; - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - } + { + span<const int> s{arr}; + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); + } + + { + span<const int, 4> s{arr}; + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); + } #ifdef CONFIRM_COMPILATION_ERRORS - { - span<const int, 2> s{arr}; - CHECK(s.size() == 2 && s.data() == arr.data()); - } + { + span<const int, 2> s{arr}; + CHECK((s.size() == 2 && s.data() == arr.data())); + } - { - span<const int, 0> s{arr}; - CHECK(s.size() == 0 && s.data() == arr.data()); - } + { + span<const int, 0> s{arr}; + CHECK((s.size() == 0 && s.data() == arr.data())); + } - { - span<const int, 5> s{arr}; - } + { + span<const int, 5> s{arr}; + } #endif - { - auto get_an_array = []() -> const std::array<int, 4> { return {1, 2, 3, 4}; }; - auto take_a_span = [](span<const int> s) { static_cast<void>(s); }; - // try to take a temporary std::array - take_a_span(get_an_array()); - } - - { - auto s = make_span(arr); - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - } + { + auto get_an_array = []() -> const std::array<int, 4> { return {1, 2, 3, 4}; }; + auto take_a_span = [](span<const int> s) { static_cast<void>(s); }; + // try to take a temporary std::array + take_a_span(get_an_array()); } - TEST(from_std_array_const_constructor) { - std::array<const int, 4> arr = {1, 2, 3, 4}; + auto s = make_span(arr); + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); + } +} - { - span<const int> s{arr}; - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - } +TEST_CASE("from_std_array_const_constructor") +{ + std::array<const int, 4> arr = {1, 2, 3, 4}; - { - span<const int, 4> s{arr}; - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); - } + { + span<const int> s{arr}; + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); + } + + { + span<const int, 4> s{arr}; + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); + } #ifdef CONFIRM_COMPILATION_ERRORS - { - span<const int, 2> s{arr}; - CHECK(s.size() == 2 && s.data() == arr.data()); - } + { + span<const int, 2> s{arr}; + CHECK((s.size() == 2 && s.data() == arr.data())); + } + + { + span<const int, 0> s{arr}; + CHECK((s.size() == 0 && s.data() == arr.data())); + } + + { + span<const int, 5> s{arr}; + } + + { + span<int, 4> s{arr}; + } +#endif + + { + auto s = make_span(arr); + CHECK((s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data())); + } +} + +TEST_CASE("from_unique_pointer_construction") +{ + { + auto ptr = std::make_unique<int>(4); { - span<const int, 0> s{arr}; - CHECK(s.size() == 0 && s.data() == arr.data()); + span<int> s{ptr}; + CHECK((s.length() == 1 && s.data() == ptr.get())); + CHECK(s[0] == 4); } { - span<const int, 5> s{arr}; + auto s = make_span(ptr); + CHECK((s.length() == 1 && s.data() == ptr.get())); + CHECK(s[0] == 4); } + } + + { + auto ptr = std::unique_ptr<int>{nullptr}; { - span<int, 4> s{arr}; + span<int> s{ptr}; + CHECK((s.length() == 0 && s.data() == nullptr)); } -#endif { - auto s = make_span(arr); - CHECK(s.size() == narrow_cast<ptrdiff_t>(arr.size()) && s.data() == arr.data()); + auto s = make_span(ptr); + CHECK((s.length() == 0 && s.data() == nullptr)); } } - TEST(from_unique_pointer_construction) { + auto arr = std::make_unique<int[]>(4); + + for (auto i = 0U; i < 4; i++) arr[i] = gsl::narrow_cast<int>(i + 1); + { - auto ptr = std::make_unique<int>(4); - - { - span<int> s{ptr}; - CHECK(s.length() == 1 && s.data() == ptr.get()); - CHECK(s[0] == 4); - } - - { - auto s = make_span(ptr); - CHECK(s.length() == 1 && s.data() == ptr.get()); - CHECK(s[0] == 4); - } + span<int> s{arr, 4}; + CHECK((s.length() == 4 && s.data() == arr.get())); + CHECK((s[0] == 1 && s[1] == 2)); } { - auto ptr = std::unique_ptr<int>{nullptr}; + auto s = make_span(arr, 4); + CHECK((s.length() == 4 && s.data() == arr.get())); + CHECK((s[0] == 1 && s[1] == 2)); + } + } - { - span<int> s{ptr}; - CHECK(s.length() == 0 && s.data() == nullptr); - } + { + auto arr = std::unique_ptr<int[]>{nullptr}; - { - auto s = make_span(ptr); - CHECK(s.length() == 0 && s.data() == nullptr); - } + { + span<int> s{arr, 0}; + CHECK((s.length() == 0 && s.data() == nullptr)); } { - auto arr = std::make_unique<int[]>(4); - - for (auto i = 0U; i < 4; i++) arr[i] = gsl::narrow_cast<int>(i + 1); + auto s = make_span(arr, 0); + CHECK((s.length() == 0 && s.data() == nullptr)); + } + } +} - { - span<int> s{arr, 4}; - CHECK(s.length() == 4 && s.data() == arr.get()); - CHECK(s[0] == 1 && s[1] == 2); - } +TEST_CASE("from_shared_pointer_construction") +{ + { + auto ptr = std::make_shared<int>(4); - { - auto s = make_span(arr, 4); - CHECK(s.length() == 4 && s.data() == arr.get()); - CHECK(s[0] == 1 && s[1] == 2); - } + { + span<int> s{ptr}; + CHECK((s.length() == 1 && s.data() == ptr.get())); + CHECK((s[0] == 4)); } { - auto arr = std::unique_ptr<int[]>{nullptr}; - - { - span<int> s{arr, 0}; - CHECK(s.length() == 0 && s.data() == nullptr); - } - - { - auto s = make_span(arr, 0); - CHECK(s.length() == 0 && s.data() == nullptr); - } + auto s = make_span(ptr); + CHECK((s.length() == 1 && s.data() == ptr.get())); + CHECK((s[0] == 4)); } } - TEST(from_shared_pointer_construction) { + auto ptr = std::shared_ptr<int>{nullptr}; + { - auto ptr = std::make_shared<int>(4); - - { - span<int> s{ptr}; - CHECK(s.length() == 1 && s.data() == ptr.get()); - CHECK(s[0] == 4); - } - - { - auto s = make_span(ptr); - CHECK(s.length() == 1 && s.data() == ptr.get()); - CHECK(s[0] == 4); - } + span<int> s{ptr}; + CHECK((s.length() == 0 && s.data() == nullptr)); } { - auto ptr = std::shared_ptr<int>{nullptr}; - - { - span<int> s{ptr}; - CHECK(s.length() == 0 && s.data() == nullptr); - } - - { - auto s = make_span(ptr); - CHECK(s.length() == 0 && s.data() == nullptr); - } + auto s = make_span(ptr); + CHECK((s.length() == 0 && s.data() == nullptr)); } } +} - TEST(from_container_constructor) - { - std::vector<int> v = {1, 2, 3}; - const std::vector<int> cv = v; +TEST_CASE("from_container_constructor") +{ + std::vector<int> v = {1, 2, 3}; + const std::vector<int> cv = v; - { - span<int> s{v}; - CHECK(s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data()); + { + span<int> s{v}; + CHECK((s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data())); - span<const int> cs{v}; - CHECK(cs.size() == narrow_cast<std::ptrdiff_t>(v.size()) && cs.data() == v.data()); - } + span<const int> cs{v}; + CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(v.size()) && 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<char> s{str}; - CHECK(s.size() == narrow_cast<std::ptrdiff_t>(str.size()) && s.data() == str.data()); + span<char> s{str}; + CHECK((s.size() == narrow_cast<std::ptrdiff_t>(str.size()) && s.data() == str.data())); #endif - span<const char> cs{str}; - CHECK(cs.size() == narrow_cast<std::ptrdiff_t>(str.size()) && cs.data() == str.data()); - } + span<const char> cs{str}; + CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(str.size()) && cs.data() == str.data())); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - span<char> s{cstr}; + span<char> s{cstr}; #endif - span<const char> cs{cstr}; - CHECK(cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size()) && - cs.data() == cstr.data()); - } + span<const char> cs{cstr}; + CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size()) && + cs.data() == cstr.data())); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_vector = []() -> std::vector<int> { return {}; }; - auto use_span = [](span<int> s) { static_cast<void>(s); }; - use_span(get_temp_vector()); + auto get_temp_vector = []() -> std::vector<int> { return {}; }; + auto use_span = [](span<int> s) { static_cast<void>(s); }; + use_span(get_temp_vector()); #endif - } + } - { - auto get_temp_vector = []() -> std::vector<int> { return {}; }; - auto use_span = [](span<const int> s) { static_cast<void>(s); }; - use_span(get_temp_vector()); - } + { + auto get_temp_vector = []() -> std::vector<int> { return {}; }; + auto use_span = [](span<const int> s) { static_cast<void>(s); }; + use_span(get_temp_vector()); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_string = []() -> std::string { return {}; }; - auto use_span = [](span<char> s) { static_cast<void>(s); }; - use_span(get_temp_string()); + auto get_temp_string = []() -> std::string { return {}; }; + auto use_span = [](span<char> s) { static_cast<void>(s); }; + use_span(get_temp_string()); #endif - } + } - { - auto get_temp_string = []() -> std::string { return {}; }; - auto use_span = [](span<const char> s) { static_cast<void>(s); }; - use_span(get_temp_string()); - } + { + auto get_temp_string = []() -> std::string { return {}; }; + auto use_span = [](span<const char> s) { static_cast<void>(s); }; + use_span(get_temp_string()); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_vector = []() -> const std::vector<int> { return {}; }; - auto use_span = [](span<const char> s) { static_cast<void>(s); }; - use_span(get_temp_vector()); + auto get_temp_vector = []() -> const std::vector<int> { return {}; }; + auto use_span = [](span<const char> s) { static_cast<void>(s); }; + use_span(get_temp_vector()); #endif - } + } - { - auto get_temp_string = []() -> const std::string { return {}; }; - auto use_span = [](span<const char> s) { static_cast<void>(s); }; - use_span(get_temp_string()); - } + { + auto get_temp_string = []() -> const std::string { return {}; }; + auto use_span = [](span<const char> s) { static_cast<void>(s); }; + use_span(get_temp_string()); + } - { + { #ifdef CONFIRM_COMPILATION_ERRORS - std::map<int, int> m; - span<int> s{m}; + std::map<int, int> m; + span<int> s{m}; #endif - } + } - { - auto s = make_span(v); - CHECK(s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data()); + { + auto s = make_span(v); + CHECK((s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data())); - auto cs = make_span(cv); - CHECK(cs.size() == narrow_cast<std::ptrdiff_t>(cv.size()) && cs.data() == cv.data()); - } + auto cs = make_span(cv); + CHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cv.size()) && cs.data() == cv.data())); } - - TEST(from_convertible_span_constructor){{span<DerivedClass> avd; - span<const DerivedClass> avcd = avd; - static_cast<void>(avcd); } +TEST_CASE("from_convertible_span_constructor") { -#ifdef CONFIRM_COMPILATION_ERRORS - span<DerivedClass> avd; - span<BaseClass> avb = avd; - static_cast<void>(avb); -#endif -} + { + span<DerivedClass> avd; + span<const DerivedClass> avcd = avd; + static_cast<void>(avcd); + } -#ifdef CONFIRM_COMPILATION_ERRORS -{ - span<int> s; - span<unsigned int> s2 = s; - static_cast<void>(s2); -} + { + #ifdef CONFIRM_COMPILATION_ERRORS + span<DerivedClass> avd; + span<BaseClass> avb = avd; + static_cast<void>(avb); + #endif + } -{ - span<int> s; - span<const unsigned int> s2 = s; - static_cast<void>(s2); -} + #ifdef CONFIRM_COMPILATION_ERRORS + { + span<int> s; + span<unsigned int> s2 = s; + static_cast<void>(s2); + } -{ - span<int> s; - span<short> s2 = s; - static_cast<void>(s2); -} -#endif + { + span<int> s; + span<const unsigned int> s2 = s; + static_cast<void>(s2); + } + + { + span<int> s; + span<short> s2 = s; + static_cast<void>(s2); + } + #endif } -TEST(copy_move_and_assignment) +TEST_CASE("copy_move_and_assignment") { span<int> s1; CHECK(s1.empty()); @@ -788,20 +789,20 @@ TEST(copy_move_and_assignment) int arr[] = {3, 4, 5}; span<const int> s2 = arr; - CHECK(s2.length() == 3 && s2.data() == &arr[0]); + CHECK((s2.length() == 3 && s2.data() == &arr[0])); s2 = s1; CHECK(s2.empty()); auto get_temp_span = [&]() -> span<int> { return {&arr[1], 2}; }; - auto use_span = [&](span<const int> s) { CHECK(s.length() == 2 && s.data() == &arr[1]); }; + auto use_span = [&](span<const int> s) { CHECK((s.length() == 2 && s.data() == &arr[1])); }; use_span(get_temp_span()); s1 = get_temp_span(); - CHECK(s1.length() == 2 && s1.data() == &arr[1]); + CHECK((s1.length() == 2 && s1.data() == &arr[1])); } -TEST(first) +TEST_CASE("first") { int arr[5] = {1, 2, 3, 4, 5}; @@ -829,7 +830,7 @@ TEST(first) CHECK(av.first<6>().length() == 6); CHECK(av.first<-1>().length() == -1); #endif - CHECK_THROW(av.first(6).length(), fail_fast); + CHECK_THROWS_AS(av.first(6).length(), fail_fast); } { @@ -839,7 +840,7 @@ TEST(first) } } -TEST(last) +TEST_CASE("last") { int arr[5] = {1, 2, 3, 4, 5}; @@ -866,7 +867,7 @@ TEST(last) #ifdef CONFIRM_COMPILATION_ERRORS CHECK(av.last<6>().length() == 6); #endif - CHECK_THROW(av.last(6).length(), fail_fast); + CHECK_THROWS_AS(av.last(6).length(), fail_fast); } { @@ -876,7 +877,7 @@ TEST(last) } } -TEST(subspan) +TEST_CASE("subspan") { int arr[5] = {1, 2, 3, 4, 5}; @@ -897,8 +898,8 @@ TEST(subspan) span<int, 5> av = arr; CHECK((av.subspan<0, 5>().length() == 5)); CHECK(av.subspan(0, 5).length() == 5); - CHECK_THROW(av.subspan(0, 6).length(), fail_fast); - CHECK_THROW(av.subspan(1, 5).length(), fail_fast); + CHECK_THROWS_AS(av.subspan(0, 6).length(), fail_fast); + CHECK_THROWS_AS(av.subspan(1, 5).length(), fail_fast); } { @@ -906,20 +907,20 @@ TEST(subspan) CHECK((av.subspan<4, 0>().length() == 0)); CHECK(av.subspan(4, 0).length() == 0); CHECK(av.subspan(5, 0).length() == 0); - CHECK_THROW(av.subspan(6, 0).length(), fail_fast); + CHECK_THROWS_AS(av.subspan(6, 0).length(), fail_fast); } { span<int> av; CHECK((av.subspan<0, 0>().length() == 0)); CHECK(av.subspan(0, 0).length() == 0); - CHECK_THROW((av.subspan<1, 0>().length()), fail_fast); + CHECK_THROWS_AS((av.subspan<1, 0>().length()), fail_fast); } { span<int> av; CHECK(av.subspan(0).length() == 0); - CHECK_THROW(av.subspan(1).length(), fail_fast); + CHECK_THROWS_AS(av.subspan(1).length(), fail_fast); } { @@ -928,7 +929,7 @@ TEST(subspan) CHECK(av.subspan(1).length() == 4); CHECK(av.subspan(4).length() == 1); CHECK(av.subspan(5).length() == 0); - CHECK_THROW(av.subspan(6).length(), fail_fast); + CHECK_THROWS_AS(av.subspan(6).length(), fail_fast); const auto av2 = av.subspan(1); for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2); } @@ -939,20 +940,20 @@ TEST(subspan) CHECK(av.subspan(1).length() == 4); CHECK(av.subspan(4).length() == 1); CHECK(av.subspan(5).length() == 0); - CHECK_THROW(av.subspan(6).length(), fail_fast); + CHECK_THROWS_AS(av.subspan(6).length(), fail_fast); const auto av2 = av.subspan(1); for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2); } } -TEST(at_call) +TEST_CASE("at_call") { int arr[4] = {1, 2, 3, 4}; { span<int> s = arr; CHECK(s.at(0) == 1); - CHECK_THROW(s.at(5), fail_fast); + CHECK_THROWS_AS(s.at(5), fail_fast); } { @@ -960,18 +961,18 @@ TEST(at_call) span<int, 2> s = arr2d; CHECK(s.at(0) == 1); CHECK(s.at(1) == 6); - CHECK_THROW(s.at(2), fail_fast); + CHECK_THROWS_AS(s.at(2), fail_fast); } } -TEST(operator_function_call) +TEST_CASE("operator_function_call") { int arr[4] = {1, 2, 3, 4}; { span<int> s = arr; CHECK(s(0) == 1); - CHECK_THROW(s(5), fail_fast); + CHECK_THROWS_AS(s(5), fail_fast); } { @@ -979,25 +980,25 @@ TEST(operator_function_call) span<int, 2> s = arr2d; CHECK(s(0) == 1); CHECK(s(1) == 6); - CHECK_THROW(s(2), fail_fast); + CHECK_THROWS_AS(s(2), fail_fast); } } -TEST(iterator_default_init) +TEST_CASE("iterator_default_init") { span<int>::iterator it1; span<int>::iterator it2; CHECK(it1 == it2); } -TEST(const_iterator_default_init) +TEST_CASE("const_iterator_default_init") { span<int>::const_iterator it1; span<int>::const_iterator it2; CHECK(it1 == it2); } -TEST(iterator_conversions) +TEST_CASE("iterator_conversions") { span<int>::iterator badIt; span<int>::const_iterator badConstIt; @@ -1019,7 +1020,7 @@ TEST(iterator_conversions) CHECK(cit3 == s.cend()); } -TEST(iterator_comparisons) +TEST_CASE("iterator_comparisons") { int a[] = {1, 2, 3, 4}; { @@ -1066,7 +1067,7 @@ TEST(iterator_comparisons) } } -TEST(begin_end) +TEST_CASE("begin_end") { { int a[] = {1, 2, 3, 4}; @@ -1092,7 +1093,7 @@ TEST(begin_end) auto beyond = s.end(); CHECK(it != beyond); - CHECK_THROW(*beyond, fail_fast); + CHECK_THROWS_AS(*beyond, fail_fast); CHECK(beyond - first == 4); CHECK(first - first == 0); @@ -1121,7 +1122,7 @@ TEST(begin_end) } } -TEST(cbegin_cend) +TEST_CASE("cbegin_cend") { { int a[] = {1, 2, 3, 4}; @@ -1147,7 +1148,7 @@ TEST(cbegin_cend) auto beyond = s.cend(); CHECK(it != beyond); - CHECK_THROW(*beyond, fail_fast); + CHECK_THROWS_AS(*beyond, fail_fast); CHECK(beyond - first == 4); CHECK(first - first == 0); @@ -1173,7 +1174,7 @@ TEST(cbegin_cend) } } -TEST(rbegin_rend) +TEST_CASE("rbegin_rend") { { int a[] = {1, 2, 3, 4}; @@ -1186,7 +1187,7 @@ TEST(rbegin_rend) auto beyond = s.rend(); CHECK(it != beyond); - CHECK_THROW(*beyond, fail_fast); + CHECK_THROWS_AS(*beyond, fail_fast); CHECK(beyond - first == 4); CHECK(first - first == 0); @@ -1215,7 +1216,7 @@ TEST(rbegin_rend) } } -TEST(crbegin_crend) +TEST_CASE("crbegin_crend") { { int a[] = {1, 2, 3, 4}; @@ -1228,7 +1229,7 @@ TEST(crbegin_crend) auto beyond = s.crend(); CHECK(it != beyond); - CHECK_THROW(*beyond, fail_fast); + CHECK_THROWS_AS(*beyond, fail_fast); CHECK(beyond - first == 4); CHECK(first - first == 0); @@ -1254,7 +1255,7 @@ TEST(crbegin_crend) } } -TEST(comparison_operators) +TEST_CASE("comparison_operators") { { span<int> s1 = nullptr; @@ -1374,7 +1375,7 @@ TEST(comparison_operators) } } -TEST(as_bytes) +TEST_CASE("as_bytes") { int a[] = {1, 2, 3, 4}; @@ -1404,7 +1405,7 @@ TEST(as_bytes) } } -TEST(as_writeable_bytes) +TEST_CASE("as_writeable_bytes") { int a[] = {1, 2, 3, 4}; @@ -1437,7 +1438,7 @@ TEST(as_writeable_bytes) } } -TEST(fixed_size_conversions) +TEST_CASE("fixed_size_conversions") { int arr[] = {1, 2, 3, 4}; @@ -1470,7 +1471,7 @@ TEST(fixed_size_conversions) span<int, 2> s2 = s; static_cast<void>(s2); }; - CHECK_THROW(f(), fail_fast); + CHECK_THROWS_AS(f(), fail_fast); } // but doing so explicitly is ok @@ -1509,7 +1510,7 @@ TEST(fixed_size_conversions) span<int, 4> _s4 = {arr2, 2}; static_cast<void>(_s4); }; - CHECK_THROW(f(), fail_fast); + CHECK_THROWS_AS(f(), fail_fast); } // this should fail - we are trying to assign a small dynamic span to a fixed_size larger one @@ -1518,10 +1519,10 @@ TEST(fixed_size_conversions) span<int, 4> _s4 = av; static_cast<void>(_s4); }; - CHECK_THROW(f(), fail_fast); + CHECK_THROWS_AS(f(), fail_fast); } -TEST(interop_with_std_regex) +TEST_CASE("interop_with_std_regex") { char lat[] = {'1', '2', '3', '4', '5', '6', 'E', 'F', 'G'}; span<char> s = lat; @@ -1544,19 +1545,16 @@ TEST(interop_with_std_regex) CHECK(match[0].second == (f_it + 1)); } -TEST(interop_with_gsl_at) +TEST_CASE("interop_with_gsl_at") { int arr[5] = {1, 2, 3, 4, 5}; span<int> s{arr}; - CHECK(at(s, 0) == 1 && at(s, 1) == 2); + CHECK((at(s, 0) == 1 && at(s, 1) == 2)); } -TEST(default_constructible) +TEST_CASE("default_constructible") { CHECK((std::is_default_constructible<span<int>>::value)); CHECK((std::is_default_constructible<span<int, 0>>::value)); CHECK((!std::is_default_constructible<span<int, 42>>::value)); } -} - -int main(int, const char* []) { return UnitTest::RunAllTests(); } diff --git a/tests/strided_span_tests.cpp b/tests/strided_span_tests.cpp index bafa304..a1ecfcb 100644 --- a/tests/strided_span_tests.cpp +++ b/tests/strided_span_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/multi_span> @@ -38,720 +38,715 @@ struct DerivedClass : BaseClass }; } -SUITE(strided_span_tests) +TEST_CASE("span_section_test") { - TEST(span_section_test) - { - int a[30][4][5]; - - const auto av = as_multi_span(a); - const auto sub = av.section({15, 0, 0}, gsl::index<3>{2, 2, 2}); - const auto subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1}); - (void) subsub; - } + int a[30][4][5]; - TEST(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 auto av = as_multi_span(a); + const auto sub = av.section({15, 0, 0}, gsl::index<3>{2, 2, 2}); + const auto subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1}); + (void) subsub; +} - const strided_span<int, 2> av_section_1 = av.section({1, 2}, {3, 4}); - 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)); +TEST_CASE("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[{0, 0}] == 12)); + CHECK((av_section_1[{0, 1}] == 13)); + CHECK((av_section_1[{1, 0}] == 22)); + CHECK((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[{0, 0}] == 24)); + CHECK((av_section_2[{0, 1}] == 25)); + CHECK((av_section_2[{1, 0}] == 34)); +} - const strided_span<int, 2> av_section_2 = av_section_1.section({1, 2}, {2, 2}); - CHECK((av_section_2[{0, 0}] == 24)); - CHECK((av_section_2[{0, 1}] == 25)); - CHECK((av_section_2[{1, 0}] == 34)); +TEST_CASE("strided_span_constructors") +{ + // Check 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() == index<1>{9}); + CHECK(sav1.bounds().stride() == 1); + CHECK((sav1[0] == 1 && sav1[8] == 9)); + + strided_span<const int, 1> sav2{carr, {{4}, {2}}}; // const T -> const T + CHECK(sav2.bounds().index_bounds() == index<1>{4}); + CHECK(sav2.bounds().strides() == index<1>{2}); + CHECK((sav2[0] == 1 && sav2[3] == 7)); + + strided_span<int, 2> sav3{arr, {{2, 2}, {6, 2}}}; // T -> const T + CHECK((sav3.bounds().index_bounds() == index<2>{2, 2})); + CHECK((sav3.bounds().strides() == index<2>{6, 2})); + CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7)); } - TEST(strided_span_constructors) + // Check multi_span constructor { - // Check 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() == index<1>{9}); - CHECK(sav1.bounds().stride() == 1); - CHECK(sav1[0] == 1 && sav1[8] == 9); - - strided_span<const int, 1> sav2{carr, {{4}, {2}}}; // const T -> const T - CHECK(sav2.bounds().index_bounds() == index<1>{4}); - CHECK(sav2.bounds().strides() == index<1>{2}); - CHECK(sav2[0] == 1 && sav2[3] == 7); - - strided_span<int, 2> sav3{arr, {{2, 2}, {6, 2}}}; // T -> const T - CHECK((sav3.bounds().index_bounds() == index<2>{2, 2})); - CHECK((sav3.bounds().strides() == index<2>{6, 2})); - CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7)); - } + int arr[] = {1, 2}; - // Check multi_span constructor + // From non-cv-qualified source { - int arr[] = {1, 2}; + const multi_span<int> src = arr; - // From non-cv-qualified source - { - const multi_span<int> src = arr; - - strided_span<int, 1> sav{src, {2, 1}}; - CHECK(sav.bounds().index_bounds() == index<1>{2}); - CHECK(sav.bounds().strides() == index<1>{1}); - CHECK(sav[1] == 2); + strided_span<int, 1> sav{src, {2, 1}}; + CHECK(sav.bounds().index_bounds() == index<1>{2}); + CHECK(sav.bounds().strides() == index<1>{1}); + CHECK(sav[1] == 2); #if _MSC_VER > 1800 - // strided_span<const int, 1> sav_c{ {src}, {2, 1} }; - strided_span<const int, 1> sav_c{multi_span<const int>{src}, - strided_bounds<1>{2, 1}}; + // strided_span<const int, 1> sav_c{ {src}, {2, 1} }; + strided_span<const int, 1> sav_c{multi_span<const int>{src}, + strided_bounds<1>{2, 1}}; #else - strided_span<const int, 1> sav_c{multi_span<const int>{src}, - strided_bounds<1>{2, 1}}; + strided_span<const int, 1> sav_c{multi_span<const int>{src}, + strided_bounds<1>{2, 1}}; #endif - CHECK(sav_c.bounds().index_bounds() == index<1>{2}); - CHECK(sav_c.bounds().strides() == index<1>{1}); - CHECK(sav_c[1] == 2); + CHECK(sav_c.bounds().index_bounds() == index<1>{2}); + CHECK(sav_c.bounds().strides() == index<1>{1}); + CHECK(sav_c[1] == 2); #if _MSC_VER > 1800 - strided_span<volatile int, 1> sav_v{src, {2, 1}}; + strided_span<volatile int, 1> sav_v{src, {2, 1}}; #else - strided_span<volatile int, 1> sav_v{multi_span<volatile int>{src}, - strided_bounds<1>{2, 1}}; + strided_span<volatile int, 1> sav_v{multi_span<volatile int>{src}, + strided_bounds<1>{2, 1}}; #endif - CHECK(sav_v.bounds().index_bounds() == index<1>{2}); - CHECK(sav_v.bounds().strides() == index<1>{1}); - CHECK(sav_v[1] == 2); + CHECK(sav_v.bounds().index_bounds() == index<1>{2}); + CHECK(sav_v.bounds().strides() == index<1>{1}); + CHECK(sav_v[1] == 2); #if _MSC_VER > 1800 - strided_span<const volatile int, 1> sav_cv{src, {2, 1}}; + strided_span<const volatile int, 1> sav_cv{src, {2, 1}}; #else - strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src}, - strided_bounds<1>{2, 1}}; + 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() == index<1>{2}); - CHECK(sav_cv.bounds().strides() == index<1>{1}); - CHECK(sav_cv[1] == 2); - } + CHECK(sav_cv.bounds().index_bounds() == index<1>{2}); + CHECK(sav_cv.bounds().strides() == index<1>{1}); + CHECK(sav_cv[1] == 2); + } - // From const-qualified source - { - const multi_span<const int> src{arr}; + // From const-qualified source + { + const multi_span<const int> src{arr}; - strided_span<const int, 1> sav_c{src, {2, 1}}; - CHECK(sav_c.bounds().index_bounds() == index<1>{2}); - CHECK(sav_c.bounds().strides() == index<1>{1}); - CHECK(sav_c[1] == 2); + strided_span<const int, 1> sav_c{src, {2, 1}}; + CHECK(sav_c.bounds().index_bounds() == index<1>{2}); + CHECK(sav_c.bounds().strides() == index<1>{1}); + CHECK(sav_c[1] == 2); #if _MSC_VER > 1800 - strided_span<const volatile int, 1> sav_cv{src, {2, 1}}; + strided_span<const volatile int, 1> sav_cv{src, {2, 1}}; #else - strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src}, - strided_bounds<1>{2, 1}}; + 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() == index<1>{2}); - CHECK(sav_cv.bounds().strides() == index<1>{1}); - CHECK(sav_cv[1] == 2); - } + CHECK(sav_cv.bounds().index_bounds() == index<1>{2}); + CHECK(sav_cv.bounds().strides() == index<1>{1}); + CHECK(sav_cv[1] == 2); + } - // From volatile-qualified source - { - const multi_span<volatile int> src{arr}; + // From volatile-qualified source + { + const multi_span<volatile int> src{arr}; - strided_span<volatile int, 1> sav_v{src, {2, 1}}; - CHECK(sav_v.bounds().index_bounds() == index<1>{2}); - CHECK(sav_v.bounds().strides() == index<1>{1}); - CHECK(sav_v[1] == 2); + strided_span<volatile int, 1> sav_v{src, {2, 1}}; + CHECK(sav_v.bounds().index_bounds() == index<1>{2}); + CHECK(sav_v.bounds().strides() == index<1>{1}); + CHECK(sav_v[1] == 2); #if _MSC_VER > 1800 - strided_span<const volatile int, 1> sav_cv{src, {2, 1}}; + strided_span<const volatile int, 1> sav_cv{src, {2, 1}}; #else - strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src}, - strided_bounds<1>{2, 1}}; + 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() == index<1>{2}); - CHECK(sav_cv.bounds().strides() == index<1>{1}); - CHECK(sav_cv[1] == 2); - } - - // From cv-qualified source - { - const multi_span<const volatile int> src{arr}; - - strided_span<const volatile int, 1> sav_cv{src, {2, 1}}; - CHECK(sav_cv.bounds().index_bounds() == index<1>{2}); - CHECK(sav_cv.bounds().strides() == index<1>{1}); - CHECK(sav_cv[1] == 2); - } + CHECK(sav_cv.bounds().index_bounds() == index<1>{2}); + CHECK(sav_cv.bounds().strides() == index<1>{1}); + CHECK(sav_cv[1] == 2); } - // Check const-casting constructor + // From cv-qualified source { - int arr[2] = {4, 5}; + const multi_span<const volatile int> src{arr}; - const multi_span<int, 2> av(arr, 2); - multi_span<const int, 2> av2{av}; - CHECK(av2[1] == 5); + strided_span<const volatile int, 1> sav_cv{src, {2, 1}}; + CHECK(sav_cv.bounds().index_bounds() == index<1>{2}); + CHECK(sav_cv.bounds().strides() == index<1>{1}); + CHECK(sav_cv[1] == 2); + } + } - static_assert( - std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value, - "ctor is not implicit!"); + // Check const-casting constructor + { + int arr[2] = {4, 5}; - const strided_span<int, 1> src{arr, {2, 1}}; - strided_span<const int, 1> sav{src}; - CHECK(sav.bounds().index_bounds() == index<1>{2}); - CHECK(sav.bounds().stride() == 1); - CHECK(sav[1] == 5); + const multi_span<int, 2> av(arr, 2); + multi_span<const int, 2> av2{av}; + CHECK(av2[1] == 5); - static_assert( - std::is_convertible<const strided_span<int, 1>, strided_span<const int, 1>>::value, - "ctor is not implicit!"); - } + static_assert( + std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value, + "ctor is not implicit!"); - // Check 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() == index<1>{2}); - CHECK(sav1.bounds().stride() == 1); - CHECK(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() == index<2>{3, 2})); - CHECK((sav2.bounds().strides() == index<2>{2, 1})); - CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5)); - } + const strided_span<int, 1> src{arr, {2, 1}}; + strided_span<const int, 1> sav{src}; + CHECK(sav.bounds().index_bounds() == index<1>{2}); + CHECK(sav.bounds().stride() == 1); + CHECK(sav[1] == 5); - // Check const-casting assignment operator - { - int arr1[2] = {1, 2}; - int arr2[6] = {3, 4, 5, 6, 7, 8}; + static_assert( + std::is_convertible<const strided_span<int, 1>, strided_span<const int, 1>>::value, + "ctor is not implicit!"); + } - 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() == index<1>{2}); - CHECK(sav.bounds().strides() == index<1>{1}); - CHECK(sav[0] == 1); - CHECK(&sav_ref == &sav); - } + // Check 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() == index<1>{2}); + CHECK(sav1.bounds().stride() == 1); + CHECK(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() == index<2>{3, 2})); + CHECK((sav2.bounds().strides() == index<2>{2, 1})); + CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5)); + } - // Check 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() == index<1>{2}); - CHECK(sav1.bounds().strides() == index<1>{1}); - CHECK(sav1[0] == 3); - CHECK(&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() == index<2>{3, 2})); - CHECK((sav2.bounds().strides() == index<2>{2, 1})); - CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5)); - CHECK(&sav2_ref == &sav2); - } + // Check const-casting assignment operator + { + int arr1[2] = {1, 2}; + int arr2[6] = {3, 4, 5, 6, 7, 8}; + + const strided_span<int, 1> src{arr1, {{2}, {1}}}; + strided_span<const int, 1> sav{arr2, {{3}, {2}}}; + strided_span<const int, 1>& sav_ref = (sav = src); + CHECK(sav.bounds().index_bounds() == index<1>{2}); + CHECK(sav.bounds().strides() == index<1>{1}); + CHECK(sav[0] == 1); + CHECK(&sav_ref == &sav); } - TEST(strided_span_slice) + // Check copy assignment operator { - std::vector<int> data(5 * 10); - std::iota(begin(data), end(data), 0); - const multi_span<int, 5, 10> src = - as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>()); + 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() == index<1>{2}); + CHECK(sav1.bounds().strides() == index<1>{1}); + CHECK(sav1[0] == 3); + CHECK(&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() == index<2>{3, 2})); + CHECK((sav2.bounds().strides() == index<2>{2, 1})); + CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5)); + CHECK(&sav2_ref == &sav2); + } +} + +TEST_CASE("strided_span_slice") +{ + std::vector<int> data(5 * 10); + std::iota(begin(data), end(data), 0); + const multi_span<int, 5, 10> src = + as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>()); - const strided_span<int, 2> sav{src, {{5, 10}, {10, 1}}}; + const strided_span<int, 2> sav{src, {{5, 10}, {10, 1}}}; #ifdef CONFIRM_COMPILATION_ERRORS - const strided_span<const int, 2> csav{{src}, {{5, 10}, {10, 1}}}; + const strided_span<const int, 2> csav{{src}, {{5, 10}, {10, 1}}}; #endif - const strided_span<const int, 2> csav{multi_span<const int, 5, 10>{src}, - {{5, 10}, {10, 1}}}; + const strided_span<const int, 2> csav{multi_span<const int, 5, 10>{src}, + {{5, 10}, {10, 1}}}; - strided_span<int, 1> sav_sl = sav[2]; - CHECK(sav_sl[0] == 20); - CHECK(sav_sl[9] == 29); + strided_span<int, 1> sav_sl = sav[2]; + CHECK(sav_sl[0] == 20); + CHECK(sav_sl[9] == 29); - strided_span<const int, 1> csav_sl = sav[3]; - CHECK(csav_sl[0] == 30); - CHECK(csav_sl[9] == 39); + strided_span<const int, 1> csav_sl = sav[3]; + CHECK(csav_sl[0] == 30); + CHECK(csav_sl[9] == 39); - CHECK(sav[4][0] == 40); - CHECK(sav[4][9] == 49); - } - - TEST(strided_span_column_major) - { - // strided_span may be used to accomodate more peculiar - // use cases, such as column-major multidimensional array - // (aka. "FORTRAN" layout). - - int cm_array[3 * 5] = {1, 4, 7, 10, 13, 2, 5, 8, 11, 14, 3, 6, 9, 12, 15}; - strided_span<int, 2> cm_sav{cm_array, {{5, 3}, {1, 5}}}; + CHECK(sav[4][0] == 40); + CHECK(sav[4][9] == 49); +} - // 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)); +TEST_CASE("strided_span_column_major") +{ + // strided_span may be used to accomodate more peculiar + // use cases, such as column-major multidimensional array + // (aka. "FORTRAN" layout). + + int cm_array[3 * 5] = {1, 4, 7, 10, 13, 2, 5, 8, 11, 14, 3, 6, 9, 12, 15}; + strided_span<int, 2> cm_sav{cm_array, {{5, 3}, {1, 5}}}; + + // Accessing elements + CHECK((cm_sav[{0, 0}] == 1)); + CHECK((cm_sav[{0, 1}] == 2)); + CHECK((cm_sav[{1, 0}] == 4)); + CHECK((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); + + // Section + strided_span<int, 2> cm_sec = cm_sav.section({2, 1}, {3, 2}); + + CHECK((cm_sec.bounds().index_bounds() == 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)); +} - // Slice - strided_span<int, 1> cm_sl = cm_sav[3]; +TEST_CASE("strided_span_bounds") +{ + int arr[] = {0, 1, 2, 3}; + multi_span<int> av(arr); - CHECK(cm_sl[0] == 10); - CHECK(cm_sl[1] == 11); - CHECK(cm_sl[2] == 12); + { + // incorrect sections - // Section - strided_span<int, 2> cm_sec = cm_sav.section({2, 1}, {3, 2}); + 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); - CHECK((cm_sec.bounds().index_bounds() == 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)); + 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); } - TEST(strided_span_bounds) { - int arr[] = {0, 1, 2, 3}; - multi_span<int> av(arr); - - { - // incorrect sections - - CHECK_THROW(av.section(0, 0)[0], fail_fast); - CHECK_THROW(av.section(1, 0)[0], fail_fast); - CHECK_THROW(av.section(1, 1)[1], fail_fast); - - CHECK_THROW(av.section(2, 5), fail_fast); - CHECK_THROW(av.section(5, 2), fail_fast); - CHECK_THROW(av.section(5, 0), fail_fast); - CHECK_THROW(av.section(0, 5), fail_fast); - CHECK_THROW(av.section(5, 5), fail_fast); - } - - { - // zero stride - strided_span<int, 1> sav{av, {{4}, {}}}; - CHECK(sav[0] == 0); - CHECK(sav[3] == 0); - CHECK_THROW(sav[4], fail_fast); - } + // zero stride + strided_span<int, 1> sav{av, {{4}, {}}}; + CHECK(sav[0] == 0); + CHECK(sav[3] == 0); + CHECK_THROWS_AS(sav[4], fail_fast); + } - { - // zero extent - strided_span<int, 1> sav{av, {{}, {1}}}; - CHECK_THROW(sav[0], fail_fast); - } + { + // zero extent + strided_span<int, 1> sav{av, {{}, {1}}}; + CHECK_THROWS_AS(sav[0], fail_fast); + } - { - // zero extent and stride - strided_span<int, 1> sav{av, {{}, {}}}; - CHECK_THROW(sav[0], fail_fast); - } + { + // zero extent and stride + strided_span<int, 1> sav{av, {{}, {}}}; + CHECK_THROWS_AS(sav[0], fail_fast); + } - { - // strided array ctor with matching strided bounds - strided_span<int, 1> sav{arr, {4, 1}}; - CHECK(sav.bounds().index_bounds() == index<1>{4}); - CHECK(sav[3] == 3); - CHECK_THROW(sav[4], fail_fast); - } + { + // strided array ctor with matching strided bounds + strided_span<int, 1> sav{arr, {4, 1}}; + CHECK(sav.bounds().index_bounds() == index<1>{4}); + CHECK(sav[3] == 3); + CHECK_THROWS_AS(sav[4], fail_fast); + } - { - // strided array ctor with smaller strided bounds - strided_span<int, 1> sav{arr, {2, 1}}; - CHECK(sav.bounds().index_bounds() == index<1>{2}); - CHECK(sav[1] == 1); - CHECK_THROW(sav[2], fail_fast); - } + { + // strided array ctor with smaller strided bounds + strided_span<int, 1> sav{arr, {2, 1}}; + CHECK(sav.bounds().index_bounds() == index<1>{2}); + CHECK(sav[1] == 1); + CHECK_THROWS_AS(sav[2], fail_fast); + } - { - // strided array ctor with fitting irregular bounds - strided_span<int, 1> sav{arr, {2, 3}}; - CHECK(sav.bounds().index_bounds() == index<1>{2}); - CHECK(sav[0] == 0); - CHECK(sav[1] == 3); - CHECK_THROW(sav[2], fail_fast); - } + { + // strided array ctor with fitting irregular bounds + strided_span<int, 1> sav{arr, {2, 3}}; + CHECK(sav.bounds().index_bounds() == index<1>{2}); + CHECK(sav[0] == 0); + CHECK(sav[1] == 3); + CHECK_THROWS_AS(sav[2], fail_fast); + } - { - // bounds cross data boundaries - from static arrays - CHECK_THROW((strided_span<int, 1>{arr, {3, 2}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{arr, {3, 3}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{arr, {4, 5}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{arr, {5, 1}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{arr, {5, 5}}), fail_fast); - } + { + // 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); + } - { - // bounds cross data boundaries - from array view - CHECK_THROW((strided_span<int, 1>{av, {3, 2}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{av, {3, 3}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{av, {4, 5}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{av, {5, 1}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{av, {5, 5}}), fail_fast); - } + { + // 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); + } - { - // bounds cross data boundaries - from dynamic arrays - CHECK_THROW((strided_span<int, 1>{av.data(), 4, {3, 2}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{av.data(), 4, {3, 3}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{av.data(), 4, {4, 5}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{av.data(), 4, {5, 1}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{av.data(), 4, {5, 5}}), fail_fast); - CHECK_THROW((strided_span<int, 1>{av.data(), 2, {2, 2}}), fail_fast); - } + { + // 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); + } #ifdef CONFIRM_COMPILATION_ERRORS - { - strided_span<int, 1> sav0{av.data(), {3, 2}}; - strided_span<int, 1> sav1{arr, {1}}; - strided_span<int, 1> sav2{arr, {1, 1, 1}}; - strided_span<int, 1> sav3{av, {1}}; - strided_span<int, 1> sav4{av, {1, 1, 1}}; - strided_span<int, 2> sav5{av.as_multi_span(dim<2>(), dim<2>()), {1}}; - strided_span<int, 2> sav6{av.as_multi_span(dim<2>(), dim<2>()), {1, 1, 1}}; - strided_span<int, 2> sav7{av.as_multi_span(dim<2>(), dim<2>()), - {{1, 1}, {1, 1}, {1, 1}}}; - - index<1> index{0, 1}; - strided_span<int, 1> sav8{arr, {1, {1, 1}}}; - strided_span<int, 1> sav9{arr, {{1, 1}, {1, 1}}}; - strided_span<int, 1> sav10{av, {1, {1, 1}}}; - strided_span<int, 1> sav11{av, {{1, 1}, {1, 1}}}; - strided_span<int, 2> sav12{av.as_multi_span(dim<2>(), dim<2>()), {{1}, {1}}}; - strided_span<int, 2> sav13{av.as_multi_span(dim<2>(), dim<2>()), {{1}, {1, 1, 1}}}; - strided_span<int, 2> sav14{av.as_multi_span(dim<2>(), dim<2>()), {{1, 1, 1}, {1}}}; - } -#endif + { + strided_span<int, 1> sav0{av.data(), {3, 2}}; + strided_span<int, 1> sav1{arr, {1}}; + strided_span<int, 1> sav2{arr, {1, 1, 1}}; + strided_span<int, 1> sav3{av, {1}}; + strided_span<int, 1> sav4{av, {1, 1, 1}}; + strided_span<int, 2> sav5{av.as_multi_span(dim<2>(), dim<2>()), {1}}; + strided_span<int, 2> sav6{av.as_multi_span(dim<2>(), dim<2>()), {1, 1, 1}}; + strided_span<int, 2> sav7{av.as_multi_span(dim<2>(), dim<2>()), + {{1, 1}, {1, 1}, {1, 1}}}; + + index<1> index{0, 1}; + strided_span<int, 1> sav8{arr, {1, {1, 1}}}; + strided_span<int, 1> sav9{arr, {{1, 1}, {1, 1}}}; + strided_span<int, 1> sav10{av, {1, {1, 1}}}; + strided_span<int, 1> sav11{av, {{1, 1}, {1, 1}}}; + strided_span<int, 2> sav12{av.as_multi_span(dim<2>(), dim<2>()), {{1}, {1}}}; + strided_span<int, 2> sav13{av.as_multi_span(dim<2>(), dim<2>()), {{1}, {1, 1, 1}}}; + strided_span<int, 2> sav14{av.as_multi_span(dim<2>(), dim<2>()), {{1, 1, 1}, {1}}}; } +#endif +} - TEST(strided_span_type_conversion) - { - int arr[] = {0, 1, 2, 3}; - multi_span<int> av(arr); +TEST_CASE("strided_span_type_conversion") +{ + int arr[] = {0, 1, 2, 3}; + multi_span<int> av(arr); - { - strided_span<int, 1> sav{av.data(), av.size(), {av.size() / 2, 2}}; + { + strided_span<int, 1> sav{av.data(), av.size(), {av.size() / 2, 2}}; #ifdef CONFIRM_COMPILATION_ERRORS - strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>(); + strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>(); #endif - } - { - strided_span<int, 1> sav{av, {av.size() / 2, 2}}; + } + { + strided_span<int, 1> sav{av, {av.size() / 2, 2}}; #ifdef CONFIRM_COMPILATION_ERRORS - strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>(); + strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>(); #endif - } + } - multi_span<const byte, dynamic_range> bytes = as_bytes(av); + multi_span<const byte, dynamic_range> bytes = as_bytes(av); - // retype strided array with regular strides - from raw data - { - strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}}; - strided_span<const byte, 2> sav2{bytes.data(), bytes.size(), bounds}; - strided_span<const int, 2> sav3 = sav2.as_strided_span<const int>(); - CHECK(sav3[0][0] == 0); - CHECK(sav3[1][0] == 2); - CHECK_THROW(sav3[1][1], fail_fast); - CHECK_THROW(sav3[0][1], fail_fast); - } + // retype strided array with regular strides - from raw data + { + strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}}; + strided_span<const byte, 2> sav2{bytes.data(), bytes.size(), bounds}; + strided_span<const int, 2> sav3 = sav2.as_strided_span<const int>(); + 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); + } - // retype strided array with regular strides - from multi_span - { - strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}}; - multi_span<const byte, 2, dynamic_range> bytes2 = - as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); - strided_span<const byte, 2> sav2{bytes2, bounds}; - strided_span<int, 2> sav3 = sav2.as_strided_span<int>(); - CHECK(sav3[0][0] == 0); - CHECK(sav3[1][0] == 2); - CHECK_THROW(sav3[1][1], fail_fast); - CHECK_THROW(sav3[0][1], fail_fast); - } + // retype strided array with regular strides - from multi_span + { + strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}}; + multi_span<const byte, 2, dynamic_range> bytes2 = + as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); + strided_span<const byte, 2> sav2{bytes2, bounds}; + strided_span<int, 2> sav3 = sav2.as_strided_span<int>(); + 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); + } - // retype strided array with not enough elements - last dimension of the array is too small - { - strided_bounds<2> bounds{{4, 2}, {4, 1}}; - multi_span<const byte, 2, dynamic_range> bytes2 = - as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); - strided_span<const byte, 2> sav2{bytes2, bounds}; - CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); - } + // retype strided array with not enough elements - last dimension of the array is too small + { + strided_bounds<2> bounds{{4, 2}, {4, 1}}; + multi_span<const byte, 2, dynamic_range> bytes2 = + as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); + strided_span<const byte, 2> sav2{bytes2, bounds}; + CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast); + } - // retype strided array with not enough elements - strides are too small - { - strided_bounds<2> bounds{{4, 2}, {2, 1}}; - multi_span<const byte, 2, dynamic_range> bytes2 = - as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); - strided_span<const byte, 2> sav2{bytes2, bounds}; - CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); - } + // retype strided array with not enough elements - strides are too small + { + strided_bounds<2> bounds{{4, 2}, {2, 1}}; + multi_span<const byte, 2, dynamic_range> bytes2 = + as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); + strided_span<const byte, 2> sav2{bytes2, bounds}; + CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast); + } - // retype strided array with not enough elements - last dimension does not divide by the new - // typesize - { - strided_bounds<2> bounds{{2, 6}, {4, 1}}; - multi_span<const byte, 2, dynamic_range> bytes2 = - as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); - strided_span<const byte, 2> sav2{bytes2, bounds}; - CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); - } + // retype strided array with not enough elements - last dimension does not divide by the new + // typesize + { + strided_bounds<2> bounds{{2, 6}, {4, 1}}; + multi_span<const byte, 2, dynamic_range> bytes2 = + as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); + strided_span<const byte, 2> sav2{bytes2, bounds}; + CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast); + } - // retype strided array with not enough elements - strides does not divide by the new - // typesize - { - strided_bounds<2> bounds{{2, 1}, {6, 1}}; - multi_span<const byte, 2, dynamic_range> bytes2 = - as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); - strided_span<const byte, 2> sav2{bytes2, bounds}; - CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); - } + // retype strided array with not enough elements - strides does not divide by the new + // typesize + { + strided_bounds<2> bounds{{2, 1}, {6, 1}}; + multi_span<const byte, 2, dynamic_range> bytes2 = + as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); + strided_span<const byte, 2> sav2{bytes2, bounds}; + CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast); + } - // 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_THROW(sav2.as_strided_span<int>(), fail_fast); - } + // 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); + } - // 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_THROW(sav2.as_strided_span<int>(), fail_fast); - } + // 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); } +} - TEST(empty_strided_spans) +TEST_CASE("empty_strided_spans") +{ { - { - multi_span<int, 0> empty_av(nullptr); - strided_span<int, 1> empty_sav{empty_av, {0, 1}}; + multi_span<int, 0> empty_av(nullptr); + strided_span<int, 1> empty_sav{empty_av, {0, 1}}; - CHECK(empty_sav.bounds().index_bounds() == index<1>{0}); - CHECK_THROW(empty_sav[0], fail_fast); - CHECK_THROW(empty_sav.begin()[0], fail_fast); - CHECK_THROW(empty_sav.cbegin()[0], fail_fast); + CHECK(empty_sav.bounds().index_bounds() == 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); - for (const auto& v : empty_sav) { - (void) v; - CHECK(false); - } + for (const auto& v : empty_sav) { + (void) v; + CHECK(false); } + } - { - strided_span<int, 1> empty_sav{nullptr, 0, {0, 1}}; + { + strided_span<int, 1> empty_sav{nullptr, 0, {0, 1}}; - CHECK(empty_sav.bounds().index_bounds() == index<1>{0}); - CHECK_THROW(empty_sav[0], fail_fast); - CHECK_THROW(empty_sav.begin()[0], fail_fast); - CHECK_THROW(empty_sav.cbegin()[0], fail_fast); + CHECK(empty_sav.bounds().index_bounds() == 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); - for (const auto& v : empty_sav) { - (void) v; - CHECK(false); - } + for (const auto& v : empty_sav) { + (void) v; + CHECK(false); } } +} - void iterate_every_other_element(multi_span<int, dynamic_range> av) - { - // pick every other element +void iterate_every_other_element(multi_span<int, dynamic_range> av) +{ + // pick every other element - auto length = av.size() / 2; + auto length = av.size() / 2; #if _MSC_VER > 1800 - auto bounds = strided_bounds<1>({length}, {2}); + auto bounds = strided_bounds<1>({length}, {2}); #else - auto bounds = strided_bounds<1>(index<1>{length}, index<1>{2}); + auto bounds = strided_bounds<1>(index<1>{length}, index<1>{2}); #endif - strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds); + 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++; - } + 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]); } - TEST(strided_span_section_iteration) - { - int arr[8] = {4, 0, 5, 1, 6, 2, 7, 3}; + int idx = 0; + for (auto num : strided) { + CHECK(num == av[2 * idx + 1]); + idx++; + } +} - // static bounds - { - multi_span<int, 8> av(arr, 8); - iterate_every_other_element(av); - } +TEST_CASE("strided_span_section_iteration") +{ + int arr[8] = {4, 0, 5, 1, 6, 2, 7, 3}; - // dynamic bounds - { - multi_span<int, dynamic_range> av(arr, 8); - iterate_every_other_element(av); - } + // static bounds + { + multi_span<int, 8> av(arr, 8); + iterate_every_other_element(av); } - TEST(dynamic_strided_span_section_iteration) + // dynamic bounds { - auto arr = new int[8]; - for (int i = 0; i < 4; ++i) { - arr[2 * i] = 4 + i; - arr[2 * i + 1] = i; - } - - auto av = as_multi_span(arr, 8); + multi_span<int, dynamic_range> av(arr, 8); iterate_every_other_element(av); + } +} - delete[] arr; +TEST_CASE("dynamic_strided_span_section_iteration") +{ + auto arr = new int[8]; + for (int i = 0; i < 4; ++i) { + arr[2 * i] = 4 + i; + arr[2 * i + 1] = i; } - 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}); + auto av = as_multi_span(arr, 8); + iterate_every_other_element(av); - 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 = index<3>{i, j, k}; // avoid braces in the CHECK macro - CHECK(section[idx] == expected[2 * i + 2 * j + k]); - } - } + delete[] arr; +} - 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]); - } +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 = index<3>{i, j, k}; // avoid braces in the CHECK macro + CHECK(section[idx] == expected[2 * i + 2 * j + k]); + } + } - int i = 0; - for (const auto num : section) { - CHECK(num == expected[i]); - i++; - } + 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]); } - TEST(strided_span_section_iteration_3d) - { - int arr[3][4][2]{}; - for (auto i = 0; i < 3; ++i) { - for (auto j = 0; j < 4; ++j) - for (auto k = 0; k < 2; ++k) arr[i][j][k] = 8 * i + 2 * j + k; - } + int i = 0; + for (const auto num : section) { + CHECK(num == expected[i]); + i++; + } +} - { - multi_span<int, 3, 4, 2> av = arr; - iterate_second_slice(av); - } +TEST_CASE("strided_span_section_iteration_3d") +{ + int arr[3][4][2]{}; + for (auto i = 0; i < 3; ++i) { + for (auto j = 0; j < 4; ++j) + for (auto k = 0; k < 2; ++k) arr[i][j][k] = 8 * i + 2 * j + k; } - TEST(dynamic_strided_span_section_iteration_3d) { - const auto height = 12, width = 2; - const auto size = height * width; + multi_span<int, 3, 4, 2> av = arr; + iterate_second_slice(av); + } +} - auto arr = new int[static_cast<std::size_t>(size)]; - for (auto i = 0; i < size; ++i) { - arr[i] = i; - } +TEST_CASE("dynamic_strided_span_section_iteration_3d") +{ + const auto height = 12, width = 2; + const auto size = height * width; - { - auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim<2>()); - iterate_second_slice(av); - } + auto arr = new int[static_cast<std::size_t>(size)]; + for (auto i = 0; i < size; ++i) { + arr[i] = i; + } - { - auto av = as_multi_span(as_multi_span(arr, 24), dim(3), dim<4>(), dim<2>()); - iterate_second_slice(av); - } + { + auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim<2>()); + iterate_second_slice(av); + } - { - auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim(4), dim<2>()); - iterate_second_slice(av); - } + { + auto av = as_multi_span(as_multi_span(arr, 24), dim(3), dim<4>(), dim<2>()); + iterate_second_slice(av); + } - { - auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim(2)); - iterate_second_slice(av); - } - delete[] arr; + { + auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim(4), dim<2>()); + iterate_second_slice(av); } - TEST(strided_span_conversion) { - // get an multi_span of 'c' values from the list of X's + auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim(2)); + iterate_second_slice(av); + } + delete[] arr; +} - struct X - { - int a; - int b; - int c; - }; +TEST_CASE("strided_span_conversion") +{ + // get an multi_span of 'c' values from the list of X's + + struct X + { + int a; + int b; + int c; + }; - X arr[4] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}; + X arr[4] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}; - int s = sizeof(int) / sizeof(byte); - auto d2 = 3 * s; - auto d1 = narrow_cast<int>(sizeof(int)) * 12 / d2; + int s = sizeof(int) / sizeof(byte); + auto d2 = 3 * s; + auto d1 = narrow_cast<int>(sizeof(int)) * 12 / d2; - // convert to 4x12 array of bytes - auto av = as_multi_span(as_bytes(as_multi_span(arr, 4)), dim(d1), dim(d2)); + // convert to 4x12 array of bytes + auto av = as_multi_span(as_bytes(as_multi_span(arr, 4)), dim(d1), dim(d2)); - CHECK(av.bounds().index_bounds()[0] == 4); - CHECK(av.bounds().index_bounds()[1] == 12); + CHECK(av.bounds().index_bounds()[0] == 4); + CHECK(av.bounds().index_bounds()[1] == 12); - // get the last 4 columns - auto section = av.section({0, 2 * s}, {4, s}); // { { arr[0].c[0], arr[0].c[1], arr[0].c[2], - // arr[0].c[3] } , { arr[1].c[0], ... } , ... - // } + // get the last 4 columns + auto section = av.section({0, 2 * s}, {4, s}); // { { arr[0].c[0], arr[0].c[1], arr[0].c[2], + // arr[0].c[3] } , { arr[1].c[0], ... } , ... + // } - // convert to array 4x1 array of integers - auto cs = section.as_strided_span<int>(); // { { arr[0].c }, {arr[1].c } , ... } + // 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); + CHECK(cs.bounds().index_bounds()[0] == 4); + CHECK(cs.bounds().index_bounds()[1] == 1); - // transpose to 1x4 array - strided_bounds<2> reverse_bounds{ - {cs.bounds().index_bounds()[1], cs.bounds().index_bounds()[0]}, - {cs.bounds().strides()[1], cs.bounds().strides()[0]}}; + // transpose to 1x4 array + strided_bounds<2> reverse_bounds{ + {cs.bounds().index_bounds()[1], cs.bounds().index_bounds()[0]}, + {cs.bounds().strides()[1], cs.bounds().strides()[0]}}; - strided_span<int, 2> transposed{cs.data(), cs.bounds().total_size(), reverse_bounds}; + strided_span<int, 2> transposed{cs.data(), cs.bounds().total_size(), reverse_bounds}; - // slice to get a one-dimensional array of c's - strided_span<int, 1> result = transposed[0]; + // 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_THROW(result.bounds().index_bounds()[1], fail_fast); + CHECK(result.bounds().index_bounds()[0] == 4); + CHECK_THROWS_AS(result.bounds().index_bounds()[1], fail_fast); - int i = 0; - for (auto& num : result) { - CHECK(num == arr[i].c); - i++; - } + int i = 0; + for (auto& num : result) { + CHECK(num == arr[i].c); + i++; } } - -int main(int, const char* []) { return UnitTest::RunAllTests(); } diff --git a/tests/string_span_tests.cpp b/tests/string_span_tests.cpp index efaf0d2..229a117 100644 --- a/tests/string_span_tests.cpp +++ b/tests/string_span_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/gsl> //owner #include <gsl/string_span> @@ -26,944 +26,938 @@ using namespace std; using namespace gsl; -SUITE(string_span_tests) +TEST_CASE("TestLiteralConstruction") { - - TEST(TestLiteralConstruction) - { - cwstring_span<> v = ensure_z(L"Hello"); - CHECK(5 == v.length()); + cwstring_span<> v = ensure_z(L"Hello"); + CHECK(5 == v.length()); #ifdef CONFIRM_COMPILATION_ERRORS - wstring_span<> v2 = ensure0(L"Hello"); + wstring_span<> v2 = ensure0(L"Hello"); #endif - } +} - TEST(TestConstructFromStdString) - { - std::string s = "Hello there world"; - cstring_span<> v = s; - CHECK(v.length() == static_cast<cstring_span<>::index_type>(s.length())); - } +TEST_CASE("TestConstructFromStdString") +{ + std::string s = "Hello there world"; + cstring_span<> v = s; + CHECK(v.length() == static_cast<cstring_span<>::index_type>(s.length())); +} + +TEST_CASE("TestConstructFromStdVector") +{ + std::vector<char> vec(5, 'h'); + string_span<> v{vec}; + CHECK(v.length() == static_cast<string_span<>::index_type>(vec.size())); +} + +TEST_CASE("TestStackArrayConstruction") +{ + wchar_t stack_string[] = L"Hello"; - TEST(TestConstructFromStdVector) { - std::vector<char> vec(5, 'h'); - string_span<> v{vec}; - CHECK(v.length() == static_cast<string_span<>::index_type>(vec.size())); + cwstring_span<> v = ensure_z(stack_string); + CHECK(v.length() == 5); } - TEST(TestStackArrayConstruction) { - wchar_t stack_string[] = L"Hello"; - - { - cwstring_span<> v = ensure_z(stack_string); - CHECK(v.length() == 5); - } - - { - cwstring_span<> v = stack_string; - CHECK(v.length() == 5); - } - - { - wstring_span<> v = ensure_z(stack_string); - CHECK(v.length() == 5); - } - - { - wstring_span<> v = stack_string; - CHECK(v.length() == 5); - } + cwstring_span<> v = stack_string; + CHECK(v.length() == 5); } - TEST(TestConstructFromConstCharPointer) { - const char* s = "Hello"; - cstring_span<> v = ensure_z(s); + wstring_span<> v = ensure_z(stack_string); CHECK(v.length() == 5); } - TEST(TestConversionToConst) { - char stack_string[] = "Hello"; - string_span<> v = ensure_z(stack_string); - cstring_span<> v2 = v; - CHECK(v.length() == v2.length()); + wstring_span<> v = stack_string; + CHECK(v.length() == 5); } +} - TEST(TestConversionFromConst) - { - char stack_string[] = "Hello"; - cstring_span<> v = ensure_z(stack_string); - (void) v; +TEST_CASE("TestConstructFromConstCharPointer") +{ + const char* s = "Hello"; + cstring_span<> v = ensure_z(s); + CHECK(v.length() == 5); +} + +TEST_CASE("TestConversionToConst") +{ + char stack_string[] = "Hello"; + string_span<> v = ensure_z(stack_string); + cstring_span<> v2 = v; + CHECK(v.length() == v2.length()); +} + +TEST_CASE("TestConversionFromConst") +{ + char stack_string[] = "Hello"; + cstring_span<> v = ensure_z(stack_string); + (void) v; #ifdef CONFIRM_COMPILATION_ERRORS - string_span<> v2 = v; - string_span<> v3 = "Hello"; + string_span<> v2 = v; + string_span<> v3 = "Hello"; #endif - } +} - TEST(TestToString) - { - auto s = gsl::to_string(cstring_span<>{}); - CHECK(s.length() == 0); +TEST_CASE("TestToString") +{ + auto s = gsl::to_string(cstring_span<>{}); + CHECK(s.length() == 0); + + char stack_string[] = "Hello"; + cstring_span<> v = ensure_z(stack_string); + auto s2 = gsl::to_string(v); + CHECK(static_cast<cstring_span<>::index_type>(s2.length()) == v.length()); + CHECK(s2.length() == 5); +} - char stack_string[] = "Hello"; - cstring_span<> v = ensure_z(stack_string); - auto s2 = gsl::to_string(v); - CHECK(static_cast<cstring_span<>::index_type>(s2.length()) == v.length()); - CHECK(s2.length() == 5); - } +TEST_CASE("TestToBasicString") +{ + auto s = gsl::to_basic_string<char, std::char_traits<char>, ::std::allocator<char>>( + cstring_span<>{}); + CHECK(s.length() == 0); + + char stack_string[] = "Hello"; + cstring_span<> v = ensure_z(stack_string); + auto s2 = gsl::to_basic_string<char, std::char_traits<char>, ::std::allocator<char>>(v); + CHECK(static_cast<cstring_span<>::index_type>(s2.length()) == v.length()); + CHECK(s2.length() == 5); +} - TEST(TestToBasicString) +TEST_CASE("EqualityAndImplicitConstructors") +{ { - auto s = gsl::to_basic_string<char, std::char_traits<char>, ::std::allocator<char>>( - cstring_span<>{}); - CHECK(s.length() == 0); + cstring_span<> span = "Hello"; + cstring_span<> span1; - char stack_string[] = "Hello"; - cstring_span<> v = ensure_z(stack_string); - auto s2 = gsl::to_basic_string<char, std::char_traits<char>, ::std::allocator<char>>(v); - CHECK(static_cast<cstring_span<>::index_type>(s2.length()) == v.length()); - CHECK(s2.length() == 5); + // comparison to empty span + CHECK(span1 != span); + CHECK(span != span1); } - TEST(EqualityAndImplicitConstructors) { - { - cstring_span<> span = "Hello"; - cstring_span<> span1; - - // comparison to empty span - CHECK(span1 != span); - CHECK(span != span1); - } - - { - cstring_span<> span = "Hello"; - cstring_span<> span1 = "Hello1"; + cstring_span<> span = "Hello"; + cstring_span<> span1 = "Hello1"; - // comparison to different span - CHECK(span1 != span); - CHECK(span != span1); - } + // comparison to different span + CHECK(span1 != span); + CHECK(span != span1); + } - { - cstring_span<> span = "Hello"; + { + cstring_span<> span = "Hello"; - const char ar[] = {'H', 'e', 'l', 'l', 'o'}; - const char ar1[] = "Hello"; - const char ar2[10] = "Hello"; - const char* ptr = "Hello"; - const std::string str = "Hello"; - const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - gsl::span<const char> sp = ensure_z("Hello"); + const char ar[] = {'H', 'e', 'l', 'l', 'o'}; + const char ar1[] = "Hello"; + const char ar2[10] = "Hello"; + const char* ptr = "Hello"; + const std::string str = "Hello"; + const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + gsl::span<const char> sp = ensure_z("Hello"); - // comparison to literal - CHECK(span == cstring_span<>("Hello")); + // comparison to literal + CHECK(span == cstring_span<>("Hello")); - // comparison to static array with no null termination - CHECK(span == cstring_span<>(ar)); + // comparison to static array with no null termination + CHECK(span == cstring_span<>(ar)); - // comparison to static array with null at the end - CHECK(span == cstring_span<>(ar1)); + // comparison to static array with null at the end + CHECK(span == cstring_span<>(ar1)); - // comparison to static array with null in the middle - CHECK(span == cstring_span<>(ar2)); + // comparison to static array with null in the middle + CHECK(span == cstring_span<>(ar2)); - // comparison to null-terminated c string - CHECK(span == cstring_span<>(ptr, 5)); + // comparison to null-terminated c string + CHECK(span == cstring_span<>(ptr, 5)); - // comparison to string - CHECK(span == cstring_span<>(str)); + // comparison to string + CHECK(span == cstring_span<>(str)); - // comparison to vector of charaters with no null termination - CHECK(span == cstring_span<>(vec)); + // comparison to vector of charaters with no null termination + CHECK(span == cstring_span<>(vec)); - // comparison to span - CHECK(span == cstring_span<>(sp)); + // comparison to span + CHECK(span == cstring_span<>(sp)); - // comparison to string_span - CHECK(span == span); - } + // comparison to string_span + CHECK(span == span); + } - { - char ar[] = {'H', 'e', 'l', 'l', 'o'}; + { + char ar[] = {'H', 'e', 'l', 'l', 'o'}; - string_span<> span = ar; + string_span<> span = ar; - char ar1[] = "Hello"; - char ar2[10] = "Hello"; - char* ptr = ar; - std::string str = "Hello"; - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - gsl::span<char> sp = ensure_z(ar1); + char ar1[] = "Hello"; + char ar2[10] = "Hello"; + char* ptr = ar; + std::string str = "Hello"; + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + gsl::span<char> sp = ensure_z(ar1); - // comparison to static array with no null termination - CHECK(span == string_span<>(ar)); + // comparison to static array with no null termination + CHECK(span == string_span<>(ar)); - // comparison to static array with null at the end - CHECK(span == string_span<>(ar1)); + // comparison to static array with null at the end + CHECK(span == string_span<>(ar1)); - // comparison to static array with null in the middle - CHECK(span == string_span<>(ar2)); + // comparison to static array with null in the middle + CHECK(span == string_span<>(ar2)); - // comparison to null-terminated c string - CHECK(span == string_span<>(ptr, 5)); + // comparison to null-terminated c string + CHECK(span == string_span<>(ptr, 5)); - // comparison to string - CHECK(span == string_span<>(str)); + // comparison to string + CHECK(span == string_span<>(str)); - // comparison to vector of charaters with no null termination - CHECK(span == string_span<>(vec)); + // comparison to vector of charaters with no null termination + CHECK(span == string_span<>(vec)); - // comparison to span - CHECK(span == string_span<>(sp)); + // comparison to span + CHECK(span == string_span<>(sp)); - // comparison to string_span - CHECK(span == span); - } + // comparison to string_span + CHECK(span == span); + } - { - const char ar[] = {'H', 'e', 'l', 'l', 'o'}; - const char ar1[] = "Hello"; - const char ar2[10] = "Hello"; - const std::string str = "Hello"; - const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - const gsl::span<const char> sp = ensure_z("Hello"); + { + const char ar[] = {'H', 'e', 'l', 'l', 'o'}; + const char ar1[] = "Hello"; + const char ar2[10] = "Hello"; + const std::string str = "Hello"; + const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const gsl::span<const char> sp = ensure_z("Hello"); - cstring_span<> span = "Hello"; + cstring_span<> span = "Hello"; - // const span, const other type + // const span, const other type - CHECK(span == "Hello"); - CHECK(span == ar); - CHECK(span == ar1); - CHECK(span == ar2); + CHECK(span == "Hello"); + CHECK(span == ar); + CHECK(span == ar1); + CHECK(span == ar2); #ifdef CONFIRM_COMPILATION_ERRORS - const char* ptr = "Hello"; - CHECK(span == ptr); + const char* ptr = "Hello"; + CHECK(span == ptr); #endif - CHECK(span == str); - CHECK(span == vec); - CHECK(span == sp); - - CHECK("Hello" == span); - CHECK(ar == span); - CHECK(ar1 == span); - CHECK(ar2 == span); + CHECK(span == str); + CHECK(span == vec); + CHECK(span == sp); + + CHECK("Hello" == span); + CHECK(ar == span); + CHECK(ar1 == span); + CHECK(ar2 == span); #ifdef CONFIRM_COMPILATION_ERRORS - CHECK(ptr == span); + CHECK(ptr == span); #endif - CHECK(str == span); - CHECK(vec == span); - CHECK(sp == span); - - // const span, non-const other type - - char _ar[] = {'H', 'e', 'l', 'l', 'o'}; - char _ar1[] = "Hello"; - char _ar2[10] = "Hello"; - char* _ptr = _ar; - std::string _str = "Hello"; - std::vector<char> _vec = {'H', 'e', 'l', 'l', 'o'}; - gsl::span<char> _sp{_ar, 5}; - - CHECK(span == _ar); - CHECK(span == _ar1); - CHECK(span == _ar2); + CHECK(str == span); + CHECK(vec == span); + CHECK(sp == span); + + // const span, non-const other type + + char _ar[] = {'H', 'e', 'l', 'l', 'o'}; + char _ar1[] = "Hello"; + char _ar2[10] = "Hello"; + char* _ptr = _ar; + std::string _str = "Hello"; + std::vector<char> _vec = {'H', 'e', 'l', 'l', 'o'}; + gsl::span<char> _sp{_ar, 5}; + + CHECK(span == _ar); + CHECK(span == _ar1); + CHECK(span == _ar2); #ifdef CONFIRM_COMPILATION_ERRORS - CHECK(span == _ptr); + CHECK(span == _ptr); #endif - CHECK(span == _str); - CHECK(span == _vec); - CHECK(span == _sp); + CHECK(span == _str); + CHECK(span == _vec); + CHECK(span == _sp); - CHECK(_ar == span); - CHECK(_ar1 == span); - CHECK(_ar2 == span); + CHECK(_ar == span); + CHECK(_ar1 == span); + CHECK(_ar2 == span); #ifdef CONFIRM_COMPILATION_ERRORS - CHECK(_ptr == span); + CHECK(_ptr == span); #endif - CHECK(_str == span); - CHECK(_vec == span); - CHECK(_sp == span); + CHECK(_str == span); + CHECK(_vec == span); + CHECK(_sp == span); - string_span<> _span{_ptr, 5}; + string_span<> _span{_ptr, 5}; - // non-const span, non-const other type + // non-const span, non-const other type - CHECK(_span == _ar); - CHECK(_span == _ar1); - CHECK(_span == _ar2); + CHECK(_span == _ar); + CHECK(_span == _ar1); + CHECK(_span == _ar2); #ifdef CONFIRM_COMPILATION_ERRORS - CHECK(_span == _ptr); + CHECK(_span == _ptr); #endif - CHECK(_span == _str); - CHECK(_span == _vec); - CHECK(_span == _sp); + CHECK(_span == _str); + CHECK(_span == _vec); + CHECK(_span == _sp); - CHECK(_ar == _span); - CHECK(_ar1 == _span); - CHECK(_ar2 == _span); + CHECK(_ar == _span); + CHECK(_ar1 == _span); + CHECK(_ar2 == _span); #ifdef CONFIRM_COMPILATION_ERRORS - CHECK(_ptr == _span); + CHECK(_ptr == _span); #endif - CHECK(_str == _span); - CHECK(_vec == _span); - CHECK(_sp == _span); + CHECK(_str == _span); + CHECK(_vec == _span); + CHECK(_sp == _span); - // non-const span, const other type + // non-const span, const other type - CHECK(_span == "Hello"); - CHECK(_span == ar); - CHECK(_span == ar1); - CHECK(_span == ar2); + CHECK(_span == "Hello"); + CHECK(_span == ar); + CHECK(_span == ar1); + CHECK(_span == ar2); #ifdef CONFIRM_COMPILATION_ERRORS - CHECK(_span == ptr); + CHECK(_span == ptr); #endif - CHECK(_span == str); - CHECK(_span == vec); - CHECK(_span == sp); - - CHECK("Hello" == _span); - CHECK(ar == _span); - CHECK(ar1 == _span); - CHECK(ar2 == _span); + CHECK(_span == str); + CHECK(_span == vec); + CHECK(_span == sp); + + CHECK("Hello" == _span); + CHECK(ar == _span); + CHECK(ar1 == _span); + CHECK(ar2 == _span); #ifdef CONFIRM_COMPILATION_ERRORS - CHECK(ptr == _span); + CHECK(ptr == _span); #endif - CHECK(str == _span); - CHECK(vec == _span); - CHECK(sp == _span); + CHECK(str == _span); + CHECK(vec == _span); + CHECK(sp == _span); - // two spans + // two spans - CHECK(_span == span); - CHECK(span == _span); - } + CHECK(_span == span); + CHECK(span == _span); + } - { - std::vector<char> str1 = {'H', 'e', 'l', 'l', 'o'}; - cstring_span<> span1 = str1; - std::vector<char> str2 = std::move(str1); - cstring_span<> span2 = str2; + { + std::vector<char> str1 = {'H', 'e', 'l', 'l', 'o'}; + cstring_span<> span1 = str1; + std::vector<char> str2 = std::move(str1); + cstring_span<> span2 = str2; - // comparison of spans from the same vector before and after move (ok) - CHECK(span1 == span2); - } + // comparison of spans from the same vector before and after move (ok) + CHECK(span1 == span2); } +} - TEST(ComparisonAndImplicitConstructors) +TEST_CASE("ComparisonAndImplicitConstructors") +{ { - { - cstring_span<> span = "Hello"; + cstring_span<> span = "Hello"; - const char ar[] = {'H', 'e', 'l', 'l', 'o'}; - const char ar1[] = "Hello"; - const char ar2[10] = "Hello"; - const char* ptr = "Hello"; - const std::string str = "Hello"; - const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const char ar[] = {'H', 'e', 'l', 'l', 'o'}; + const char ar1[] = "Hello"; + const char ar2[10] = "Hello"; + const char* ptr = "Hello"; + const std::string str = "Hello"; + const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - // comparison to literal - CHECK(span < cstring_span<>("Helloo")); - CHECK(span > cstring_span<>("Hell")); + // comparison to literal + CHECK(span < cstring_span<>("Helloo")); + CHECK(span > cstring_span<>("Hell")); - // comparison to static array with no null termination - CHECK(span >= cstring_span<>(ar)); + // comparison to static array with no null termination + CHECK(span >= cstring_span<>(ar)); - // comparison to static array with null at the end - CHECK(span <= cstring_span<>(ar1)); + // comparison to static array with null at the end + CHECK(span <= cstring_span<>(ar1)); - // comparison to static array with null in the middle - CHECK(span >= cstring_span<>(ar2)); + // comparison to static array with null in the middle + CHECK(span >= cstring_span<>(ar2)); - // comparison to null-terminated c string - CHECK(span <= cstring_span<>(ptr, 5)); + // comparison to null-terminated c string + CHECK(span <= cstring_span<>(ptr, 5)); - // comparison to string - CHECK(span >= cstring_span<>(str)); + // comparison to string + CHECK(span >= cstring_span<>(str)); - // comparison to vector of charaters with no null termination - CHECK(span <= cstring_span<>(vec)); - } + // comparison to vector of charaters with no null termination + CHECK(span <= cstring_span<>(vec)); + } - { - char ar[] = {'H', 'e', 'l', 'l', 'o'}; + { + char ar[] = {'H', 'e', 'l', 'l', 'o'}; - string_span<> span = ar; + string_span<> span = ar; - char larr[] = "Hell"; - char rarr[] = "Helloo"; + char larr[] = "Hell"; + char rarr[] = "Helloo"; - char ar1[] = "Hello"; - char ar2[10] = "Hello"; - char* ptr = ar; - std::string str = "Hello"; - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + char ar1[] = "Hello"; + char ar2[10] = "Hello"; + char* ptr = ar; + std::string str = "Hello"; + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - // comparison to static array with no null termination - CHECK(span <= string_span<>(ar)); - CHECK(span < string_span<>(rarr)); - CHECK(span > string_span<>(larr)); + // comparison to static array with no null termination + CHECK(span <= string_span<>(ar)); + CHECK(span < string_span<>(rarr)); + CHECK(span > string_span<>(larr)); - // comparison to static array with null at the end - CHECK(span >= string_span<>(ar1)); + // comparison to static array with null at the end + CHECK(span >= string_span<>(ar1)); - // comparison to static array with null in the middle - CHECK(span <= string_span<>(ar2)); + // comparison to static array with null in the middle + CHECK(span <= string_span<>(ar2)); - // comparison to null-terminated c string - CHECK(span >= string_span<>(ptr, 5)); + // comparison to null-terminated c string + CHECK(span >= string_span<>(ptr, 5)); - // comparison to string - CHECK(span <= string_span<>(str)); + // comparison to string + CHECK(span <= string_span<>(str)); - // comparison to vector of charaters with no null termination - CHECK(span >= string_span<>(vec)); - } + // comparison to vector of charaters with no null termination + CHECK(span >= string_span<>(vec)); } - TEST(ConstrutorsEnsureZ) +} +TEST_CASE("ConstrutorsEnsureZ") +{ + // remove z from literals { - // remove z from literals - { - cstring_span<> sp = "hello"; - CHECK((sp.length() == 5)); - } + cstring_span<> sp = "hello"; + CHECK((sp.length() == 5)); + } - // take the string as is - { - auto str = std::string("hello"); - cstring_span<> sp = str; - CHECK((sp.length() == 5)); - } + // take the string as is + { + auto str = std::string("hello"); + cstring_span<> sp = str; + CHECK((sp.length() == 5)); + } - // ensure z on c strings - { - gsl::owner<char*> ptr = new char[3]; + // ensure z on c strings + { + gsl::owner<char*> ptr = new char[3]; - ptr[0] = 'a'; - ptr[1] = 'b'; - ptr[2] = '\0'; + ptr[0] = 'a'; + ptr[1] = 'b'; + ptr[2] = '\0'; - string_span<> span = ensure_z(ptr); - CHECK(span.length() == 2); + string_span<> span = ensure_z(ptr); + CHECK(span.length() == 2); - delete[] ptr; - } + delete[] ptr; } +} - TEST(Constructors) - { - // creating cstring_span +TEST_CASE("Constructors") +{ + // creating cstring_span - // from span of a final extent - { - span<const char, 6> sp = "Hello"; - cstring_span<> span = sp; - CHECK(span.length() == 6); - } + // from span of a final extent + { + span<const char, 6> sp = "Hello"; + cstring_span<> span = sp; + CHECK(span.length() == 6); + } // from const span of a final extent to non-const string_span #ifdef CONFIRM_COMPILATION_ERRORS - { - span<const char, 6> sp = "Hello"; - string_span<> span = sp; - CHECK(span.length() == 6); - } + { + span<const char, 6> sp = "Hello"; + string_span<> span = sp; + CHECK(span.length() == 6); + } #endif // from string temporary #ifdef CONFIRM_COMPILATION_ERRORS - { - cstring_span<> span = std::string("Hello"); - } + { + cstring_span<> span = std::string("Hello"); + } #endif - // default - { - cstring_span<> span; - CHECK(span.length() == 0); - } + // default + { + cstring_span<> span; + CHECK(span.length() == 0); + } - // from nullptr - { - cstring_span<> span(nullptr); - CHECK(span.length() == 0); - } + // from nullptr + { + cstring_span<> span(nullptr); + CHECK(span.length() == 0); + } - // from string literal - { - cstring_span<> span = "Hello"; - CHECK(span.length() == 5); - } + // from string literal + { + cstring_span<> span = "Hello"; + CHECK(span.length() == 5); + } - // from const static array - { - const char ar[] = {'H', 'e', 'l', 'l', 'o'}; - cstring_span<> span = ar; - CHECK(span.length() == 5); - } + // from const static array + { + const char ar[] = {'H', 'e', 'l', 'l', 'o'}; + cstring_span<> span = ar; + CHECK(span.length() == 5); + } - // from non-const static array - { - char ar[] = {'H', 'e', 'l', 'l', 'o'}; - cstring_span<> span = ar; - CHECK(span.length() == 5); - } + // from non-const static array + { + char ar[] = {'H', 'e', 'l', 'l', 'o'}; + cstring_span<> span = ar; + CHECK(span.length() == 5); + } - // from const ptr and length - { - const char* ptr = "Hello"; - cstring_span<> span{ptr, 5}; - CHECK(span.length() == 5); - } + // from const ptr and length + { + const char* ptr = "Hello"; + cstring_span<> span{ptr, 5}; + CHECK(span.length() == 5); + } - // from const ptr and length, include 0 - { - const char* ptr = "Hello"; - cstring_span<> span{ptr, 6}; - CHECK(span.length() == 6); - } + // from const ptr and length, include 0 + { + const char* ptr = "Hello"; + cstring_span<> span{ptr, 6}; + CHECK(span.length() == 6); + } - // from const ptr and length, 0 inside - { - const char* ptr = "He\0lo"; - cstring_span<> span{ptr, 5}; - CHECK(span.length() == 5); - } + // from const ptr and length, 0 inside + { + const char* ptr = "He\0lo"; + cstring_span<> span{ptr, 5}; + CHECK(span.length() == 5); + } - // from non-const ptr and length - { - char ar[] = {'H', 'e', 'l', 'l', 'o'}; - char* ptr = ar; - cstring_span<> span{ptr, 5}; - CHECK(span.length() == 5); - } + // from non-const ptr and length + { + char ar[] = {'H', 'e', 'l', 'l', 'o'}; + char* ptr = ar; + cstring_span<> span{ptr, 5}; + CHECK(span.length() == 5); + } - // from non-const ptr and length, 0 inside - { - char ar[] = {'H', 'e', '\0', 'l', 'o'}; - char* ptr = ar; - cstring_span<> span{ptr, 5}; - CHECK(span.length() == 5); - } + // from non-const ptr and length, 0 inside + { + char ar[] = {'H', 'e', '\0', 'l', 'o'}; + char* ptr = ar; + cstring_span<> span{ptr, 5}; + CHECK(span.length() == 5); + } - // from const string - { - const std::string str = "Hello"; - const cstring_span<> span = str; - CHECK(span.length() == 5); - } + // from const string + { + const std::string str = "Hello"; + const cstring_span<> span = str; + CHECK(span.length() == 5); + } - // from non-const string - { - std::string str = "Hello"; - const cstring_span<> span = str; - CHECK(span.length() == 5); - } + // from non-const string + { + std::string str = "Hello"; + const cstring_span<> span = str; + CHECK(span.length() == 5); + } - // from const vector - { - const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - const cstring_span<> span = vec; - CHECK(span.length() == 5); - } + // from const vector + { + const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const cstring_span<> span = vec; + CHECK(span.length() == 5); + } - // from non-const vector - { - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - const cstring_span<> span = vec; - CHECK(span.length() == 5); - } + // from non-const vector + { + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const cstring_span<> span = vec; + CHECK(span.length() == 5); + } - // from const span - { - const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - const span<const char> inner = vec; - const cstring_span<> span = inner; - CHECK(span.length() == 5); - } + // from const span + { + const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const span<const char> inner = vec; + const cstring_span<> span = inner; + CHECK(span.length() == 5); + } - // from non-const span - { - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - const span<char> inner = vec; - const cstring_span<> span = inner; - CHECK(span.length() == 5); - } + // from non-const span + { + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const span<char> inner = vec; + const cstring_span<> span = inner; + CHECK(span.length() == 5); + } - // from const string_span - { - const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - const cstring_span<> tmp = vec; - const cstring_span<> span = tmp; - CHECK(span.length() == 5); - } + // from const string_span + { + const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const cstring_span<> tmp = vec; + const cstring_span<> span = tmp; + CHECK(span.length() == 5); + } - // from non-const string_span - { - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - string_span<> tmp = vec; - cstring_span<> span = tmp; - CHECK(span.length() == 5); - } + // from non-const string_span + { + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + string_span<> tmp = vec; + cstring_span<> span = tmp; + CHECK(span.length() == 5); + } - // creating string_span + // creating string_span - // from string literal - { + // from string literal + { #ifdef CONFIRM_COMPILATION_ERRORS - string_span<> span = "Hello"; + string_span<> span = "Hello"; #endif - } + } - // from const static array - { + // from const static array + { #ifdef CONFIRM_COMPILATION_ERRORS - const char ar[] = {'H', 'e', 'l', 'l', 'o'}; - string_span<> span = ar; - CHECK(span.length() == 5); + const char ar[] = {'H', 'e', 'l', 'l', 'o'}; + string_span<> span = ar; + CHECK(span.length() == 5); #endif - } + } - // from non-const static array - { - char ar[] = {'H', 'e', 'l', 'l', 'o'}; - string_span<> span = ar; - CHECK(span.length() == 5); - } + // from non-const static array + { + char ar[] = {'H', 'e', 'l', 'l', 'o'}; + string_span<> span = ar; + CHECK(span.length() == 5); + } - // from const ptr and length - { + // from const ptr and length + { #ifdef CONFIRM_COMPILATION_ERRORS - const char* ptr = "Hello"; - string_span<> span{ptr, 5}; - CHECK(span.length() == 5); + const char* ptr = "Hello"; + string_span<> span{ptr, 5}; + CHECK(span.length() == 5); #endif - } + } - // from non-const ptr and length - { - char ar[] = {'H', 'e', 'l', 'l', 'o'}; - char* ptr = ar; - string_span<> span{ptr, 5}; - CHECK(span.length() == 5); - } + // from non-const ptr and length + { + char ar[] = {'H', 'e', 'l', 'l', 'o'}; + char* ptr = ar; + string_span<> span{ptr, 5}; + CHECK(span.length() == 5); + } - // from const string - { + // from const string + { #ifdef CONFIRM_COMPILATION_ERRORS - const std::string str = "Hello"; - string_span<> span = str; - CHECK(span.length() == 5); + const std::string str = "Hello"; + string_span<> span = str; + CHECK(span.length() == 5); #endif - } + } - // from non-const string - { - std::string str = "Hello"; - string_span<> span = str; - CHECK(span.length() == 5); - } + // from non-const string + { + std::string str = "Hello"; + string_span<> span = str; + CHECK(span.length() == 5); + } - // from const vector - { + // from const vector + { #ifdef CONFIRM_COMPILATION_ERRORS - const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - string_span<> span = vec; - CHECK(span.length() == 5); + const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + string_span<> span = vec; + CHECK(span.length() == 5); #endif - } + } - // from non-const vector - { - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - string_span<> span = vec; - CHECK(span.length() == 5); - } + // from non-const vector + { + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + string_span<> span = vec; + CHECK(span.length() == 5); + } - // from const span - { + // from const span + { #ifdef CONFIRM_COMPILATION_ERRORS - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - const span<const char> inner = vec; - string_span<> span = inner; - CHECK(span.length() == 5); + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const span<const char> inner = vec; + string_span<> span = inner; + CHECK(span.length() == 5); #endif - } + } - // from non-const span - { - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - span<char> inner = vec; - string_span<> span = inner; - CHECK(span.length() == 5); - } + // from non-const span + { + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + span<char> inner = vec; + string_span<> span = inner; + CHECK(span.length() == 5); + } - // from non-const span of non-const data from const vector - { + // from non-const span of non-const data from const vector + { #ifdef CONFIRM_COMPILATION_ERRORS - const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - const span<char> inner = vec; - string_span<> span = inner; - CHECK(span.length() == 5); + const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const span<char> inner = vec; + string_span<> span = inner; + CHECK(span.length() == 5); #endif - } + } - // from const string_span - { + // from const string_span + { #ifdef CONFIRM_COMPILATION_ERRORS - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - cstring_span<> tmp = vec; - string_span<> span = tmp; - CHECK(span.length() == 5); + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + cstring_span<> tmp = vec; + string_span<> span = tmp; + CHECK(span.length() == 5); #endif - } + } - // from non-const string_span - { - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - const string_span<> tmp = vec; - const string_span<> span = tmp; - CHECK(span.length() == 5); - } + // from non-const string_span + { + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const string_span<> tmp = vec; + const string_span<> span = tmp; + CHECK(span.length() == 5); + } - // from non-const string_span from const vector - { + // from non-const string_span from const vector + { #ifdef CONFIRM_COMPILATION_ERRORS - const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - string_span<> tmp = vec; - string_span<> span = tmp; - CHECK(span.length() == 5); + const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + string_span<> tmp = vec; + string_span<> span = tmp; + CHECK(span.length() == 5); #endif - } - - // from const string_span of non-const data - { - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - const string_span<> tmp = vec; - const string_span<> span = tmp; - CHECK(span.length() == 5); - } } - template <typename T> - T move_wrapper(T && t) + // from const string_span of non-const data { - return std::move(t); + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + const string_span<> tmp = vec; + const string_span<> span = tmp; + CHECK(span.length() == 5); } +} - template <class T> - T create() +template <typename T> +T move_wrapper(T && t) +{ + return std::move(t); +} + +template <class T> +T create() +{ + return T{}; +} + +template <class T> +void use(basic_string_span<T, gsl::dynamic_extent>) +{ +} + +TEST_CASE("MoveConstructors") +{ + // move string_span { - return T{}; + cstring_span<> span = "Hello"; + const auto span1 = std::move(span); + CHECK(span1.length() == 5); } - - template <class T> - void use(basic_string_span<T, gsl::dynamic_extent>) { + cstring_span<> span = "Hello"; + const auto span1 = move_wrapper(std::move(span)); + CHECK(span1.length() == 5); } - - TEST(MoveConstructors) { - // move string_span - { - cstring_span<> span = "Hello"; - const auto span1 = std::move(span); - CHECK(span1.length() == 5); - } - { - cstring_span<> span = "Hello"; - const auto span1 = move_wrapper(std::move(span)); - CHECK(span1.length() == 5); - } - { - cstring_span<> span = "Hello"; - const auto span1 = move_wrapper(std::move(span)); - CHECK(span1.length() == 5); - } + cstring_span<> span = "Hello"; + const auto span1 = move_wrapper(std::move(span)); + CHECK(span1.length() == 5); + } - // move span - { - span<const char> span = ensure_z("Hello"); - const cstring_span<> span1 = std::move(span); - CHECK(span1.length() == 5); - } - { - span<const char> span = ensure_z("Hello"); - const cstring_span<> span2 = move_wrapper(std::move(span)); - CHECK(span2.length() == 5); - } + // move span + { + span<const char> span = ensure_z("Hello"); + const cstring_span<> span1 = std::move(span); + CHECK(span1.length() == 5); + } + { + span<const char> span = ensure_z("Hello"); + const cstring_span<> span2 = move_wrapper(std::move(span)); + CHECK(span2.length() == 5); + } - // move string - { + // move string + { #ifdef CONFIRM_COMPILATION_ERRORS - std::string str = "Hello"; - string_span<> span = std::move(str); - CHECK(span.length() == 5); + std::string str = "Hello"; + string_span<> span = std::move(str); + CHECK(span.length() == 5); #endif - } - { + } + { #ifdef CONFIRM_COMPILATION_ERRORS - std::string str = "Hello"; - string_span<> span = move_wrapper<std::string>(std::move(str)); - CHECK(span.length() == 5); + std::string str = "Hello"; + string_span<> span = move_wrapper<std::string>(std::move(str)); + CHECK(span.length() == 5); #endif - } - { + } + { #ifdef CONFIRM_COMPILATION_ERRORS - use<char>(create<string>()); + use<char>(create<string>()); #endif - } + } - // move container - { -#ifdef CONFIRM_COMPILATION_ERRORS - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - string_span<> span = std::move(vec); - CHECK(span.length() == 5); -#endif - } - { + // move container + { #ifdef CONFIRM_COMPILATION_ERRORS - std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; - string_span<> span = move_wrapper<std::vector<char>>(std::move(vec)); - CHECK(span.length() == 5); + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + string_span<> span = std::move(vec); + CHECK(span.length() == 5); #endif - } - { + } + { #ifdef CONFIRM_COMPILATION_ERRORS - use<char>(create<std::vector<char>>()); + std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'}; + string_span<> span = move_wrapper<std::vector<char>>(std::move(vec)); + CHECK(span.length() == 5); #endif - } } - - TEST(Conversion) { #ifdef CONFIRM_COMPILATION_ERRORS - cstring_span<> span = "Hello"; - cwstring_span<> wspan{span}; - CHECK(wspan.length() == 5); + use<char>(create<std::vector<char>>()); #endif } +} - czstring_span<> CreateTempName(string_span<> span) - { - Expects(span.size() > 1); - - int last = 0; - if (span.size() > 4) { - span[0] = 't'; - span[1] = 'm'; - span[2] = 'p'; - last = 3; - } - span[last] = '\0'; +TEST_CASE("Conversion") +{ +#ifdef CONFIRM_COMPILATION_ERRORS + cstring_span<> span = "Hello"; + cwstring_span<> wspan{span}; + CHECK(wspan.length() == 5); +#endif +} - auto ret = span.subspan(0, 4); - return {ret}; +czstring_span<> CreateTempName(string_span<> span) +{ + Expects(span.size() > 1); + + int last = 0; + if (span.size() > 4) { + span[0] = 't'; + span[1] = 'm'; + span[2] = 'p'; + last = 3; } + span[last] = '\0'; - TEST(zstring) - { - - // create zspan from zero terminated string - { - char buf[1]; - buf[0] = '\0'; + auto ret = span.subspan(0, 4); + return {ret}; +} - zstring_span<> zspan({buf, 1}); +TEST_CASE("zstring") +{ - CHECK(strlen(zspan.assume_z()) == 0); - CHECK(zspan.as_string_span().size() == 0); - CHECK(zspan.ensure_z().size() == 0); - } + // create zspan from zero terminated string + { + char buf[1]; + buf[0] = '\0'; - // create zspan from non-zero terminated string - { - char buf[1]; - buf[0] = 'a'; + zstring_span<> zspan({buf, 1}); - auto workaround_macro = [&]() { zstring_span<> zspan({buf, 1}); }; - CHECK_THROW(workaround_macro(), fail_fast); - } + CHECK(strlen(zspan.assume_z()) == 0); + CHECK(zspan.as_string_span().size() == 0); + CHECK(zspan.ensure_z().size() == 0); + } - // usage scenario: create zero-terminated temp file name and pass to a legacy API - { - char buf[10]; + // create zspan from non-zero terminated string + { + char buf[1]; + buf[0] = 'a'; - auto name = CreateTempName({buf, 10}); - if (!name.empty()) { - czstring<> str = name.assume_z(); - CHECK(strlen(str) == 3); - CHECK(*(str + 3) == '\0'); - } - } + auto workaround_macro = [&]() { zstring_span<> zspan({buf, 1}); }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); } - cwzstring_span<> CreateTempNameW(wstring_span<> span) + // usage scenario: create zero-terminated temp file name and pass to a legacy API { - Expects(span.size() > 1); + char buf[10]; - int last = 0; - if (span.size() > 4) { - span[0] = L't'; - span[1] = L'm'; - span[2] = L'p'; - last = 3; + auto name = CreateTempName({buf, 10}); + if (!name.empty()) { + czstring<> str = name.assume_z(); + CHECK(strlen(str) == 3); + CHECK(*(str + 3) == '\0'); } - span[last] = L'\0'; - - auto ret = span.subspan(0, 4); - return {ret}; } +} - TEST(wzstring) - { +cwzstring_span<> CreateTempNameW(wstring_span<> span) +{ + Expects(span.size() > 1); + + int last = 0; + if (span.size() > 4) { + span[0] = L't'; + span[1] = L'm'; + span[2] = L'p'; + last = 3; + } + span[last] = L'\0'; - // create zspan from zero terminated string - { - wchar_t buf[1]; - buf[0] = L'\0'; + auto ret = span.subspan(0, 4); + return {ret}; +} - wzstring_span<> zspan({buf, 1}); +TEST_CASE("wzstring") +{ - CHECK(wcsnlen(zspan.assume_z(), 1) == 0); - CHECK(zspan.as_string_span().size() == 0); - CHECK(zspan.ensure_z().size() == 0); - } + // create zspan from zero terminated string + { + wchar_t buf[1]; + buf[0] = L'\0'; - // create zspan from non-zero terminated string - { - wchar_t buf[1]; - buf[0] = L'a'; + wzstring_span<> zspan({buf, 1}); - const auto workaround_macro = [&]() { wzstring_span<> zspan({buf, 1}); }; - CHECK_THROW(workaround_macro(), fail_fast); - } + CHECK(wcsnlen(zspan.assume_z(), 1) == 0); + CHECK(zspan.as_string_span().size() == 0); + CHECK(zspan.ensure_z().size() == 0); + } - // usage scenario: create zero-terminated temp file name and pass to a legacy API - { - wchar_t buf[10]; + // create zspan from non-zero terminated string + { + wchar_t buf[1]; + buf[0] = L'a'; - const auto name = CreateTempNameW({buf, 10}); - if (!name.empty()) { - cwzstring<> str = name.assume_z(); - CHECK(wcsnlen(str, 10) == 3); - CHECK(*(str + 3) == L'\0'); - } - } + const auto workaround_macro = [&]() { wzstring_span<> zspan({buf, 1}); }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); } - TEST(Issue305) + // usage scenario: create zero-terminated temp file name and pass to a legacy API { - std::map<gsl::cstring_span<>, int> foo = {{"foo", 0}, {"bar", 1}}; - CHECK(foo["foo"] == 0); - CHECK(foo["bar"] == 1); + wchar_t buf[10]; + + const auto name = CreateTempNameW({buf, 10}); + if (!name.empty()) { + cwzstring<> str = name.assume_z(); + CHECK(wcsnlen(str, 10) == 3); + CHECK(*(str + 3) == L'\0'); + } } } -int main(int, const char* []) { return UnitTest::RunAllTests(); } +TEST_CASE("Issue305") +{ + std::map<gsl::cstring_span<>, int> foo = {{"foo", 0}, {"bar", 1}}; + CHECK(foo["foo"] == 0); + CHECK(foo["bar"] == 1); +} diff --git a/tests/test.cpp b/tests/test.cpp new file mode 100644 index 0000000..bae194d --- /dev/null +++ b/tests/test.cpp @@ -0,0 +1,18 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +#define CATCH_CONFIG_MAIN +#include <catch/catch.hpp> diff --git a/tests/unittest-cpp b/tests/unittest-cpp deleted file mode 160000 -Subproject c331bb0deaaf92659a31887c029ee34cac2ab19 diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp index d45af3c..67cceb5 100644 --- a/tests/utils_tests.cpp +++ b/tests/utils_tests.cpp @@ -14,7 +14,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <UnitTest++/UnitTest++.h> +#include <catch/catch.hpp> #include <gsl/gsl> @@ -22,94 +22,89 @@ using namespace gsl; -SUITE(utils_tests) +void f(int& i) { i += 1; } + +TEST_CASE("finally_lambda") { - void f(int& i) { i += 1; } + int i = 0; + { + auto _ = finally([&]() { f(i); }); + CHECK(i == 0); + } + CHECK(i == 1); +} - TEST(finally_lambda) +TEST_CASE("finally_lambda_move") +{ + int i = 0; { - int i = 0; + auto _1 = finally([&]() { f(i); }); { - auto _ = finally([&]() { f(i); }); + auto _2 = std::move(_1); CHECK(i == 0); } CHECK(i == 1); - } - - TEST(finally_lambda_move) - { - int i = 0; { - auto _1 = finally([&]() { f(i); }); - { - auto _2 = std::move(_1); - CHECK(i == 0); - } - CHECK(i == 1); - { - auto _2 = std::move(_1); - CHECK(i == 1); - } + auto _2 = std::move(_1); CHECK(i == 1); } CHECK(i == 1); } + CHECK(i == 1); +} - TEST(finally_function_with_bind) +TEST_CASE("finally_function_with_bind") +{ + int i = 0; { - int i = 0; - { - auto _ = finally(std::bind(&f, std::ref(i))); - CHECK(i == 0); - } - CHECK(i == 1); + auto _ = finally(std::bind(&f, std::ref(i))); + CHECK(i == 0); } + CHECK(i == 1); +} - int j = 0; - void g() { j += 1; } - TEST(finally_function_ptr) +int j = 0; +void g() { j += 1; } +TEST_CASE("finally_function_ptr") +{ + j = 0; { - j = 0; - { - auto _ = finally(&g); - CHECK(j == 0); - } - CHECK(j == 1); + auto _ = finally(&g); + CHECK(j == 0); } + CHECK(j == 1); +} - TEST(narrow_cast) - { - int n = 120; - char c = narrow_cast<char>(n); - CHECK(c == 120); +TEST_CASE("narrow_cast") +{ + int n = 120; + char c = narrow_cast<char>(n); + CHECK(c == 120); - n = 300; - unsigned char uc = narrow_cast<unsigned char>(n); - CHECK(uc == 44); - } + n = 300; + unsigned char uc = narrow_cast<unsigned char>(n); + CHECK(uc == 44); +} - TEST(narrow) - { - int n = 120; - const char c = narrow<char>(n); - CHECK(c == 120); +TEST_CASE("narrow") +{ + int n = 120; + const char c = narrow<char>(n); + CHECK(c == 120); - n = 300; - CHECK_THROW(narrow<char>(n), narrowing_error); + n = 300; + CHECK_THROWS_AS(narrow<char>(n), narrowing_error); - const auto int32_max = std::numeric_limits<int32_t>::max(); - const auto int32_min = std::numeric_limits<int32_t>::min(); + 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)); + 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)); - CHECK_THROW(narrow<uint32_t>(int32_t(-1)), narrowing_error); - CHECK_THROW(narrow<uint32_t>(int32_min), narrowing_error); + CHECK_THROWS_AS(narrow<uint32_t>(int32_t(-1)), narrowing_error); + CHECK_THROWS_AS(narrow<uint32_t>(int32_min), narrowing_error); - n = -42; - CHECK_THROW(narrow<unsigned>(n), narrowing_error); - } + n = -42; + CHECK_THROWS_AS(narrow<unsigned>(n), narrowing_error); } - -int main(int, const char* []) { return UnitTest::RunAllTests(); } |