From 6436dbfda05ba2bc6f05ee8db69aca64b52fee49 Mon Sep 17 00:00:00 2001 From: Werner Henze Date: Mon, 30 Dec 2024 13:38:45 +0100 Subject: [PATCH] algorithm_test, span_tests.cpp --- tests/algorithm_tests.cpp | 2 +- tests/span_tests.cpp | 364 ++++++++++++++++---------------------- 2 files changed, 151 insertions(+), 215 deletions(-) diff --git a/tests/algorithm_tests.cpp b/tests/algorithm_tests.cpp index e369be0..b4a4f81 100644 --- a/tests/algorithm_tests.cpp +++ b/tests/algorithm_tests.cpp @@ -188,7 +188,7 @@ TEST(algorithm_tests, incompatible_type) span src_span_dyn(src); span src_span_static(src); span dst_span_dyn(dst); - span dst_span_static(dst); + span dst_span_static(gsl::make_span(dst)); // every line should produce a compilation error copy(src_span_dyn, dst_span_dyn); diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index d86458b..0836dab 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -62,8 +62,7 @@ struct AddressOverloaded #if (__cplusplus > 201402L) [[maybe_unused]] #endif - AddressOverloaded - operator&() const + AddressOverloaded operator&() const { return {}; } @@ -298,70 +297,14 @@ TEST(span_test, from_array_constructor) int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; -#ifdef CONFIRM_COMPILATION_ERRORS - { - span s{arr}; - } - - { - span s{arr}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == &arr[0]); - } - - { - span s{arr2d}; - EXPECT_TRUE(s.size() == 6); - EXPECT_TRUE(s.data() == &arr2d[0][0]); - EXPECT_TRUE(s[0] == 1); - EXPECT_TRUE(s[5] == 6); - } - - { - span s{arr2d}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == &arr2d[0][0]); - } - - { - span s{arr2d}; - } -#endif { const span s{std::addressof(arr2d[0]), 1}; EXPECT_TRUE(s.size() == 1); EXPECT_TRUE(s.data() == std::addressof(arr2d[0])); } - int arr3d[2][3][2] = { { {1, 2}, {3, 4}, {5, 6} }, { {7, 8}, {9, 10}, {11, 12} } }; + int arr3d[2][3][2] = {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}}; -#ifdef CONFIRM_COMPILATION_ERRORS - { - span s{arr3d}; - EXPECT_TRUE(s.size() == 12); - EXPECT_TRUE(s.data() == &arr3d[0][0][0]); - EXPECT_TRUE(s[0] == 1); - EXPECT_TRUE(s[11] == 12); - } - - { - span s{arr3d}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == &arr3d[0][0][0]); - } - - { - span s{arr3d}; - } - - { - span s{arr3d}; - EXPECT_TRUE(s.size() == 12); - EXPECT_TRUE(s.data() == &arr3d[0][0][0]); - EXPECT_TRUE(s[0] == 1); - EXPECT_TRUE(s[5] == 6); - } -#endif { const span s{std::addressof(arr3d[0]), 1}; EXPECT_TRUE(s.size() == 1); @@ -428,42 +371,9 @@ TEST(span_test, from_std_array_constructor) EXPECT_TRUE(ao_arr.data() == fs.data()); } -#ifdef CONFIRM_COMPILATION_ERRORS - { - span s{arr}; - EXPECT_TRUE(s.size() == 2); - EXPECT_TRUE(s.data() == arr.data()); - - span cs{arr}; - EXPECT_TRUE(cs.size() == 2); - EXPECT_TRUE(cs.data() == arr.data()); - } - - { - span s{arr}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == arr.data()); - - span cs{arr}; - EXPECT_TRUE(cs.size() == 0); - EXPECT_TRUE(cs.data() == arr.data()); - } - - { - span s{arr}; - } - { auto get_an_array = []() -> std::array { return {1, 2, 3, 4}; }; - auto take_a_span = [](span s) { static_cast(s); }; - // try to take a temporary std::array - take_a_span(get_an_array()); - } -#endif - - { - auto get_an_array = []() -> std::array { return {1, 2, 3, 4}; }; - auto take_a_span = [](span s) { static_cast(s); }; + auto take_a_span = [](span) {}; // try to take a temporary std::array take_a_span(get_an_array()); } @@ -493,24 +403,6 @@ TEST(span_test, from_const_std_array_constructor) EXPECT_TRUE(s.data() == ao_arr.data()); } -#ifdef CONFIRM_COMPILATION_ERRORS - { - span s{arr}; - EXPECT_TRUE(s.size() == 2); - EXPECT_TRUE(s.data() == arr.data()); - } - - { - span s{arr}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == arr.data()); - } - - { - span s{arr}; - } -#endif - { auto get_an_array = []() -> const std::array { return {1, 2, 3, 4}; }; auto take_a_span = [](span s) { static_cast(s); }; @@ -534,28 +426,6 @@ TEST(span_test, from_std_array_const_constructor) EXPECT_TRUE(s.size() == arr.size()); EXPECT_TRUE(s.data() == arr.data()); } - -#ifdef CONFIRM_COMPILATION_ERRORS - { - span s{arr}; - EXPECT_TRUE(s.size() == 2); - EXPECT_TRUE(s.data() == arr.data()); - } - - { - span s{arr}; - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == arr.data()); - } - - { - span s{arr}; - } - - { - span s{arr}; - } -#endif } TEST(span_test, from_container_constructor) @@ -577,73 +447,40 @@ TEST(span_test, from_container_constructor) const std::string cstr = "hello"; { -#ifdef CONFIRM_COMPILATION_ERRORS +#ifdef FAIL_ON_SOME_PLATFORMS span s{str}; EXPECT_TRUE(s.size() == str.size()); - EXPECT_TRUE(s.data() == str.data())); + EXPECT_TRUE(s.data() == str.data()); #endif - span cs{str}; - EXPECT_TRUE(cs.size() == str.size()); - EXPECT_TRUE(cs.data() == str.data()); + + span cs{str}; + EXPECT_TRUE(cs.size() == str.size()); + EXPECT_TRUE(cs.data() == str.data()); } { -#ifdef CONFIRM_COMPILATION_ERRORS - span s{cstr}; -#endif span cs{cstr}; EXPECT_TRUE(cs.size() == cstr.size()); EXPECT_TRUE(cs.data() == cstr.data()); } - { -#ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_vector = []() -> std::vector { return {}; }; - auto use_span = [](span s) { static_cast(s); }; - use_span(get_temp_vector()); -#endif - } - { auto get_temp_vector = []() -> std::vector { return {}; }; auto use_span = [](span s) { static_cast(s); }; use_span(get_temp_vector()); } - { -#ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_string = []() -> std::string { return {}; }; - auto use_span = [](span s) { static_cast(s); }; - use_span(get_temp_string()); -#endif - } - { auto get_temp_string = []() -> std::string { return {}; }; auto use_span = [](span s) { static_cast(s); }; use_span(get_temp_string()); } - { -#ifdef CONFIRM_COMPILATION_ERRORS - auto get_temp_vector = []() -> const std::vector { return {}; }; - auto use_span = [](span s) { static_cast(s); }; - use_span(get_temp_vector()); -#endif - } - { auto get_temp_string = []() -> const std::string { return {}; }; auto use_span = [](span s) { static_cast(s); }; use_span(get_temp_string()); } - - { -#ifdef CONFIRM_COMPILATION_ERRORS - std::map m; - span s{m}; -#endif - } } TEST(span_test, from_convertible_span_constructor) @@ -799,7 +636,7 @@ TEST(span_test, first) { span av = arr; -#ifdef CONFIRM_COMPILATION_ERRORS +#ifdef FAIL_ON_SOME_PLATFORMS EXPECT_TRUE(av.first<6>().size() == 6); EXPECT_TRUE(av.first<-1>().size() == -1); #endif @@ -843,7 +680,7 @@ TEST(span_test, last) { span av = arr; -#ifdef CONFIRM_COMPILATION_ERRORS +#ifdef FAIL_ON_SOME_PLATFORMS EXPECT_TRUE(av.last<6>().size() == 6); #endif EXPECT_DEATH(av.last(6).size(), expected); @@ -1147,17 +984,6 @@ TEST(span_test, as_writable_bytes) { int a[] = {1, 2, 3, 4}; - { -#ifdef CONFIRM_COMPILATION_ERRORS - // you should not be able to get writeable bytes for const objects - span s = a; - EXPECT_TRUE(s.size() == 4); - span bs = as_writable_bytes(s); - EXPECT_TRUE(static_cast(bs.data()) == static_cast(s.data())); - EXPECT_TRUE(bs.size() == s.size_bytes()); -#endif - } - { span s; const auto bs = as_writable_bytes(s); @@ -1197,8 +1023,8 @@ TEST(span_test, fixed_size_conversions) static_cast(s); } -// initialization or assignment to static span that REDUCES size is NOT ok #ifdef CONFIRM_COMPILATION_ERRORS + // initialization or assignment to static span that REDUCES size is NOT ok { span s = arr; } @@ -1206,11 +1032,9 @@ TEST(span_test, fixed_size_conversions) span s2 = s4; static_cast(s2); } -#endif // even when done dynamically { - /* // this now results in a compile-time error, rather than runtime. // There is no suitable conversion from dynamic span to fixed span. span s = arr; @@ -1219,8 +1043,8 @@ TEST(span_test, fixed_size_conversions) static_cast(s2); }; EXPECT_DEATH(f(), expected); - */ } +#endif // but doing so explicitly is ok @@ -1234,19 +1058,19 @@ TEST(span_test, fixed_size_conversions) static_cast(s1); } - /* - // this is not a legal operation in std::span, so we are no longer supporting it - // conversion from span to span via call to `first` - // then convert from span to span - // The dynamic to fixed extents are not supported in the standard - // to make this work, span would need to be span. - { +#ifdef CONFIRM_COMPILATION_ERRORS + // this is not a legal operation in std::span, so we are no longer supporting it + // conversion from span to span via call to `first` + // then convert from span to span + // The dynamic to fixed extents are not supported in the standard + // to make this work, span would need to be span. + { - // NB: implicit conversion to span from span - span s1 = s4.first(1); - static_cast(s1); - } - */ + // NB: implicit conversion to span from span + span s1 = s4.first(1); + static_cast(s1); + } +#endif // initialization or assignment to static span that requires size INCREASE is not ok. int arr2[2] = {1, 2}; @@ -1268,16 +1092,17 @@ TEST(span_test, fixed_size_conversions) EXPECT_DEATH(f(), expected); } - /* - // This no longer compiles. There is no suitable conversion from dynamic span to a fixed size - span. - // this should fail - we are trying to assign a small dynamic span to a fixed_size larger one - span av = arr2; auto f = [&]() { - const span _s4 = av; - static_cast(_s4); - }; - EXPECT_DEATH(f(), expected); - */ +#ifdef CONFIRM_COMPILATION_ERRORS + // This no longer compiles. There is no suitable conversion from dynamic span to a fixed size + // span. this should fail - we are trying to assign a small dynamic span to a fixed_size larger + // one + span av = arr2; + auto f = [&]() { + const span _s4 = av; + static_cast(_s4); + }; + EXPECT_DEATH(f(), expected); +#endif } TEST(span_test, interop_with_std_regex) @@ -1376,8 +1201,119 @@ TEST(span_test, msvc_compile_error_PR1100) int arr[]{1, 7, 2, 9}; gsl::span sp{arr, std::size(arr)}; std::ranges::sort(sp); - for (const auto& e : sp) { - (void)e; - } + for (const auto& e : sp) { (void) e; } } #endif // defined(__cpp_lib_span) && defined(__cpp_lib_ranges) + +#if __cplusplus >= 201703l +using std::void_t; +#else // __cplusplus >= 201703l +template +using void_t = void; +#endif // __cplusplus < 201703l + +template +static constexpr bool CtorCompilesFor = false; +template +static constexpr bool CtorCompilesFor()})>> = true; +static_assert(CtorCompilesFor, std::array&>, + "CtorCompilesFor, std::array&>"); +static_assert(CtorCompilesFor, std::array&>, + "CtorCompilesFor, std::array&>"); +static_assert(CtorCompilesFor, std::array&>, + "CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(CtorCompilesFor, std::array&>, + "CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, int[2][3]>, "!CtorCompilesFor, int[2][3]>"); +static_assert(!CtorCompilesFor, int[2][3]>, + "!CtorCompilesFor, int[2][3]>"); +static_assert(!CtorCompilesFor, int[2][3]>, + "!CtorCompilesFor, int[2][3]>"); +static_assert(!CtorCompilesFor, int[2][3][2]>, + "!CtorCompilesFor, int[2][3][2]>"); +static_assert(!CtorCompilesFor, int[2][3][2]>, + "!CtorCompilesFor, int[2][3][2]>"); +static_assert(!CtorCompilesFor, int[2][3][2]>, + "!CtorCompilesFor, int[2][3][2]>"); +static_assert(!CtorCompilesFor, int[2][3][2]>, + "!CtorCompilesFor, int[2][3][2]>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(CtorCompilesFor, std::array&>, + "CtorCompilesFor, std::array&>"); +#ifdef FAIL_ON_SOME_PLATFORMS +static_assert(!CtorCompilesFor, std::array&&>, + "!CtorCompilesFor, std::array&&>"); +#endif +static_assert(!CtorCompilesFor, const std::array&>, + "!CtorCompilesFor, const std::array&>"); +static_assert(!CtorCompilesFor, const std::array&>, + "!CtorCompilesFor, const std::array&>"); +static_assert(!CtorCompilesFor, const std::array&>, + "!CtorCompilesFor, const std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, std::array&>, + "!CtorCompilesFor, std::array&>"); +static_assert(!CtorCompilesFor, const std::string&>, + "!CtorCompilesFor, const std::string&>"); + +static_assert(CtorCompilesFor, std::vector&>, + "CtorCompilesFor, std::vector&>"); +static_assert(CtorCompilesFor, std::vector&&>, + "CtorCompilesFor, std::vector&&>"); +#ifdef FAIL_ON_SOME_PLATFORMS +static_assert(!CtorCompilesFor, std::vector&&>, + "!CtorCompilesFor, std::vector&&>"); +static_assert(!CtorCompilesFor, const std::vector&&>, + "!CtorCompilesFor, const std::vector&&>"); +#endif + +#ifdef FAIL_ON_SOME_PLATFORMS +static_assert(CtorCompilesFor, std::string&>, + "CtorCompilesFor, std::string&>"); +#endif +static_assert(CtorCompilesFor, std::string&&>, + "CtorCompilesFor, std::string&&>"); +static_assert(!CtorCompilesFor, std::string&&>, + "!CtorCompilesFor, std::string&&>"); +static_assert(!CtorCompilesFor, const std::string&&>, + "!CtorCompilesFor, const std::string&&>"); + +static_assert(!CtorCompilesFor, std::map&>, + "!CtorCompilesFor, std::map&>"); + +static_assert(CtorCompilesFor, span&>, + "CtorCompilesFor, span&>"); +static_assert(CtorCompilesFor, span&>, + "CtorCompilesFor, span&>"); +static_assert(!CtorCompilesFor, span&>, + "!CtorCompilesFor, span&>"); + +template +static constexpr bool AsWritableBytesCompilesFor = false; +template +static constexpr bool + AsWritableBytesCompilesFor()))>> = true; +static_assert(AsWritableBytesCompilesFor>, + "AsWriteableBytesCompilesFor>"); +static_assert(!AsWritableBytesCompilesFor>, + "!AsWriteableBytesCompilesFor>");