diff options
author | Roelf-Jilling <r-j.wolthuis@live.com> | 2020-03-26 18:24:19 +0300 |
---|---|---|
committer | Roelf-Jilling <r-j.wolthuis@live.com> | 2020-03-26 18:24:19 +0300 |
commit | 30c068781fb26ffb23c198e1a2abf1737885e31e (patch) | |
tree | fcbc0c625b586f4685685fb236fb79ac778398ff /tests | |
parent | f4c2292f9de8b8a3c2e14f9d1a39fbdde6916b08 (diff) | |
parent | d90fefea6de716fdf5e90fe3cfd8281a704e3be2 (diff) |
Merge branch 'master' into TravisCI
Diffstat (limited to 'tests')
-rw-r--r-- | tests/CMakeLists.txt | 76 | ||||
-rw-r--r-- | tests/CMakeLists.txt.in | 2 | ||||
-rw-r--r-- | tests/algorithm_tests.cpp | 23 | ||||
-rw-r--r-- | tests/assertion_tests.cpp | 23 | ||||
-rw-r--r-- | tests/at_tests.cpp | 23 | ||||
-rw-r--r-- | tests/bounds_tests.cpp | 26 | ||||
-rw-r--r-- | tests/byte_tests.cpp | 23 | ||||
-rw-r--r-- | tests/multi_span_tests.cpp | 27 | ||||
-rw-r--r-- | tests/notnull_tests.cpp | 29 | ||||
-rw-r--r-- | tests/owner_tests.cpp | 24 | ||||
-rw-r--r-- | tests/span_compatibility_tests.cpp | 1072 | ||||
-rw-r--r-- | tests/span_ext_tests.cpp | 360 | ||||
-rw-r--r-- | tests/span_tests.cpp | 495 | ||||
-rw-r--r-- | tests/strict_notnull_tests.cpp | 29 | ||||
-rw-r--r-- | tests/strided_span_tests.cpp | 26 | ||||
-rw-r--r-- | tests/string_span_tests.cpp | 44 | ||||
-rw-r--r-- | tests/utils_tests.cpp | 26 |
17 files changed, 1609 insertions, 719 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 680bd5e..0219319 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -45,14 +45,38 @@ if(MSVC) # MSVC or simulating MSVC /EHsc /W4 /WX + $<$<CXX_COMPILER_ID:MSVC>: + /wd4996 # Use of function or classes marked [[deprecated]] + /wd26409 # CppCoreCheck - GTest + /wd26426 # CppCoreCheck - GTest + /wd26440 # CppCoreCheck - GTest + /wd26446 # CppCoreCheck - prefer gsl::at() + /wd26472 # CppCoreCheck - use gsl::narrow(_cast) + /wd26481 # CppCoreCheck - use span instead of pointer arithmetic + $<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,1920>: # VS2015 + /wd4189 # variable is initialized but not referenced + $<$<NOT:$<CONFIG:Debug>>: # Release, RelWithDebInfo + /wd4702 # Unreachable code + > + > + > $<$<CXX_COMPILER_ID:Clang>: -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic + -Wno-covered-switch-default # GTest + -Wno-deprecated-declarations # Allow tests for [[deprecated]] elements + -Wno-global-constructors # GTest + -Wno-language-extension-token # GTest gtest-port.h -Wno-missing-braces -Wno-missing-prototypes - -Wno-unknown-attributes - $<$<EQUAL:${GSL_CXX_STANDARD},14>:-Wno-unused-member-function> + -Wno-shift-sign-overflow # GTest gtest-port.h + -Wno-undef # GTest + -Wno-used-but-marked-unused # GTest EXPECT_DEATH + $<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]] + -Wno-unused-member-function + -Wno-unused-variable + > > ) else() @@ -67,16 +91,23 @@ else() -Wpedantic -Wshadow -Wsign-conversion + -Wno-deprecated-declarations # Allow tests for [[deprecated]] elements $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>: -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-missing-braces + -Wno-covered-switch-default # GTest + -Wno-global-constructors # GTest -Wno-missing-prototypes -Wno-padded -Wno-unknown-attributes - $<$<EQUAL:${GSL_CXX_STANDARD},14>:-Wno-unused-member-function> + -Wno-used-but-marked-unused # GTest EXPECT_DEATH -Wno-weak-vtables + $<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]] + -Wno-unused-member-function + -Wno-unused-variable + > > $<$<CXX_COMPILER_ID:Clang>: $<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,4.99>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>: @@ -88,6 +119,21 @@ else() $<$<EQUAL:${GSL_CXX_STANDARD},17>:-Wno-undefined-func-template> > > + $<$<CXX_COMPILER_ID:GNU>: + -Wdouble-promotion # float implicit to double + -Wlogical-op # suspicious uses of logical operators + $<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>: + -Wduplicated-cond # duplicated if-else conditions + -Wmisleading-indentation + -Wnull-dereference + $<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]] + -Wno-unused-variable + > + > + $<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7>>: + -Wduplicated-branches # identical if-else branches + > + > ) endif(MSVC) @@ -114,6 +160,8 @@ function(add_gsl_test name) endfunction() add_gsl_test(span_tests) +add_gsl_test(span_ext_tests) +add_gsl_test(span_compatibility_tests) add_gsl_test(multi_span_tests) add_gsl_test(strided_span_tests) add_gsl_test(string_span_tests) @@ -140,14 +188,18 @@ endforeach(flag_var) # please try to keep entries ordered =) add_library(gsl_tests_config_noexcept INTERFACE) if(MSVC) # MSVC or simulating MSVC + target_compile_definitions(gsl_tests_config_noexcept INTERFACE + _HAS_EXCEPTIONS=0 # disable exceptions in the Microsoft STL + ) target_compile_options(gsl_tests_config_noexcept INTERFACE ${GSL_CPLUSPLUS_OPT} - /EHsc /W4 /WX $<$<CXX_COMPILER_ID:MSVC>: /wd4577 /wd4702 + /wd26440 # CppCoreCheck - GTest + /wd26446 # CppCoreCheck - prefer gsl::at() > $<$<CXX_COMPILER_ID:Clang>: -Weverything @@ -178,6 +230,22 @@ else() -Wno-unknown-attributes -Wno-weak-vtables > + $<$<CXX_COMPILER_ID:GNU>: + -Wdouble-promotion # float implicit to double + -Wlogical-op # suspicious uses of logical operators + -Wuseless-cast # casting to its own type + $<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>: + -Wduplicated-cond # duplicated if-else conditions + -Wmisleading-indentation + -Wnull-dereference + > + $<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7>>: + -Wduplicated-branches # identical if-else branches + > + $<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>>: + -Wcast-align=strict # increase alignment (i.e. char* to int*) + > + > ) endif(MSVC) diff --git a/tests/CMakeLists.txt.in b/tests/CMakeLists.txt.in index 50c041d..f380b8f 100644 --- a/tests/CMakeLists.txt.in +++ b/tests/CMakeLists.txt.in @@ -4,7 +4,7 @@ project(googletest-download NONE) include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG master + GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" CONFIGURE_COMMAND "" diff --git a/tests/algorithm_tests.cpp b/tests/algorithm_tests.cpp index 50bff11..ec9b2d1 100644 --- a/tests/algorithm_tests.cpp +++ b/tests/algorithm_tests.cpp @@ -14,25 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch -#endif - -#if __clang__ || __GNUC__ -// disable warnings from gtest -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/gsl_algorithm> // for copy #include <gsl/span> // for span @@ -244,7 +225,3 @@ TEST(algorithm_tests, small_destination_span) copy(src_span_static, dst_span_static); #endif } - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/assertion_tests.cpp b/tests/assertion_tests.cpp index 598c7dc..c45b00c 100644 --- a/tests/assertion_tests.cpp +++ b/tests/assertion_tests.cpp @@ -14,25 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch -#endif - -#if __clang__ || __GNUC__ -//disable warnings from gtest -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/gsl_assert> // for fail_fast (ptr only), Ensures, Expects @@ -78,7 +59,3 @@ TEST(assertion_tests, ensures) EXPECT_TRUE(g(2) == 3); EXPECT_DEATH(g(9), deathstring); } - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/at_tests.cpp b/tests/at_tests.cpp index cbed5ba..be2c7b8 100644 --- a/tests/at_tests.cpp +++ b/tests/at_tests.cpp @@ -14,25 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch -#endif - -#if __clang__ || __GNUC__ -//disable warnings from gtest -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/gsl_util> // for at @@ -152,7 +133,3 @@ static constexpr bool test_constexpr() static_assert(test_constexpr(), "FAIL"); #endif - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/bounds_tests.cpp b/tests/bounds_tests.cpp index 4291ae1..9c2fb96 100644 --- a/tests/bounds_tests.cpp +++ b/tests/bounds_tests.cpp @@ -14,28 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch -#pragma warning(disable : 4996) // use of function or classes marked [[deprecated]] -#endif - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -//disable warnings from gtest -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/multi_span> // for static_bounds, static_bounds_dynamic_range_t @@ -122,7 +100,3 @@ TEST(bounds_tests, bounds_convertible) #ifdef CONFIRM_COMPILATION_ERRORS copy(src_span_static, dst_span_static); #endif - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/byte_tests.cpp b/tests/byte_tests.cpp index ab243a7..f2850ad 100644 --- a/tests/byte_tests.cpp +++ b/tests/byte_tests.cpp @@ -14,25 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) -#endif // _MSC_VER - -#if __clang__ || __GNUC__ -//disable warnings from gtest -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/gsl_byte> // for to_byte, to_integer, byte, operator&, ope... @@ -146,7 +127,3 @@ TEST(byte_tests, aliasing) #ifdef CONFIRM_COMPILATION_ERRORS copy(src_span_static, dst_span_static); #endif - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/multi_span_tests.cpp b/tests/multi_span_tests.cpp index f2e040f..6425928 100644 --- a/tests/multi_span_tests.cpp +++ b/tests/multi_span_tests.cpp @@ -14,29 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch -#pragma warning(disable : 4996) // multi_span is in the process of being deprecated. - // Suppressing warnings until it is completely removed -#endif - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -//disable warnings from gtest -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/gsl_byte> // for byte @@ -1884,7 +1861,3 @@ TEST(multi_span_test, iterator) #ifdef CONFIRM_COMPILATION_ERRORS copy(src_span_static, dst_span_static); #endif - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index 038119e..0578131 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -14,28 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch - -// Fix VS2015 build breaks in Release -#pragma warning(disable : 4702) // unreachable code -#endif - -#if __clang__ || __GNUC__ -//disable warnings from gtest -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/pointers> // for not_null, operator<, operator<=, operator> @@ -555,10 +533,3 @@ TEST(notnull_tests, TestMakeNotNull) } #endif } - -static_assert(std::is_nothrow_move_constructible<not_null<void*>>::value, - "not_null must be no-throw move constructible"); - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/owner_tests.cpp b/tests/owner_tests.cpp index 8756596..ca8222f 100644 --- a/tests/owner_tests.cpp +++ b/tests/owner_tests.cpp @@ -14,26 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch - -#endif - -#if __clang__ || __GNUC__ -//disable warnings from gtest -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/pointers> // for owner @@ -61,7 +41,3 @@ TEST(owner_tests, check_pointer_constraint) } #endif } - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/span_compatibility_tests.cpp b/tests/span_compatibility_tests.cpp new file mode 100644 index 0000000..8733e72 --- /dev/null +++ b/tests/span_compatibility_tests.cpp @@ -0,0 +1,1072 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <gtest/gtest.h> + +#include <gsl/gsl_byte> // for byte +#include <gsl/span> // for span, span_iterator, operator==, operator!= + +#include <array> // for array +#include <cstddef> // for ptrdiff_t +#include <iterator> // for reverse_iterator, operator-, operator== +#include <type_traits> // for integral_constant<>::value, is_default_co... +#include <utility> +#include <vector> // for vector + +using namespace std; +using namespace gsl; + +// Below are tests that verify the gsl interface support the same things as the std +// Ranges and Concepts support need to be added later. + +struct Base +{ +}; +struct Derived : Base +{ +}; +static_assert(std::is_convertible<Derived*, Base*>::value, "std::is_convertible<Derived*, Base*>"); +static_assert(!std::is_convertible<Derived (*)[], Base (*)[]>::value, + "!std::is_convertible<Derived(*)[], Base(*)[]>"); + +TEST(span_compatibility_tests, assertion_tests) +{ + int arr[3]{10, 20, 30}; + std::array<int, 3> stl{{100, 200, 300}}; + + { + gsl::span<int> sp_dyn; + EXPECT_TRUE(sp_dyn.data() == nullptr); + EXPECT_TRUE(sp_dyn.size() == 0); + EXPECT_TRUE(sp_dyn.empty()); + } + { + gsl::span<int, 0> sp_zero; + EXPECT_TRUE(sp_zero.data() == nullptr); + EXPECT_TRUE(sp_zero.size() == 0); + EXPECT_TRUE(sp_zero.empty()); + + gsl::span<int> sp_dyn_a(arr, 3); + gsl::span<int> sp_dyn_b(begin(arr), 3); + EXPECT_TRUE(sp_dyn_a.data() == std::begin(arr)); + EXPECT_TRUE(sp_dyn_b.data() == std::begin(arr)); + EXPECT_TRUE(sp_dyn_a.size() == 3); + EXPECT_TRUE(sp_dyn_b.size() == 3); + + gsl::span<int, 3> sp_three_a(arr, 3); + gsl::span<int, 3> sp_three_b(begin(arr), 3); + EXPECT_TRUE(sp_three_a.data() == std::begin(arr)); + EXPECT_TRUE(sp_three_b.data() == std::begin(arr)); + EXPECT_TRUE(sp_three_a.size() == 3); + EXPECT_TRUE(sp_three_b.size() == 3); + + gsl::span<const int> sp_const_a(arr, 3); + gsl::span<const int> sp_const_b(begin(arr), 3); + EXPECT_TRUE(sp_const_a.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_b.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_a.size() == 3); + EXPECT_TRUE(sp_const_b.size() == 3); + +#if __cplusplus >= 201703l + gsl::span<const int> sp_const_c(std::as_const(arr), 3); + EXPECT_TRUE(sp_const_c.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_c.size() == 3); +#endif // __cplusplus >= 201703l + + gsl::span<const int> sp_const_d(cbegin(arr), 3); + EXPECT_TRUE(sp_const_d.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_d.size() == 3); + } + { + gsl::span<int> sp_dyn_a(begin(arr), std::end(arr)); + EXPECT_TRUE(sp_dyn_a.data() == std::begin(arr)); + EXPECT_TRUE(sp_dyn_a.size() == 3); + + gsl::span<int, 3> sp_three_a(begin(arr), std::end(arr)); + EXPECT_TRUE(sp_three_a.data() == std::begin(arr)); + EXPECT_TRUE(sp_three_a.size() == 3); + + gsl::span<const int> sp_const_a(begin(arr), std::end(arr)); + gsl::span<const int> sp_const_b(begin(arr), std::cend(arr)); + gsl::span<const int> sp_const_c(cbegin(arr), std::end(arr)); + gsl::span<const int> sp_const_d(cbegin(arr), std::cend(arr)); + EXPECT_TRUE(sp_const_a.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_b.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_c.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_d.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_a.size() == 3); + EXPECT_TRUE(sp_const_b.size() == 3); + EXPECT_TRUE(sp_const_c.size() == 3); + EXPECT_TRUE(sp_const_d.size() == 3); + } + { + gsl::span<int> sp_dyn_a(arr); + gsl::span<int> sp_dyn_b(stl); + gsl::span<int> sp_dyn_c{stl}; + gsl::span<const int> sp_dyn_d{stl}; + EXPECT_TRUE(sp_dyn_a.data() == std::begin(arr)); + EXPECT_TRUE(sp_dyn_b.data() == stl.data()); + EXPECT_TRUE(sp_dyn_a.size() == 3); + EXPECT_TRUE(sp_dyn_b.size() == 3); + + gsl::span<int, 3> sp_three_a(arr); + gsl::span<int, 3> sp_three_b(stl); + EXPECT_TRUE(sp_three_a.data() == std::begin(arr)); + EXPECT_TRUE(sp_three_b.data() == stl.data()); + EXPECT_TRUE(sp_three_a.size() == 3); + EXPECT_TRUE(sp_three_b.size() == 3); + + gsl::span<const int> sp_const_w(arr); + gsl::span<const int> sp_const_y(stl); + EXPECT_TRUE(sp_const_w.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_y.data() == stl.data()); + EXPECT_TRUE(sp_const_w.size() == 3); + EXPECT_TRUE(sp_const_y.size() == 3); + +#if __cplusplus >= 201703l + gsl::span<const int> sp_const_x(std::as_const(arr)); + EXPECT_TRUE(sp_const_x.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_x.size() == 3); + + gsl::span<const int> sp_const_z(std::as_const(stl)); + EXPECT_TRUE(sp_const_z.data() == stl.data()); + EXPECT_TRUE(sp_const_z.size() == 3); +#endif // __cplusplus >= 201703l + } + { + const gsl::span<int> orig_dyn(arr); + const gsl::span<int, 3> orig_three(arr); + const gsl::span<const int> orig_const_dyn(arr); + const gsl::span<const int, 3> orig_const_three(arr); + + gsl::span<int> sp_a(orig_dyn); + gsl::span<int> sp_b(orig_three); + + gsl::span<int, 3> sp_c(orig_three); + + gsl::span<const int> sp_d(orig_dyn); + gsl::span<const int> sp_e(orig_three); + gsl::span<const int> sp_f(orig_const_dyn); + gsl::span<const int> sp_g(orig_const_three); + + gsl::span<const int, 3> sp_h(orig_three); + gsl::span<const int, 3> sp_i(orig_const_three); + + EXPECT_TRUE(sp_a.data() == std::begin(arr)); + EXPECT_TRUE(sp_b.data() == std::begin(arr)); + EXPECT_TRUE(sp_c.data() == std::begin(arr)); + EXPECT_TRUE(sp_d.data() == std::begin(arr)); + EXPECT_TRUE(sp_e.data() == std::begin(arr)); + EXPECT_TRUE(sp_f.data() == std::begin(arr)); + EXPECT_TRUE(sp_g.data() == std::begin(arr)); + EXPECT_TRUE(sp_h.data() == std::begin(arr)); + EXPECT_TRUE(sp_i.data() == std::begin(arr)); + EXPECT_TRUE(sp_a.size() == 3); + EXPECT_TRUE(sp_b.size() == 3); + EXPECT_TRUE(sp_c.size() == 3); + EXPECT_TRUE(sp_d.size() == 3); + EXPECT_TRUE(sp_e.size() == 3); + EXPECT_TRUE(sp_f.size() == 3); + EXPECT_TRUE(sp_g.size() == 3); + EXPECT_TRUE(sp_h.size() == 3); + EXPECT_TRUE(sp_i.size() == 3); + } + { + gsl::span<int> sp_dyn(arr); + gsl::span<int, 3> sp_three(arr); + gsl::span<const int> sp_const_dyn(arr); + gsl::span<const int, 3> sp_const_three(arr); + + EXPECT_TRUE(sp_dyn.data() == std::begin(arr)); + EXPECT_TRUE(sp_three.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_dyn.data() == std::begin(arr)); + EXPECT_TRUE(sp_const_three.data() == std::begin(arr)); + EXPECT_TRUE(sp_dyn.size() == 3); + EXPECT_TRUE(sp_three.size() == 3); + EXPECT_TRUE(sp_const_dyn.size() == 3); + EXPECT_TRUE(sp_const_three.size() == 3); + + int other[4]{12, 34, 56, 78}; + + sp_dyn = gsl::span<int>{other}; + sp_three = gsl::span<int, 3>{stl}; + sp_const_dyn = gsl::span<const int>{other}; + sp_const_three = gsl::span<const int, 3>{stl}; + + EXPECT_TRUE(sp_dyn.data() == std::begin(other)); + EXPECT_TRUE(sp_three.data() == stl.data()); + EXPECT_TRUE(sp_const_dyn.data() == std::begin(other)); + EXPECT_TRUE(sp_const_three.data() == stl.data()); + EXPECT_TRUE(sp_dyn.size() == 4); + EXPECT_TRUE(sp_three.size() == 3); + EXPECT_TRUE(sp_const_dyn.size() == 4); + EXPECT_TRUE(sp_const_three.size() == 3); + } + { + gsl::span<int>::iterator it_dyn{}; + + { + gsl::span<int> sp_dyn(arr); + it_dyn = sp_dyn.begin(); + } + + EXPECT_TRUE(*it_dyn == arr[0]); + EXPECT_TRUE(it_dyn[2] == arr[2]); + + gsl::span<int, 3>::iterator it_three{}; + + { + gsl::span<int, 3> sp_three(stl); + it_three = sp_three.begin(); + } + + EXPECT_TRUE(*it_three == stl[0]); + EXPECT_TRUE(it_three[2] == stl[2]); + } + + { + int sequence[9]{10, 20, 30, 40, 50, 60, 70, 80, 90}; + + const gsl::span<int> sp_dyn(sequence); + const gsl::span<int, 9> sp_nine(sequence); + + auto first_3 = sp_dyn.first<3>(); + auto first_4 = sp_nine.first<4>(); + auto first_5 = sp_dyn.first(5); + auto first_6 = sp_nine.first(6); + static_assert(noexcept(sp_dyn.first<3>()), "noexcept(sp_dyn.first<3>())"); // strengthened + static_assert(noexcept(sp_nine.first<4>()), "noexcept(sp_nine.first<4>())"); // strengthened + static_assert(noexcept(sp_dyn.first(5)), "noexcept(sp_dyn.first(5))"); // strengthened + static_assert(noexcept(sp_nine.first(6)), "noexcept(sp_nine.first(6))"); // strengthened + static_assert(is_same<decltype(first_3), gsl::span<int, 3>>::value, + "is_same<decltype(first_3), gsl::span<int, 3>>::value"); + static_assert(is_same<decltype(first_4), gsl::span<int, 4>>::value, + "is_same<decltype(first_4), gsl::span<int, 4>>::value"); + static_assert(is_same<decltype(first_5), gsl::span<int>>::value, + "is_same<decltype(first_5), gsl::span<int>>::value"); + static_assert(is_same<decltype(first_6), gsl::span<int>>::value, + "is_same<decltype(first_6), gsl::span<int>>::value"); + EXPECT_TRUE(first_3.data() == std::begin(sequence)); + EXPECT_TRUE(first_4.data() == std::begin(sequence)); + EXPECT_TRUE(first_5.data() == std::begin(sequence)); + EXPECT_TRUE(first_6.data() == std::begin(sequence)); + EXPECT_TRUE(first_3.size() == 3); + EXPECT_TRUE(first_4.size() == 4); + EXPECT_TRUE(first_5.size() == 5); + EXPECT_TRUE(first_6.size() == 6); + + auto last_3 = sp_dyn.last<3>(); + auto last_4 = sp_nine.last<4>(); + auto last_5 = sp_dyn.last(5); + auto last_6 = sp_nine.last(6); + static_assert(noexcept(sp_dyn.last<3>()), "noexcept(sp_dyn.last<3>())"); // strengthened + static_assert(noexcept(sp_nine.last<4>()), "noexcept(sp_nine.last<4>())"); // strengthened + static_assert(noexcept(sp_dyn.last(5)), "noexcept(sp_dyn.last(5))"); // strengthened + static_assert(noexcept(sp_nine.last(6)), "noexcept(sp_nine.last(6))"); // strengthened + static_assert(is_same<decltype(last_3), gsl::span<int, 3>>::value, + "is_same<decltype(last_3), gsl::span<int, 3>>::value"); + static_assert(is_same<decltype(last_4), gsl::span<int, 4>>::value, + "is_same<decltype(last_4), gsl::span<int, 4>>::value"); + static_assert(is_same<decltype(last_5), gsl::span<int>>::value, + "is_same<decltype(last_5), gsl::span<int>>::value"); + static_assert(is_same<decltype(last_6), gsl::span<int>>::value, + "is_same<decltype(last_6), gsl::span<int>>::value"); + EXPECT_TRUE(last_3.data() == std::begin(sequence) + 6); + EXPECT_TRUE(last_4.data() == std::begin(sequence) + 5); + EXPECT_TRUE(last_5.data() == std::begin(sequence) + 4); + EXPECT_TRUE(last_6.data() == std::begin(sequence) + 3); + EXPECT_TRUE(last_3.size() == 3); + EXPECT_TRUE(last_4.size() == 4); + EXPECT_TRUE(last_5.size() == 5); + EXPECT_TRUE(last_6.size() == 6); + + auto offset_3 = sp_dyn.subspan<3>(); + auto offset_4 = sp_nine.subspan<4>(); + auto offset_5 = sp_dyn.subspan(5); + auto offset_6 = sp_nine.subspan(6); + static_assert(noexcept(sp_dyn.subspan<3>()), + "noexcept(sp_dyn.subspan<3>())"); // strengthened + static_assert(noexcept(sp_nine.subspan<4>()), + "noexcept(sp_nine.subspan<4>())"); // strengthened + static_assert(noexcept(sp_dyn.subspan(5)), "noexcept(sp_dyn.subspan(5))"); // strengthened + static_assert(noexcept(sp_nine.subspan(6)), "noexcept(sp_nine.subspan(6))"); // strengthened + static_assert(is_same<decltype(offset_3), gsl::span<int>>::value, + "is_same<decltype(offset_3), gsl::span<int>>::value"); + static_assert(is_same<decltype(offset_4), gsl::span<int, 5>>::value, + "is_same<decltype(offset_4), gsl::span<int, 5>>::value"); + static_assert(is_same<decltype(offset_5), gsl::span<int>>::value, + "is_same<decltype(offset_5), gsl::span<int>>::value"); + static_assert(is_same<decltype(offset_6), gsl::span<int>>::value, + "is_same<decltype(offset_6), gsl::span<int>>::value"); + EXPECT_TRUE(offset_3.data() == std::begin(sequence) + 3); + EXPECT_TRUE(offset_4.data() == std::begin(sequence) + 4); + EXPECT_TRUE(offset_5.data() == std::begin(sequence) + 5); + EXPECT_TRUE(offset_6.data() == std::begin(sequence) + 6); + EXPECT_TRUE(offset_3.size() == 6); + EXPECT_TRUE(offset_4.size() == 5); + EXPECT_TRUE(offset_5.size() == 4); + EXPECT_TRUE(offset_6.size() == 3); + + auto subspan_3 = sp_dyn.subspan<3, 2>(); + auto subspan_4 = sp_nine.subspan<4, 2>(); + auto subspan_5 = sp_dyn.subspan(5, 2); + auto subspan_6 = sp_nine.subspan(6, 2); + static_assert(noexcept(sp_dyn.subspan<3, 2>()), + "noexcept(sp_dyn.subspan<3, 2>())"); // strengthened + static_assert(noexcept(sp_nine.subspan<4, 2>()), + "noexcept(sp_nine.subspan<4, 2>())"); // strengthened + static_assert(noexcept(sp_dyn.subspan(5, 2)), + "noexcept(sp_dyn.subspan(5, 2))"); // strengthened + static_assert(noexcept(sp_nine.subspan(6, 2)), + "noexcept(sp_nine.subspan(6, 2))"); // strengthened + static_assert(is_same<decltype(subspan_3), gsl::span<int, 2>>::value, + "is_same<decltype(subspan_3), gsl::span<int, 2>>::value"); + static_assert(is_same<decltype(subspan_4), gsl::span<int, 2>>::value, + "is_same<decltype(subspan_4), gsl::span<int, 2>>::value"); + static_assert(is_same<decltype(subspan_5), gsl::span<int>>::value, + "is_same<decltype(subspan_5), gsl::span<int>>::value"); + static_assert(is_same<decltype(subspan_6), gsl::span<int>>::value, + "is_same<decltype(subspan_6), gsl::span<int>>::value"); + EXPECT_TRUE(subspan_3.data() == std::begin(sequence) + 3); + EXPECT_TRUE(subspan_4.data() == std::begin(sequence) + 4); + EXPECT_TRUE(subspan_5.data() == std::begin(sequence) + 5); + EXPECT_TRUE(subspan_6.data() == std::begin(sequence) + 6); + EXPECT_TRUE(subspan_3.size() == 2); + EXPECT_TRUE(subspan_4.size() == 2); + EXPECT_TRUE(subspan_5.size() == 2); + EXPECT_TRUE(subspan_6.size() == 2); + + static_assert(noexcept(sp_dyn.size()), "noexcept(sp_dyn.size())"); + static_assert(noexcept(sp_dyn.size_bytes()), "noexcept(sp_dyn.size_bytes())"); + static_assert(noexcept(sp_dyn.empty()), "noexcept(sp_dyn.empty())"); + static_assert(noexcept(sp_dyn[0]), "noexcept(sp_dyn[0])"); // strengthened + static_assert(noexcept(sp_dyn.front()), "noexcept(sp_dyn.front())"); // strengthened + static_assert(noexcept(sp_dyn.back()), "noexcept(sp_dyn.back())"); // strengthened + static_assert(noexcept(sp_dyn.data()), "noexcept(sp_dyn.data())"); + static_assert(noexcept(sp_dyn.begin()), "noexcept(sp_dyn.begin())"); + static_assert(noexcept(sp_dyn.end()), "noexcept(sp_dyn.end())"); + static_assert(noexcept(sp_dyn.cbegin()), "noexcept(sp_dyn.cbegin())"); + static_assert(noexcept(sp_dyn.cend()), "noexcept(sp_dyn.cend())"); + static_assert(noexcept(sp_dyn.rbegin()), "noexcept(sp_dyn.rbegin())"); + static_assert(noexcept(sp_dyn.rend()), "noexcept(sp_dyn.rend())"); + static_assert(noexcept(sp_dyn.crbegin()), "noexcept(sp_dyn.crbegin())"); + static_assert(noexcept(sp_dyn.crend()), "noexcept(sp_dyn.crend())"); + + static_assert(noexcept(sp_nine.size()), "noexcept(sp_nine.size())"); + static_assert(noexcept(sp_nine.size_bytes()), "noexcept(sp_nine.size_bytes())"); + static_assert(noexcept(sp_nine.empty()), "noexcept(sp_nine.empty())"); + static_assert(noexcept(sp_nine[0]), "noexcept(sp_nine[0])"); // strengthened + static_assert(noexcept(sp_nine.front()), "noexcept(sp_nine.front())"); // strengthened + static_assert(noexcept(sp_nine.back()), "noexcept(sp_nine.back())"); // strengthened + static_assert(noexcept(sp_nine.data()), "noexcept(sp_nine.data())"); + static_assert(noexcept(sp_nine.begin()), "noexcept(sp_nine.begin())"); + static_assert(noexcept(sp_nine.end()), "noexcept(sp_nine.end())"); + static_assert(noexcept(sp_nine.cbegin()), "noexcept(sp_nine.cbegin())"); + static_assert(noexcept(sp_nine.cend()), "noexcept(sp_nine.cend())"); + static_assert(noexcept(sp_nine.rbegin()), "noexcept(sp_nine.rbegin())"); + static_assert(noexcept(sp_nine.rend()), "noexcept(sp_nine.rend())"); + static_assert(noexcept(sp_nine.crbegin()), "noexcept(sp_nine.crbegin())"); + static_assert(noexcept(sp_nine.crend()), "noexcept(sp_nine.crend())"); + + EXPECT_TRUE(sp_dyn.size() == 9); + EXPECT_TRUE(sp_nine.size() == 9); + + EXPECT_TRUE(sp_dyn.size_bytes() == 9 * sizeof(int)); + EXPECT_TRUE(sp_nine.size_bytes() == 9 * sizeof(int)); + + EXPECT_TRUE(!sp_dyn.empty()); + EXPECT_TRUE(!sp_nine.empty()); + + EXPECT_TRUE(sp_dyn[0] == 10); + EXPECT_TRUE(sp_nine[0] == 10); + EXPECT_TRUE(sp_dyn[8] == 90); + EXPECT_TRUE(sp_nine[8] == 90); + + EXPECT_TRUE(sp_dyn.front() == 10); + EXPECT_TRUE(sp_nine.front() == 10); + + EXPECT_TRUE(sp_dyn.back() == 90); + EXPECT_TRUE(sp_nine.back() == 90); + + EXPECT_TRUE(&sp_dyn.front() == std::begin(sequence)); + EXPECT_TRUE(&sp_nine.front() == std::begin(sequence)); + EXPECT_TRUE(&sp_dyn[4] == std::begin(sequence) + 4); + EXPECT_TRUE(&sp_nine[4] == std::begin(sequence) + 4); + EXPECT_TRUE(&sp_dyn.back() == std::begin(sequence) + 8); + EXPECT_TRUE(&sp_nine.back() == std::begin(sequence) + 8); + + EXPECT_TRUE(sp_dyn.data() == std::begin(sequence)); + EXPECT_TRUE(sp_nine.data() == std::begin(sequence)); + + EXPECT_TRUE(*sp_dyn.begin() == 10); + EXPECT_TRUE(*sp_nine.begin() == 10); + + EXPECT_TRUE(sp_dyn.end()[-2] == 80); + EXPECT_TRUE(sp_nine.end()[-2] == 80); + + EXPECT_TRUE(*sp_dyn.cbegin() == 10); + EXPECT_TRUE(*sp_nine.cbegin() == 10); + + EXPECT_TRUE(sp_dyn.cend()[-2] == 80); + EXPECT_TRUE(sp_nine.cend()[-2] == 80); + + EXPECT_TRUE(*sp_dyn.rbegin() == 90); + EXPECT_TRUE(*sp_nine.rbegin() == 90); + + EXPECT_TRUE(sp_dyn.rend()[-2] == 20); + EXPECT_TRUE(sp_nine.rend()[-2] == 20); + + EXPECT_TRUE(*sp_dyn.crbegin() == 90); + EXPECT_TRUE(*sp_nine.crbegin() == 90); + + EXPECT_TRUE(sp_dyn.crend()[-2] == 20); + EXPECT_TRUE(sp_nine.crend()[-2] == 20); + + static_assert(is_same<decltype(sp_dyn.begin()), gsl::span<int>::iterator>::value, + "is_same<decltype(sp_dyn.begin()), gsl::span<int>::iterator>::value"); + static_assert(is_same<decltype(sp_nine.begin()), gsl::span<int, 9>::iterator>::value, + "is_same<decltype(sp_nine.begin()), gsl::span<int, 9>::iterator>::value"); + static_assert(is_same<decltype(sp_dyn.end()), gsl::span<int>::iterator>::value, + "is_same<decltype(sp_dyn.end()), gsl::span<int>::iterator>::value"); + static_assert(is_same<decltype(sp_nine.end()), gsl::span<int, 9>::iterator>::value, + "is_same<decltype(sp_nine.end()), gsl::span<int, 9>::iterator>::value"); + static_assert(is_same<decltype(sp_dyn.cbegin()), gsl::span<int>::const_iterator>::value, + "is_same<decltype(sp_dyn.cbegin()), gsl::span<int>::const_iterator>::value"); + static_assert( + is_same<decltype(sp_nine.cbegin()), gsl::span<int, 9>::const_iterator>::value, + "is_same<decltype(sp_nine.cbegin()), gsl::span<int, 9>::const_iterator>::value"); + static_assert(is_same<decltype(sp_dyn.cend()), gsl::span<int>::const_iterator>::value, + "is_same<decltype(sp_dyn.cend()), gsl::span<int>::const_iterator>::value"); + static_assert( + is_same<decltype(sp_nine.cend()), gsl::span<int, 9>::const_iterator>::value, + "is_same<decltype(sp_nine.cend()), gsl::span<int, 9>::const_iterator>::value"); + static_assert( + is_same<decltype(sp_dyn.rbegin()), gsl::span<int>::reverse_iterator>::value, + "is_same<decltype(sp_dyn.rbegin()), gsl::span<int>::reverse_iterator>::value"); + static_assert( + is_same<decltype(sp_nine.rbegin()), gsl::span<int, 9>::reverse_iterator>::value, + "is_same<decltype(sp_nine.rbegin()), gsl::span<int, 9>::reverse_iterator>::value"); + static_assert(is_same<decltype(sp_dyn.rend()), gsl::span<int>::reverse_iterator>::value, + "is_same<decltype(sp_dyn.rend()), gsl::span<int>::reverse_iterator>::value"); + static_assert( + is_same<decltype(sp_nine.rend()), gsl::span<int, 9>::reverse_iterator>::value, + "is_same<decltype(sp_nine.rend()), gsl::span<int, 9>::reverse_iterator>::value"); + static_assert( + is_same<decltype(sp_dyn.crbegin()), gsl::span<int>::const_reverse_iterator>::value, + "is_same<decltype(sp_dyn.crbegin()), gsl::span<int>::const_reverse_iterator>::value"); + static_assert( + is_same<decltype(sp_nine.crbegin()), gsl::span<int, 9>::const_reverse_iterator>::value, + "is_same<decltype(sp_nine.crbegin()), gsl::span<int, " + "9>::const_reverse_iterator>::value"); + static_assert( + is_same<decltype(sp_dyn.crend()), gsl::span<int>::const_reverse_iterator>::value, + "is_same<decltype(sp_dyn.crend()), gsl::span<int>::const_reverse_iterator>::value"); + static_assert( + is_same<decltype(sp_nine.crend()), gsl::span<int, 9>::const_reverse_iterator>::value, + "is_same<decltype(sp_nine.crend()), gsl::span<int, 9>::const_reverse_iterator>::value"); + } + { + int sequence[9]{10, 20, 30, 40, 50, 60, 70, 80, 90}; + + constexpr size_t SizeBytes = sizeof(sequence); + + const gsl::span<int> sp_dyn(sequence); + const gsl::span<int, 9> sp_nine(sequence); + const gsl::span<const int> sp_const_dyn(sequence); + const gsl::span<const int, 9> sp_const_nine(sequence); + + static_assert(noexcept(as_bytes(sp_dyn)), "noexcept(as_bytes(sp_dyn))"); + static_assert(noexcept(as_bytes(sp_nine)), "noexcept(as_bytes(sp_nine))"); + static_assert(noexcept(as_bytes(sp_const_dyn)), "noexcept(as_bytes(sp_const_dyn))"); + static_assert(noexcept(as_bytes(sp_const_nine)), "noexcept(as_bytes(sp_const_nine))"); + static_assert(noexcept(as_writable_bytes(sp_dyn)), "noexcept(as_writable_bytes(sp_dyn))"); + static_assert(noexcept(as_writable_bytes(sp_nine)), "noexcept(as_writable_bytes(sp_nine))"); + + auto sp_1 = as_bytes(sp_dyn); + auto sp_2 = as_bytes(sp_nine); + auto sp_3 = as_bytes(sp_const_dyn); + auto sp_4 = as_bytes(sp_const_nine); + auto sp_5 = as_writable_bytes(sp_dyn); + auto sp_6 = as_writable_bytes(sp_nine); + + static_assert(is_same<decltype(sp_1), gsl::span<const byte>>::value, + "is_same<decltype(sp_1), gsl::span<const byte>>::value"); + static_assert(is_same<decltype(sp_2), gsl::span<const byte, SizeBytes>>::value, + "is_same<decltype(sp_2), gsl::span<const byte, SizeBytes>>::value"); + static_assert(is_same<decltype(sp_3), gsl::span<const byte>>::value, + "is_same<decltype(sp_3), gsl::span<const byte>>::value"); + static_assert(is_same<decltype(sp_4), gsl::span<const byte, SizeBytes>>::value, + "is_same<decltype(sp_4), gsl::span<const byte, SizeBytes>>::value"); + static_assert(is_same<decltype(sp_5), gsl::span<byte>>::value, + "is_same<decltype(sp_5), gsl::span<byte>>::value"); + static_assert(is_same<decltype(sp_6), gsl::span<byte, SizeBytes>>::value, + "is_same<decltype(sp_6), gsl::span<byte, SizeBytes>>::value"); + + EXPECT_TRUE(sp_1.data() == reinterpret_cast<const byte*>(begin(sequence))); + EXPECT_TRUE(sp_2.data() == reinterpret_cast<const byte*>(begin(sequence))); + EXPECT_TRUE(sp_3.data() == reinterpret_cast<const byte*>(begin(sequence))); + EXPECT_TRUE(sp_4.data() == reinterpret_cast<const byte*>(begin(sequence))); + EXPECT_TRUE(sp_5.data() == reinterpret_cast<byte*>(begin(sequence))); + EXPECT_TRUE(sp_6.data() == reinterpret_cast<byte*>(begin(sequence))); + + EXPECT_TRUE(sp_1.size() == SizeBytes); + EXPECT_TRUE(sp_2.size() == SizeBytes); + EXPECT_TRUE(sp_3.size() == SizeBytes); + EXPECT_TRUE(sp_4.size() == SizeBytes); + EXPECT_TRUE(sp_5.size() == SizeBytes); + EXPECT_TRUE(sp_6.size() == SizeBytes); + } +} + +// assertions for span's definition +static_assert(std::is_same<decltype(gsl::dynamic_extent), const std::size_t>::value, + "gsl::dynamic_extent must be respresented as std::size_t"); +static_assert(gsl::dynamic_extent == static_cast<std::size_t>(-1), + "gsl::dynamic_extent must be defined as the max value of std::size_t"); + +static_assert(std::is_same<decltype(gsl::span<int>::extent), const std::size_t>::value, + "Ensure that the type of gsl::span::extent is std::size_t"); +static_assert(gsl::span<int>::extent == gsl::dynamic_extent, + "gsl::span<int>::extent should be equivalent to gsl::dynamic_extent"); + +static_assert(std::is_same<decltype(gsl::span<int, 3>::extent), const std::size_t>::value, + "Ensure that the type of gsl::span::extent is std::size_t"); +static_assert(gsl::span<int, 3>::extent == 3, "Ensure that span<int, 3>::extent is equal to 3"); + +static_assert(std::is_same<gsl::span<int>::element_type, int>::value, + "span<int>::element_type should be int"); +static_assert(std::is_same<gsl::span<int>::value_type, int>::value, + "span<int>::value_type should be int"); +static_assert(std::is_same<gsl::span<int>::size_type, std::size_t>::value, + "span<int>::size_type should be std::size_t"); +static_assert(std::is_same<gsl::span<int>::difference_type, ptrdiff_t>::value, + "span<int>::difference_type should be std::ptrdiff_t"); +static_assert(std::is_same<gsl::span<int>::pointer, int*>::value, + "span<int>::pointer should be int*"); +static_assert(std::is_same<gsl::span<int>::const_pointer, const int*>::value, + "span<int>::const_pointer should be const int*"); +static_assert(std::is_same<gsl::span<int>::reference, int&>::value, + "span<int>::reference should be int&"); +static_assert(std::is_same<gsl::span<int>::const_reference, const int&>::value, + "span<int>::const_reference should be const int&"); + +static_assert(std::is_same<gsl::span<int, 3>::element_type, int>::value, + "span<int, 3>::element_type should be int"); +static_assert(std::is_same<gsl::span<int, 3>::value_type, int>::value, + "span<int, 3>::value_type should be int"); +static_assert(std::is_same<gsl::span<int, 3>::size_type, std::size_t>::value, + "span<int, 3>::size_type should be std::size_t"); +static_assert(std::is_same<gsl::span<int, 3>::difference_type, ptrdiff_t>::value, + "span<int, 3>::difference_type should be std::ptrdiff_t"); +static_assert(std::is_same<gsl::span<int, 3>::pointer, int*>::value, + "span<int, 3>::pointer should be int*"); +static_assert(std::is_same<gsl::span<int, 3>::const_pointer, const int*>::value, + "span<int, 3>::const_pointer should be const int*"); +static_assert(std::is_same<gsl::span<int, 3>::reference, int&>::value, + "span<int, 3>::reference should be int&"); +static_assert(std::is_same<gsl::span<int, 3>::const_reference, const int&>::value, + "span<int, 3>::const_reference should be const int&"); + +static_assert(std::is_same<gsl::span<const int>::element_type, const int>::value, + "span<const int>::element_type should be const int"); +static_assert(std::is_same<gsl::span<const int>::value_type, int>::value, + "span<const int>::value_type should be int"); +static_assert(std::is_same<gsl::span<const int>::size_type, std::size_t>::value, + "span<const int>::size_type should be size_t"); +static_assert(std::is_same<gsl::span<const int>::difference_type, ptrdiff_t>::value, + "span<const int>::difference_type should be ptrdiff_t"); +static_assert(std::is_same<gsl::span<const int>::pointer, const int*>::value, + "span<const int>::pointer should be const int*"); +static_assert(std::is_same<gsl::span<const int>::const_pointer, const int*>::value, + "span<const int>::const_pointer should be const int*"); +static_assert(std::is_same<gsl::span<const int>::reference, const int&>::value, + "span<const int>::reference should be const int&"); +static_assert(std::is_same<gsl::span<const int>::const_reference, const int&>::value, + "span<const int>::const_reference should be const int&"); + +static_assert(std::is_same<gsl::span<const int, 3>::element_type, const int>::value, + "span<const int, 3>::element_type should be const int"); +static_assert(std::is_same<gsl::span<const int, 3>::value_type, int>::value, + "span<const int, 3>::value_type should be int"); +static_assert(std::is_same<gsl::span<const int, 3>::size_type, std::size_t>::value, + "span<const int, 3>::size_type should be size_t"); +static_assert(std::is_same<gsl::span<const int, 3>::difference_type, ptrdiff_t>::value, + "span<const int, 3>::difference_type should be ptrdiff_t"); +static_assert(std::is_same<gsl::span<const int, 3>::pointer, const int*>::value, + "span<const int, 3>::pointer should be const int*"); +static_assert(std::is_same<gsl::span<const int, 3>::const_pointer, const int*>::value, + "span<const int, 3>::const_pointer should be const int*"); +static_assert(std::is_same<gsl::span<const int, 3>::reference, const int&>::value, + "span<const int, 3>::reference should be const int&"); +static_assert(std::is_same<gsl::span<const int, 3>::const_reference, const int&>::value, + "span<const int, 3>::const_reference should be const int&"); + +// assertions for span_iterator +static_assert(std::is_same<std::iterator_traits<gsl::span<int>::iterator>::pointer, int*>::value, + "span<int>::iterator's pointer should be int*"); +static_assert( + std::is_same<std::iterator_traits<gsl::span<int>::const_iterator>::pointer, const int*>::value, + "span<int>::const_iterator's pointer should be const int*"); +static_assert( + std::is_same<gsl::span<int>::reverse_iterator, + std::reverse_iterator<gsl::span<int>::iterator>>::value, + "span<int>::reverse_iterator should equal std::reverse_iterator<span<int>::iterator>"); +static_assert(std::is_same<gsl::span<int>::const_reverse_iterator, + std::reverse_iterator<gsl::span<int>::const_iterator>>::value, + "span<int>::const_reverse_iterator should equal " + "std::reverse_iterator<span<int>::const_iterator>"); + +static_assert(std::is_same<std::iterator_traits<gsl::span<int, 3>::iterator>::pointer, int*>::value, + "span<int, 3>::iterator's pointer should be int*"); +static_assert(std::is_same<std::iterator_traits<gsl::span<int, 3>::const_iterator>::pointer, + const int*>::value, + "span<int, 3>::const_iterator's pointer should be const int*"); +static_assert( + std::is_same<gsl::span<int, 3>::reverse_iterator, + std::reverse_iterator<gsl::span<int, 3>::iterator>>::value, + "span<int, 3>::reverse_iterator should equal std::reverse_iterator<span<int, 3>::iterator>"); +static_assert(std::is_same<gsl::span<int, 3>::const_reverse_iterator, + std::reverse_iterator<gsl::span<int, 3>::const_iterator>>::value, + "span<int, 3>::const_reverse_iterator should equal std::reverse_iterator<span<int, " + "3>::const_iterator>"); + +static_assert( + std::is_same<std::iterator_traits<gsl::span<const int>::iterator>::pointer, const int*>::value, + "span<const int>::iterator's pointer should be int*"); +static_assert(std::is_same<std::iterator_traits<gsl::span<const int>::const_iterator>::pointer, + const int*>::value, + "span<const int>::const_iterator's pointer should be const int*"); +static_assert(std::is_same<gsl::span<const int>::reverse_iterator, + std::reverse_iterator<gsl::span<const int>::iterator>>::value, + "span<const int>::reverse_iterator should equal std::reverse_iterator<span<const " + "int>::iterator>"); +static_assert(std::is_same<gsl::span<const int>::const_reverse_iterator, + std::reverse_iterator<gsl::span<const int>::const_iterator>>::value, + "span<const int>::const_reverse_iterator should equal " + "std::reverse_iterator<span<const int>::const_iterator>"); + +static_assert(std::is_same<std::iterator_traits<gsl::span<const int, 3>::iterator>::pointer, + const int*>::value, + "span<const int, 3>::iterator's pointer should be int*"); +static_assert(std::is_same<std::iterator_traits<gsl::span<const int, 3>::const_iterator>::pointer, + const int*>::value, + "span<const int, 3>::const_iterator's pointer should be const int*"); +static_assert(std::is_same<gsl::span<const int, 3>::reverse_iterator, + std::reverse_iterator<gsl::span<const int, 3>::iterator>>::value, + "span<const int, 3>::reverse_iterator should equal std::reverse_iterator<span<const " + "int, 3>::iterator>"); +static_assert(std::is_same<gsl::span<const int, 3>::const_reverse_iterator, + std::reverse_iterator<gsl::span<const int, 3>::const_iterator>>::value, + "span<const int, 3>::const_reverse_iterator should equal " + "std::reverse_iterator<span<const int, 3>::const_iterator>"); + +// copyability assertions +static_assert(std::is_trivially_copyable<gsl::span<int>>::value, + "span<int> should be trivially copyable"); +static_assert(std::is_trivially_copyable<gsl::span<int>::iterator>::value, + "span<int>::iterator should be trivially copyable"); +static_assert(std::is_trivially_copyable<gsl::span<int>::const_iterator>::value, + "span<int>::const_iterator should be trivially copyable"); + +static_assert(std::is_trivially_copyable<gsl::span<int, 3>>::value, + "span<int, 3> should be trivially copyable"); +static_assert(std::is_trivially_copyable<gsl::span<int, 3>::iterator>::value, + "span<int, 3>::iterator should be trivially copyable"); +static_assert(std::is_trivially_copyable<gsl::span<int, 3>::const_iterator>::value, + "span<int, 3>::const_iterator should be trivially copyable"); + +static_assert(std::is_trivially_copyable<gsl::span<const int>>::value, + "span<const int> should be trivially copyable"); +static_assert(std::is_trivially_copyable<gsl::span<const int>::iterator>::value, + "span<const int>::iterator should be trivially copyable"); +static_assert(std::is_trivially_copyable<gsl::span<const int>::const_iterator>::value, + "span<const int>::const_iterator should be trivially copyable"); + +static_assert(std::is_trivially_copyable<gsl::span<const int, 3>>::value, + "span<const int, 3> should be trivially copyable"); +static_assert(std::is_trivially_copyable<gsl::span<const int, 3>::iterator>::value, + "span<const int, 3>::iterator should be trivially copyable"); +static_assert(std::is_trivially_copyable<gsl::span<const int, 3>::const_iterator>::value, + "span<const int, 3>::const_iterator should be trivially copyable"); + +// nothrow constructible assertions +static_assert(std::is_nothrow_constructible<gsl::span<int>, int*, std::size_t>::value, + "std::is_nothrow_constructible<gsl::span<int>, int*, std::size_t>"); +static_assert(std::is_nothrow_constructible<gsl::span<int>, int*, std::uint16_t>::value, + "std::is_nothrow_constructible<gsl::span<int>, int*, std::uint16_t>"); +static_assert(std::is_nothrow_constructible<gsl::span<int>, int*, int*>::value, + "std::is_nothrow_constructible<gsl::span<int>, int*, int*>"); +static_assert(std::is_nothrow_constructible<gsl::span<int>, int (&)[3]>::value, + "std::is_nothrow_constructible<gsl::span<int>, int(&)[3]>"); +static_assert(std::is_nothrow_constructible<gsl::span<int>, const gsl::span<int>&>::value, + "std::is_nothrow_constructible<gsl::span<int>, const gsl::span<int>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<int>, const gsl::span<int, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<int>, const gsl::span<int, 3>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<int>, const gsl::span<int, 500>&>::value, + "std::is_nothrow_constructible<gsl::span<int>, const gsl::span<int, 500>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<int>, std::array<int, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<int>, std::array<int, 3>&>"); + +static_assert(std::is_nothrow_constructible<gsl::span<int, 3>, int*, std::size_t>::value, + "std::is_nothrow_constructible<gsl::span<int, 3>, int*, std::size_t>"); +static_assert(std::is_nothrow_constructible<gsl::span<int, 3>, int*, std::uint16_t>::value, + "std::is_nothrow_constructible<gsl::span<int, 3>, int*, std::uint16_t>"); +static_assert(std::is_nothrow_constructible<gsl::span<int, 3>, int*, int*>::value, + "std::is_nothrow_constructible<gsl::span<int, 3>, int*, int*>"); +static_assert(std::is_nothrow_constructible<gsl::span<int, 3>, int (&)[3]>::value, + "std::is_nothrow_constructible<gsl::span<int, 3>, int(&)[3]>"); +static_assert(std::is_nothrow_constructible<gsl::span<int, 3>, const gsl::span<int, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<int, 3>, const gsl::span<int, 3>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<int, 3>, std::array<int, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<int, 3>, std::array<int, 3>&>"); + +static_assert(std::is_nothrow_constructible<gsl::span<const int>, int*, std::size_t>::value, + "std::is_nothrow_constructible<gsl::span<const int>, int*, std::size_t>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, int*, int*>::value, + "std::is_nothrow_constructible<gsl::span<const int>, int*, int*>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, int*, const int*>::value, + "std::is_nothrow_constructible<gsl::span<const int>, int*, const int*>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, int (&)[3]>::value, + "std::is_nothrow_constructible<gsl::span<const int>, int(&)[3]>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, const int*, int*>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const int*, int*>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, const int*, const int*>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const int*, const int*>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, const int*, std::size_t>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const int*, std::size_t>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, const int (&)[3]>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const int(&)[3]>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<int>&>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<int>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<int, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<int, 3>&>"); +static_assert( + std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<int, 500>&>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<int, 500>&>"); +static_assert( + std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<const int>&>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<const int>&>"); +static_assert( + std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<const int, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<const int, 3>&>"); +static_assert( + std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<const int, 500>&>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const gsl::span<const int, 500>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, std::array<int, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const int>, std::array<int, 3>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<const int>, const std::array<int, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const int>, const std::array<int, 3>&>"); + +static_assert( + std::is_nothrow_constructible<gsl::span<const int, 3>, const gsl::span<int, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const int, 3>, const gsl::span<int, 3>&>"); +static_assert( + std::is_nothrow_constructible<gsl::span<const int, 3>, const gsl::span<const int, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const int, 3>, const gsl::span<const int, 3>&>"); + +static_assert(std::is_nothrow_constructible<gsl::span<Base>, Base (&)[3]>::value, + "std::is_nothrow_constructible<gsl::span<Base>, Base(&)[3]>"); +static_assert(std::is_nothrow_constructible<gsl::span<Base>, const gsl::span<Base>&>::value, + "std::is_nothrow_constructible<gsl::span<Base>, const gsl::span<Base>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<Base>, const gsl::span<Base, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<Base>, const gsl::span<Base, 3>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<Base>, std::array<Base, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<Base>, std::array<Base, 3>&>"); + +static_assert(std::is_nothrow_constructible<gsl::span<Base, 3>, Base (&)[3]>::value, + "std::is_nothrow_constructible<gsl::span<Base, 3>, Base(&)[3]>"); +static_assert(std::is_nothrow_constructible<gsl::span<Base, 3>, const gsl::span<Base, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<Base, 3>, const gsl::span<Base, 3>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<Base, 3>, std::array<Base, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<Base, 3>, std::array<Base, 3>&>"); + +static_assert(std::is_nothrow_constructible<gsl::span<const Base>, Base (&)[3]>::value, + "std::is_nothrow_constructible<gsl::span<const Base>, Base(&)[3]>"); +static_assert(std::is_nothrow_constructible<gsl::span<const Base>, const Base (&)[3]>::value, + "std::is_nothrow_constructible<gsl::span<const Base>, const Base(&)[3]>"); +static_assert(std::is_nothrow_constructible<gsl::span<const Base>, const gsl::span<Base>&>::value, + "std::is_nothrow_constructible<gsl::span<const Base>, const gsl::span<Base>&>"); +static_assert( + std::is_nothrow_constructible<gsl::span<const Base>, const gsl::span<Base, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const Base>, const gsl::span<Base, 3>&>"); +static_assert( + std::is_nothrow_constructible<gsl::span<const Base>, const gsl::span<const Base>&>::value, + "std::is_nothrow_constructible<gsl::span<const Base>, const gsl::span<const Base>&>"); +static_assert( + std::is_nothrow_constructible<gsl::span<const Base>, const gsl::span<const Base, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const Base>, const gsl::span<const Base, 3>&>"); +static_assert(std::is_nothrow_constructible<gsl::span<const Base>, std::array<Base, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const Base>, std::array<Base, 3>&>"); +static_assert( + std::is_nothrow_constructible<gsl::span<const Base>, const std::array<Base, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const Base>, const std::array<Base, 3>&>"); + +static_assert( + std::is_nothrow_constructible<gsl::span<const Base, 3>, const gsl::span<Base, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const Base, 3>, const gsl::span<Base, 3>&>"); +static_assert( + std::is_nothrow_constructible<gsl::span<const Base, 3>, const gsl::span<const Base, 3>&>::value, + "std::is_nothrow_constructible<gsl::span<const Base, 3>, const gsl::span<const Base, 3>&>"); + +// non-constructible assertions +static_assert(!std::is_constructible<gsl::span<int>, const int*, int*>::value, + "!std::is_constructible<gsl::span<int>, const int*, int*>"); +static_assert(!std::is_constructible<gsl::span<int>, const int*, const int*>::value, + "!std::is_constructible<gsl::span<int>, const int*, const int*>"); +static_assert(!std::is_constructible<gsl::span<int>, const int*, double*>::value, + "!std::is_constructible<gsl::span<int>, const int*, double*>"); +static_assert(!std::is_constructible<gsl::span<int>, const int*, std::size_t>::value, + "!std::is_constructible<gsl::span<int>, const int*, std::size_t>"); +static_assert(!std::is_constructible<gsl::span<int>, const int (&)[3]>::value, + "!std::is_constructible<gsl::span<int>, const int(&)[3]>"); +static_assert(!std::is_constructible<gsl::span<int>, double*, int*>::value, + "!std::is_constructible<gsl::span<int>, double*, int*>"); +static_assert(!std::is_constructible<gsl::span<int>, double*, const int*>::value, + "!std::is_constructible<gsl::span<int>, double*, const int*>"); +static_assert(!std::is_constructible<gsl::span<int>, double*, double*>::value, + "!std::is_constructible<gsl::span<int>, double*, double*>"); +static_assert(!std::is_constructible<gsl::span<int>, double*, std::size_t>::value, + "!std::is_constructible<gsl::span<int>, double*, std::size_t>"); +static_assert(!std::is_constructible<gsl::span<int>, double (&)[3]>::value, + "!std::is_constructible<gsl::span<int>, double(&)[3]>"); +static_assert(!std::is_constructible<gsl::span<int>, int*, double*>::value, + "!std::is_constructible<gsl::span<int>, int*, double*>"); +static_assert(!std::is_constructible<gsl::span<int>, std::size_t, int*>::value, + "!std::is_constructible<gsl::span<int>, std::size_t, int*>"); +static_assert(!std::is_constructible<gsl::span<int>, std::size_t, std::size_t>::value, + "!std::is_constructible<gsl::span<int>, std::size_t, std::size_t>"); +static_assert(!std::is_constructible<gsl::span<int>, const gsl::span<const int>&>::value, + "!std::is_constructible<gsl::span<int>, const gsl::span<const int>&>"); +static_assert(!std::is_constructible<gsl::span<int>, const gsl::span<const int, 3>&>::value, + "!std::is_constructible<gsl::span<int>, const gsl::span<const int, 3>&>"); +static_assert(!std::is_constructible<gsl::span<int>, const gsl::span<const int, 500>&>::value, + "!std::is_constructible<gsl::span<int>, const gsl::span<const int, 500>&>"); +static_assert(!std::is_constructible<gsl::span<int>, const gsl::span<double, 3>&>::value, + "!std::is_constructible<gsl::span<int>, const gsl::span<double, 3>&>"); +static_assert(!std::is_constructible<gsl::span<int>, std::array<double, 3>&>::value, + "!std::is_constructible<gsl::span<int>, std::array<double, 3>&>"); +static_assert(!std::is_constructible<gsl::span<int>, const std::array<int, 3>&>::value, + "!std::is_constructible<gsl::span<int>, const std::array<int, 3>&>"); + +static_assert(!std::is_constructible<gsl::span<int, 3>, int*, double*>::value, + "!std::is_constructible<gsl::span<int, 3>, int*, double*>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, int (&)[500]>::value, + "!std::is_constructible<gsl::span<int, 3>, int(&)[500]>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const int*, int*>::value, + "!std::is_constructible<gsl::span<int, 3>, const int*, int*>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const int*, const int*>::value, + "!std::is_constructible<gsl::span<int, 3>, const int*, const int*>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const int*, std::size_t>::value, + "!std::is_constructible<gsl::span<int, 3>, const int*, std::size_t>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const int*, double*>::value, + "!std::is_constructible<gsl::span<int, 3>, const int*, double*>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const int (&)[3]>::value, + "!std::is_constructible<gsl::span<int, 3>, const int(&)[3]>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, double*, std::size_t>::value, + "!std::is_constructible<gsl::span<int, 3>, double*, std::size_t>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, double*, int*>::value, + "!std::is_constructible<gsl::span<int, 3>, double*, int*>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, double*, const int*>::value, + "!std::is_constructible<gsl::span<int, 3>, double*, const int*>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, double*, double*>::value, + "!std::is_constructible<gsl::span<int, 3>, double*, double*>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, double (&)[3]>::value, + "!std::is_constructible<gsl::span<int, 3>, double(&)[3]>"); + +static_assert(!std::is_constructible<gsl::span<int, 3>, std::size_t, int*>::value, + "!std::is_constructible<gsl::span<int, 3>, std::size_t, int*>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, std::size_t, std::size_t>::value, + "!std::is_constructible<gsl::span<int, 3>, std::size_t, std::size_t>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, std::array<double, 3>&>::value, + "!std::is_constructible<gsl::span<int, 3>, std::array<double, 3>&>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, std::array<int, 500>&>::value, + "!std::is_constructible<gsl::span<int, 3>, std::array<int, 500>&>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const std::array<int, 3>&>::value, + "!std::is_constructible<gsl::span<int, 3>, const std::array<int, 3>&>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const gsl::span<int>&>::value, + "!std::is_constructible<gsl::span<int, 3>, const gsl::span<int>&>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const gsl::span<int, 500>&>::value, + "!std::is_constructible<gsl::span<int, 3>, const gsl::span<int, 500>&>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const gsl::span<const int>&>::value, + "!std::is_constructible<gsl::span<int, 3>, const gsl::span<const int>&>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const gsl::span<const int, 3>&>::value, + "!std::is_constructible<gsl::span<int, 3>, const gsl::span<const int, 3>&>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const gsl::span<const int, 500>&>::value, + "!std::is_constructible<gsl::span<int, 3>, const gsl::span<const int, 500>&>"); +static_assert(!std::is_constructible<gsl::span<int, 3>, const gsl::span<double, 3>&>::value, + "!std::is_constructible<gsl::span<int, 3>, const gsl::span<double, 3>&>"); + +static_assert(!std::is_constructible<gsl::span<const int>, double (&)[3]>::value, + "!std::is_constructible<gsl::span<const int>, double(&)[3]>"); +static_assert(!std::is_constructible<gsl::span<const int>, std::array<double, 3>&>::value, + "!std::is_constructible<gsl::span<const int>, std::array<double, 3>&>"); +static_assert(!std::is_constructible<gsl::span<const int>, const gsl::span<double, 3>&>::value, + "!std::is_constructible<gsl::span<const int>, const gsl::span<double, 3>&>"); + +static_assert(!std::is_constructible<gsl::span<const int, 3>, const gsl::span<int>&>::value, + "!std::is_constructible<gsl::span<const int, 3>, const gsl::span<int>&>"); +static_assert(!std::is_constructible<gsl::span<const int, 3>, const gsl::span<int, 500>&>::value, + "!std::is_constructible<gsl::span<const int, 3>, const gsl::span<int, 500>&>"); +static_assert(!std::is_constructible<gsl::span<const int, 3>, const gsl::span<const int>&>::value, + "!std::is_constructible<gsl::span<const int, 3>, const gsl::span<const int>&>"); +static_assert( + !std::is_constructible<gsl::span<const int, 3>, const gsl::span<const int, 500>&>::value, + "!std::is_constructible<gsl::span<const int, 3>, const gsl::span<const int, 500>&>"); +static_assert(!std::is_constructible<gsl::span<const int, 3>, const gsl::span<double, 3>&>::value, + "!std::is_constructible<gsl::span<const int, 3>, const gsl::span<double, 3>&>"); + +static_assert(!std::is_constructible<gsl::span<Base>, Derived (&)[3]>::value, + "!std::is_constructible<gsl::span<Base>, Derived(&)[3]>"); +static_assert(!std::is_constructible<gsl::span<Base>, std::array<Derived, 3>&>::value, + "!std::is_constructible<gsl::span<Base>, std::array<Derived, 3>&>"); +static_assert(!std::is_constructible<gsl::span<Base>, std::vector<Derived>&>::value, + "!std::is_constructible<gsl::span<Base>, std::vector<Derived>&>"); +static_assert(!std::is_constructible<gsl::span<Base>, const gsl::span<Derived>&>::value, + "!std::is_constructible<gsl::span<Base>, const gsl::span<Derived>&>"); +static_assert(!std::is_constructible<gsl::span<Base>, const gsl::span<Derived, 3>&>::value, + "!std::is_constructible<gsl::span<Base>, const gsl::span<Derived, 3>&>"); + +static_assert(!std::is_constructible<gsl::span<Base, 3>, const gsl::span<Derived, 3>&>::value, + "!std::is_constructible<gsl::span<Base, 3>, const gsl::span<Derived, 3>&>"); +static_assert(!std::is_constructible<gsl::span<Base, 3>, Derived (&)[3]>::value, + "!std::is_constructible<gsl::span<Base, 3>, Derived(&)[3]>"); +static_assert(!std::is_constructible<gsl::span<Base, 3>, std::array<Derived, 3>&>::value, + "!std::is_constructible<gsl::span<Base, 3>, std::array<Derived, 3>&>"); + +static_assert(!std::is_constructible<gsl::span<const Base>, Derived (&)[3]>::value, + "!std::is_constructible<gsl::span<const Base>, Derived(&)[3]>"); +static_assert(!std::is_constructible<gsl::span<const Base>, const Derived (&)[3]>::value, + "!std::is_constructible<gsl::span<const Base>, const Derived(&)[3]>"); +static_assert(!std::is_constructible<gsl::span<const Base>, std::array<Derived, 3>&>::value, + "!std::is_constructible<gsl::span<const Base>, std::array<Derived, 3>&>"); +static_assert(!std::is_constructible<gsl::span<const Base>, const std::array<Derived, 3>&>::value, + "!std::is_constructible<gsl::span<const Base>, const std::array<Derived, 3>&>"); +static_assert(!std::is_constructible<gsl::span<const Base>, const gsl::span<Derived>&>::value, + "!std::is_constructible<gsl::span<const Base>, const gsl::span<Derived>&>"); +static_assert(!std::is_constructible<gsl::span<const Base>, const gsl::span<Derived, 3>&>::value, + "!std::is_constructible<gsl::span<const Base>, const gsl::span<Derived, 3>&>"); +static_assert(!std::is_constructible<gsl::span<const Base>, const gsl::span<const Derived>&>::value, + "!std::is_constructible<gsl::span<const Base>, const gsl::span<const Derived>&>"); +static_assert( + !std::is_constructible<gsl::span<const Base>, const gsl::span<const Derived, 3>&>::value, + "!std::is_constructible<gsl::span<const Base>, const gsl::span<const Derived, 3>&>"); + +static_assert(!std::is_constructible<gsl::span<const Base, 3>, const gsl::span<Derived, 3>&>::value, + "!std::is_constructible<gsl::span<const Base, 3>, const gsl::span<Derived, 3>&>"); +static_assert( + !std::is_constructible<gsl::span<const Base, 3>, const gsl::span<const Derived, 3>&>::value, + "!std::is_constructible<gsl::span<const Base, 3>, const gsl::span<const Derived, 3>&>"); + +static_assert(!std::is_constructible<gsl::span<const Derived>, std::array<Base, 3>&>::value, + "!std::is_constructible<gsl::span<const Derived>, std::array<Base, 3>&>"); +static_assert(!std::is_constructible<gsl::span<const Derived>, const std::array<Base, 3>&>::value, + "!std::is_constructible<gsl::span<const Derived>, const std::array<Base, 3>&>"); + +// no throw copy constructor +static_assert(std::is_nothrow_copy_constructible<gsl::span<int>>::value, + "std::is_nothrow_copy_constructible<gsl::span<int>>"); +static_assert(std::is_nothrow_copy_constructible<gsl::span<int, 3>>::value, + "std::is_nothrow_copy_constructible<gsl::span<int, 3>>"); +static_assert(std::is_nothrow_copy_constructible<gsl::span<const int>>::value, + "std::is_nothrow_copy_constructible<gsl::span<const int>>"); +static_assert(std::is_nothrow_copy_constructible<gsl::span<const int, 3>>::value, + "std::is_nothrow_copy_constructible<gsl::span<const int, 3>>"); + +// no throw copy assignment +static_assert(std::is_nothrow_copy_assignable<gsl::span<int>>::value, + "std::is_nothrow_copy_assignable<gsl::span<int>>"); +static_assert(std::is_nothrow_copy_assignable<gsl::span<int, 3>>::value, + "std::is_nothrow_copy_assignable<gsl::span<int, 3>>"); +static_assert(std::is_nothrow_copy_assignable<gsl::span<const int>>::value, + "std::is_nothrow_copy_assignable<gsl::span<const int>>"); +static_assert(std::is_nothrow_copy_assignable<gsl::span<const int, 3>>::value, + "std::is_nothrow_copy_assignable<gsl::span<const int, 3>>"); + +// no throw destruction +static_assert(std::is_nothrow_destructible<gsl::span<int>>::value, + "std::is_nothrow_destructible<gsl::span<int>>"); +static_assert(std::is_nothrow_destructible<gsl::span<int, 3>>::value, + "std::is_nothrow_destructible<gsl::span<int, 3>>"); +static_assert(std::is_nothrow_destructible<gsl::span<const int>>::value, + "std::is_nothrow_destructible<gsl::span<const int>>"); + +// conversions +static_assert(std::is_convertible<int (&)[3], gsl::span<int>>::value, + "std::is_convertible<int(&)[3], gsl::span<int>>"); +static_assert(std::is_convertible<int (&)[3], gsl::span<int, 3>>::value, + "std::is_convertible<int(&)[3], gsl::span<int, 3>>"); +static_assert(std::is_convertible<int (&)[3], gsl::span<const int>>::value, + "std::is_convertible<int(&)[3], gsl::span<const int>>"); + +static_assert(std::is_convertible<const int (&)[3], gsl::span<const int>>::value, + "std::is_convertible<const int(&)[3], gsl::span<const int>>"); + +static_assert(std::is_convertible<const gsl::span<int>&, gsl::span<int>>::value, + "std::is_convertible<const gsl::span<int>&, gsl::span<int>>"); +static_assert(std::is_convertible<const gsl::span<int>&, gsl::span<const int>>::value, + "std::is_convertible<const gsl::span<int>&, gsl::span<const int>>"); + +static_assert(std::is_convertible<const gsl::span<int, 3>&, gsl::span<int>>::value, + "std::is_convertible<const gsl::span<int, 3>&, gsl::span<int>>"); +static_assert(std::is_convertible<const gsl::span<int, 3>&, gsl::span<int, 3>>::value, + "std::is_convertible<const gsl::span<int, 3>&, gsl::span<int, 3>>"); +static_assert(std::is_convertible<const gsl::span<int, 3>&, gsl::span<const int>>::value, + "std::is_convertible<const gsl::span<int, 3>&, gsl::span<const int>>"); +static_assert(std::is_convertible<const gsl::span<int, 3>&, gsl::span<const int, 3>>::value, + "std::is_convertible<const gsl::span<int, 3>&, gsl::span<const int, 3>>"); +static_assert(std::is_convertible<const gsl::span<int, 500>&, gsl::span<int>>::value, + "std::is_convertible<const gsl::span<int, 500>&, gsl::span<int>>"); +static_assert(std::is_convertible<const gsl::span<int, 500>&, gsl::span<const int>>::value, + "std::is_convertible<const gsl::span<int, 500>&, gsl::span<const int>>"); + +static_assert(std::is_convertible<const gsl::span<const int>&, gsl::span<const int>>::value, + "std::is_convertible<const gsl::span<const int>&, gsl::span<const int>>"); + +static_assert(std::is_convertible<const gsl::span<const int, 3>&, gsl::span<const int>>::value, + "std::is_convertible<const gsl::span<const int, 3>&, gsl::span<const int>>"); +static_assert(std::is_convertible<const gsl::span<const int, 3>&, gsl::span<const int, 3>>::value, + "std::is_convertible<const gsl::span<const int, 3>&, gsl::span<const int, 3>>"); +static_assert(std::is_convertible<const gsl::span<const int, 500>&, gsl::span<const int>>::value, + "std::is_convertible<const gsl::span<const int, 500>&, gsl::span<const int>>"); + +static_assert(std::is_convertible<std::array<int, 3>&, gsl::span<int>>::value, + "std::is_convertible<std::array<int, 3>&, gsl::span<int>>"); +static_assert(std::is_convertible<std::array<int, 3>&, gsl::span<int, 3>>::value, + "std::is_convertible<std::array<int, 3>&, gsl::span<int, 3>>"); +static_assert(std::is_convertible<std::array<int, 3>&, gsl::span<const int>>::value, + "std::is_convertible<std::array<int, 3>&, gsl::span<const int>>"); + +static_assert(std::is_convertible<const std::array<int, 3>&, gsl::span<const int>>::value, + "std::is_convertible<const std::array<int, 3>&, gsl::span<const int>>"); + + +#if __cplusplus >= 201703l +template <typename U, typename = void> +static constexpr bool AsWritableBytesCompilesFor = false; + +template <typename U> +static constexpr bool AsWritableBytesCompilesFor<U, void_t<decltype(as_writable_bytes(declval<U>()))>> = + true; + +static_assert(AsWritableBytesCompilesFor<gsl::span<int>>, + "AsWritableBytesCompilesFor<gsl::span<int>>"); +static_assert(AsWritableBytesCompilesFor<gsl::span<int, 9>>, + "AsWritableBytesCompilesFor<gsl::span<int, 9>>"); +static_assert(!AsWritableBytesCompilesFor<gsl::span<const int>>, + "!AsWritableBytesCompilesFor<gsl::span<const int>>"); +static_assert(!AsWritableBytesCompilesFor<gsl::span<const int, 9>>, + "!AsWritableBytesCompilesFor<gsl::span<const int, 9>>"); +#endif // __cplusplus >= 201703l diff --git a/tests/span_ext_tests.cpp b/tests/span_ext_tests.cpp new file mode 100644 index 0000000..bd256a8 --- /dev/null +++ b/tests/span_ext_tests.cpp @@ -0,0 +1,360 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <gtest/gtest.h> + +#include <gsl/gsl_util> // for narrow_cast, at +#include <gsl/span_ext> // for operator==, operator!=, make_span + +#include <array> // for array +#include <iostream> // for cerr +#include <vector> // for vector + +using namespace std; +using namespace gsl; + +namespace +{ +static constexpr char deathstring[] = "Expected Death"; +} // namespace + +TEST(span_ext_test, make_span_from_pointer_length_constructor) +{ + std::set_terminate([] { + std::cerr << "Expected Death. from_pointer_length_constructor"; + std::abort(); + }); + int arr[4] = {1, 2, 3, 4}; + + { + auto s = make_span(&arr[0], 2); + EXPECT_TRUE(s.size() == 2); + EXPECT_TRUE(s.data() == &arr[0]); + EXPECT_TRUE(s[0] == 1); + EXPECT_TRUE(s[1] == 2); + } + + { + int* p = nullptr; + auto s = make_span(p, narrow_cast<span<int>::size_type>(0)); + EXPECT_TRUE(s.size() == 0); + EXPECT_TRUE(s.data() == nullptr); + } + + { + int* p = nullptr; + auto workaround_macro = [=]() { make_span(p, 2); }; + EXPECT_DEATH(workaround_macro(), deathstring); + } +} + +TEST(span_ext_test, make_span_from_pointer_pointer_construction) +{ + int arr[4] = {1, 2, 3, 4}; + + { + auto s = make_span(&arr[0], &arr[2]); + EXPECT_TRUE(s.size() == 2); + EXPECT_TRUE(s.data() == &arr[0]); + EXPECT_TRUE(s[0] == 1); + EXPECT_TRUE(s[1] == 2); + } + + { + auto s = make_span(&arr[0], &arr[0]); + EXPECT_TRUE(s.size() == 0); + EXPECT_TRUE(s.data() == &arr[0]); + } + + { + int* p = nullptr; + auto s = make_span(p, p); + EXPECT_TRUE(s.size() == 0); + EXPECT_TRUE(s.data() == nullptr); + } +} + +TEST(span_ext_test, make_span_from_array_constructor) + { + int arr[5] = {1, 2, 3, 4, 5}; + int arr2d[2][3] = {1, 2, 3, 4, 5, 6}; + int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + + { + const auto s = make_span(arr); + EXPECT_TRUE(s.size() == 5); + EXPECT_TRUE(s.data() == std::addressof(arr[0])); + } + + { + const auto s = make_span(std::addressof(arr2d[0]), 1); + EXPECT_TRUE(s.size() == 1); + EXPECT_TRUE(s.data() == std::addressof(arr2d[0])); + } + + { + const auto s = make_span(std::addressof(arr3d[0]), 1); + EXPECT_TRUE(s.size() == 1); + EXPECT_TRUE(s.data() == std::addressof(arr3d[0])); + } + } + + TEST(span_ext_test, make_span_from_dynamic_array_constructor) + { + double(*arr)[3][4] = new double[100][3][4]; + + { + auto s = make_span(&arr[0][0][0], 10); + EXPECT_TRUE(s.size() == 10); + EXPECT_TRUE(s.data() == &arr[0][0][0]); + } + + delete[] arr; + } + + TEST(span_ext_test, make_span_from_std_array_constructor) + { + std::array<int, 4> arr = {1, 2, 3, 4}; + + { + auto s = make_span(arr); + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); + } + + // This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590 + { + span<int> s1 = make_span(arr); + + static span<int> s2; + s2 = s1; + + #if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \ + __GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__) + // Known to be broken in gcc 6.4 and 6.5 with optimizations + // Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116 + EXPECT_TRUE(s1.size() == 4); + EXPECT_TRUE(s2.size() == 0); + #else + EXPECT_TRUE(s1.size() == s2.size()); + #endif + } + } + + TEST(span_ext_test, make_span_from_const_std_array_constructor) + { + const std::array<int, 4> arr = {1, 2, 3, 4}; + + { + auto s = make_span(arr); + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); + } + } + + TEST(span_ext_test, make_span_from_std_array_const_constructor) + { + std::array<const int, 4> arr = {1, 2, 3, 4}; + + { + auto s = make_span(arr); + EXPECT_TRUE(s.size() == arr.size()); + EXPECT_TRUE(s.data() == arr.data()); + } + } + + TEST(span_ext_test, make_span_from_container_constructor) + { + std::vector<int> v = {1, 2, 3}; + const std::vector<int> cv = v; + + { + auto s = make_span(v); + EXPECT_TRUE(s.size() == v.size()); + EXPECT_TRUE(s.data() == v.data()); + + auto cs = make_span(cv); + EXPECT_TRUE(cs.size() == cv.size()); + EXPECT_TRUE(cs.data() == cv.data()); + } + } + + TEST(span_test, interop_with_gsl_at) + { + int arr[5] = {1, 2, 3, 4, 5}; + span<int> s{arr}; + EXPECT_TRUE(at(s, 0) == 1); + EXPECT_TRUE(at(s, 1) == 2); + } + + TEST(span_ext_test, iterator_free_functions) + { + int a[] = {1, 2, 3, 4}; + span<int> s{a}; + + EXPECT_TRUE((std::is_same<decltype(s.begin()), decltype(begin(s))>::value)); + EXPECT_TRUE((std::is_same<decltype(s.end()), decltype(end(s))>::value)); + + EXPECT_TRUE((std::is_same<decltype(s.cbegin()), decltype(cbegin(s))>::value)); + EXPECT_TRUE((std::is_same<decltype(s.cend()), decltype(cend(s))>::value)); + + EXPECT_TRUE((std::is_same<decltype(s.rbegin()), decltype(rbegin(s))>::value)); + EXPECT_TRUE((std::is_same<decltype(s.rend()), decltype(rend(s))>::value)); + + EXPECT_TRUE((std::is_same<decltype(s.crbegin()), decltype(crbegin(s))>::value)); + EXPECT_TRUE((std::is_same<decltype(s.crend()), decltype(crend(s))>::value)); + + EXPECT_TRUE(s.begin() == begin(s)); + EXPECT_TRUE(s.end() == end(s)); + + EXPECT_TRUE(s.cbegin() == cbegin(s)); + EXPECT_TRUE(s.cend() == cend(s)); + + EXPECT_TRUE(s.rbegin() == rbegin(s)); + EXPECT_TRUE(s.rend() == rend(s)); + + EXPECT_TRUE(s.crbegin() == crbegin(s)); + EXPECT_TRUE(s.crend() == crend(s)); + } + + TEST(span_ext_test, ssize_free_function) + { + int a[] = {1, 2, 3, 4}; + span<int> s{a}; + + EXPECT_FALSE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value)); + EXPECT_TRUE(s.size() == static_cast<std::size_t>(ssize(s))); + } + + TEST(span_ext_test, comparison_operators) + { + { + span<int> s1; + span<int> s2; + EXPECT_TRUE(s1 == s2); + EXPECT_FALSE(s1 != s2); + EXPECT_FALSE(s1 < s2); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s1 >= s2); + EXPECT_TRUE(s2 == s1); + EXPECT_FALSE(s2 != s1); + EXPECT_FALSE(s2 != s1); + EXPECT_TRUE(s2 <= s1); + EXPECT_FALSE(s2 > s1); + EXPECT_TRUE(s2 >= s1); + } + + { + int arr[] = {2, 1}; + span<int> s1 = arr; + span<int> s2 = arr; + + EXPECT_TRUE(s1 == s2); + EXPECT_FALSE(s1 != s2); + EXPECT_FALSE(s1 < s2); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s1 >= s2); + EXPECT_TRUE(s2 == s1); + EXPECT_FALSE(s2 != s1); + EXPECT_FALSE(s2 < s1); + EXPECT_TRUE(s2 <= s1); + EXPECT_FALSE(s2 > s1); + EXPECT_TRUE(s2 >= s1); + } + + { + int arr[] = {2, 1}; // bigger + + span<int> s1; + span<int> s2 = arr; + + EXPECT_TRUE(s1 != s2); + EXPECT_TRUE(s2 != s1); + EXPECT_FALSE(s1 == s2); + EXPECT_FALSE(s2 == s1); + EXPECT_TRUE(s1 < s2); + EXPECT_FALSE(s2 < s1); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s2 <= s1); + EXPECT_TRUE(s2 > s1); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s2 >= s1); + EXPECT_FALSE(s1 >= s2); + } + + { + int arr1[] = {1, 2}; + int arr2[] = {1, 2}; + span<int> s1 = arr1; + span<int> s2 = arr2; + + EXPECT_TRUE(s1 == s2); + EXPECT_FALSE(s1 != s2); + EXPECT_FALSE(s1 < s2); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s1 >= s2); + EXPECT_TRUE(s2 == s1); + EXPECT_FALSE(s2 != s1); + EXPECT_FALSE(s2 < s1); + EXPECT_TRUE(s2 <= s1); + EXPECT_FALSE(s2 > s1); + EXPECT_TRUE(s2 >= s1); + } + + { + int arr[] = {1, 2, 3}; + + span<int> s1 = {&arr[0], 2}; // shorter + span<int> s2 = arr; // longer + + EXPECT_TRUE(s1 != s2); + EXPECT_TRUE(s2 != s1); + EXPECT_FALSE(s1 == s2); + EXPECT_FALSE(s2 == s1); + EXPECT_TRUE(s1 < s2); + EXPECT_FALSE(s2 < s1); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s2 <= s1); + EXPECT_TRUE(s2 > s1); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s2 >= s1); + EXPECT_FALSE(s1 >= s2); + } + + { + int arr1[] = {1, 2}; // smaller + int arr2[] = {2, 1}; // bigger + + span<int> s1 = arr1; + span<int> s2 = arr2; + + EXPECT_TRUE(s1 != s2); + EXPECT_TRUE(s2 != s1); + EXPECT_FALSE(s1 == s2); + EXPECT_FALSE(s2 == s1); + EXPECT_TRUE(s1 < s2); + EXPECT_FALSE(s2 < s1); + EXPECT_TRUE(s1 <= s2); + EXPECT_FALSE(s2 <= s1); + EXPECT_TRUE(s2 > s1); + EXPECT_FALSE(s1 > s2); + EXPECT_TRUE(s2 >= s1); + EXPECT_FALSE(s1 >= s2); + } + } diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 28c97f5..689fff9 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -14,27 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426 26497 4189 4996) -#endif - -#if __clang__ || __GNUC__ -//disable warnings from gtest -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wundef" -#pragma GCC diagnostic ignored "-Wunused-variable" -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/gsl_byte> // for byte @@ -46,15 +25,11 @@ #include <iterator> // for reverse_iterator, operator-, operator== #include <memory> // for unique_ptr, shared_ptr, make_unique, allo... #include <regex> // for match_results, sub_match, match_results<>... -#include <stddef.h> // for ptrdiff_t +#include <cstddef> // for ptrdiff_t #include <string> // for string #include <type_traits> // for integral_constant<>::value, is_default_co... #include <vector> // for vector - -namespace gsl -{ -struct fail_fast; -} // namespace gsl +#include <utility> using namespace std; using namespace gsl; @@ -131,17 +106,17 @@ TEST(span_test, from_nullptr_size_constructor) std::abort(); }); { - span<int> s{nullptr, narrow_cast<span<int>::index_type>(0)}; + span<int> s{nullptr, narrow_cast<span<int>::size_type>(0)}; EXPECT_TRUE(s.size() == 0); EXPECT_TRUE(s.data() == nullptr); - span<int> cs{nullptr, narrow_cast<span<int>::index_type>(0)}; + span<int> cs{nullptr, narrow_cast<span<int>::size_type>(0)}; EXPECT_TRUE(cs.size() == 0); EXPECT_TRUE(cs.data() == nullptr); } { auto workaround_macro = []() { - const span<int, 1> s{nullptr, narrow_cast<span<int>::index_type>(0)}; + const span<int, 1> s{nullptr, narrow_cast<span<int>::size_type>(0)}; }; EXPECT_DEATH(workaround_macro(), deathstring); } @@ -160,11 +135,11 @@ TEST(span_test, from_nullptr_size_constructor) EXPECT_DEATH(const_workaround_macro(), deathstring); } { - span<int*> s{nullptr, narrow_cast<span<int>::index_type>(0)}; + span<int*> s{nullptr, narrow_cast<span<int>::size_type>(0)}; EXPECT_TRUE(s.size() == 0); EXPECT_TRUE(s.data() == nullptr); - span<const int*> cs{nullptr, narrow_cast<span<int>::index_type>(0)}; + span<const int*> cs{nullptr, narrow_cast<span<int>::size_type>(0)}; EXPECT_TRUE(cs.size() == 0); EXPECT_TRUE(cs.data() == nullptr); } @@ -182,29 +157,21 @@ TEST(span_test, from_pointer_length_constructor) for (int i = 0; i < 4; ++i) { { - span<int> s = {&arr[0], i}; - EXPECT_TRUE(s.size() == i); + span<int> s = {&arr[0], narrow_cast<std::size_t>(i)}; + EXPECT_TRUE(s.size() == narrow_cast<std::size_t>(i)); EXPECT_TRUE(s.data() == &arr[0]); EXPECT_TRUE(s.empty() == (i == 0)); for (int j = 0; j < i; ++j) - { - EXPECT_TRUE(arr[j] == s[j]); - EXPECT_TRUE(arr[j] == s.at(j)); - EXPECT_TRUE(arr[j] == s(j)); - } + EXPECT_TRUE(arr[j] == s[narrow_cast<std::size_t>(j)]); } { - span<int> s = {&arr[i], 4 - narrow_cast<ptrdiff_t>(i)}; - EXPECT_TRUE(s.size() == 4 - i); + span<int> s = {&arr[i], 4 - narrow_cast<std::size_t>(i)}; + EXPECT_TRUE(s.size() == 4 - narrow_cast<std::size_t>(i)); EXPECT_TRUE(s.data() == &arr[i]); EXPECT_TRUE(s.empty() == ((4 - i) == 0)); for (int j = 0; j < 4 - i; ++j) - { - EXPECT_TRUE(arr[j + i] == s[j]); - EXPECT_TRUE(arr[j + i] == s.at(j)); - EXPECT_TRUE(arr[j + i] == s(j)); - } + EXPECT_TRUE(arr[j + i] == s[narrow_cast<std::size_t>(j)]); } } } @@ -219,7 +186,7 @@ TEST(span_test, from_pointer_length_constructor) { int* p = nullptr; - span<int> s{p, narrow_cast<span<int>::index_type>(0)}; + span<int> s{p, narrow_cast<span<int>::size_type>(0)}; EXPECT_TRUE(s.size() == 0); EXPECT_TRUE(s.data() == nullptr); } @@ -229,27 +196,6 @@ TEST(span_test, from_pointer_length_constructor) auto workaround_macro = [=]() { const span<int> s{p, 2}; }; EXPECT_DEATH(workaround_macro(), deathstring); } - - { - auto s = make_span(&arr[0], 2); - EXPECT_TRUE(s.size() == 2); - EXPECT_TRUE(s.data() == &arr[0]); - EXPECT_TRUE(s[0] == 1); - EXPECT_TRUE(s[1] == 2); - } - - { - int* p = nullptr; - auto s = make_span(p, narrow_cast<span<int>::index_type>(0)); - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == nullptr); - } - - { - int* p = nullptr; - auto workaround_macro = [=]() { make_span(p, 2); }; - EXPECT_DEATH(workaround_macro(), deathstring); - } } TEST(span_test, from_pointer_pointer_construction) @@ -316,27 +262,6 @@ TEST(span_test, from_pointer_pointer_construction) // auto workaround_macro = [&]() { span<int> s{&arr[0], p}; }; // EXPECT_DEATH(workaround_macro(), deathstring); //} - - { - auto s = make_span(&arr[0], &arr[2]); - EXPECT_TRUE(s.size() == 2); - EXPECT_TRUE(s.data() == &arr[0]); - EXPECT_TRUE(s[0] == 1); - EXPECT_TRUE(s[1] == 2); - } - - { - auto s = make_span(&arr[0], &arr[0]); - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == &arr[0]); - } - - { - int* p = nullptr; - auto s = make_span(p, p); - EXPECT_TRUE(s.size() == 0); - EXPECT_TRUE(s.data() == nullptr); - } } TEST(span_test, from_array_constructor) @@ -426,24 +351,6 @@ TEST(span_test, from_array_constructor) EXPECT_TRUE(s.size() == 1); } - { - const auto s = make_span(arr); - EXPECT_TRUE(s.size() == 5); - EXPECT_TRUE(s.data() == std::addressof(arr[0])); - } - - { - const auto s = make_span(std::addressof(arr2d[0]), 1); - EXPECT_TRUE(s.size() == 1); - EXPECT_TRUE(s.data() == std::addressof(arr2d[0])); - } - - { - const auto s = make_span(std::addressof(arr3d[0]), 1); - EXPECT_TRUE(s.size() == 1); - EXPECT_TRUE(s.data() == std::addressof(arr3d[0])); - } - AddressOverloaded ao_arr[5] = {}; { @@ -463,12 +370,6 @@ TEST(span_test, from_array_constructor) EXPECT_TRUE(s.data() == &arr[0][0][0]); } - { - auto s = make_span(&arr[0][0][0], 10); - EXPECT_TRUE(s.size() == 10); - EXPECT_TRUE(s.data() == &arr[0][0][0]); - } - delete[] arr; } @@ -478,21 +379,21 @@ TEST(span_test, from_array_constructor) { span<int> s{arr}; - EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); + EXPECT_TRUE(s.size() == arr.size()); EXPECT_TRUE(s.data() == arr.data()); span<const int> cs{arr}; - EXPECT_TRUE(cs.size() == narrow_cast<ptrdiff_t>(arr.size())); + EXPECT_TRUE(cs.size() == arr.size()); EXPECT_TRUE(cs.data() == arr.data()); } { span<int, 4> s{arr}; - EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); + EXPECT_TRUE(s.size() == arr.size()); EXPECT_TRUE(s.data() == arr.data()); span<const int, 4> cs{arr}; - EXPECT_TRUE(cs.size() == narrow_cast<ptrdiff_t>(arr.size())); + EXPECT_TRUE(cs.size() == arr.size()); EXPECT_TRUE(cs.data() == arr.data()); } @@ -507,7 +408,7 @@ TEST(span_test, from_array_constructor) { span<AddressOverloaded, 4> fs{ao_arr}; - EXPECT_TRUE(fs.size() == narrow_cast<ptrdiff_t>(ao_arr.size())); + EXPECT_TRUE(fs.size() == ao_arr.size()); EXPECT_TRUE(ao_arr.data() == fs.data()); } @@ -550,30 +451,6 @@ TEST(span_test, from_array_constructor) // try to take a temporary std::array take_a_span(get_an_array()); } - - { - auto s = make_span(arr); - EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); - EXPECT_TRUE(s.data() == arr.data()); - } - - // This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590 - { - span<int> s1 = make_span(arr); - - static span<int> s2; - s2 = s1; - - #if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \ - __GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__) - // Known to be broken in gcc 6.4 and 6.5 with optimizations - // Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116 - EXPECT_TRUE(s1.size() == 4); - EXPECT_TRUE(s2.size() == 0); - #else - EXPECT_TRUE(s1.size() == s2.size()); - #endif - } } TEST(span_test, from_const_std_array_constructor) @@ -582,13 +459,13 @@ TEST(span_test, from_array_constructor) { span<const int> s{arr}; - EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); + EXPECT_TRUE(s.size() == arr.size()); EXPECT_TRUE(s.data() == arr.data()); } { span<const int, 4> s{arr}; - EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); + EXPECT_TRUE(s.size() == arr.size()); EXPECT_TRUE(s.data() == arr.data()); } @@ -596,7 +473,7 @@ TEST(span_test, from_array_constructor) { span<const AddressOverloaded, 4> s{ao_arr}; - EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(ao_arr.size())); + EXPECT_TRUE(s.size() == ao_arr.size()); EXPECT_TRUE(s.data() == ao_arr.data()); } @@ -624,12 +501,6 @@ TEST(span_test, from_array_constructor) // try to take a temporary std::array take_a_span(get_an_array()); } - - { - auto s = make_span(arr); - EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); - EXPECT_TRUE(s.data() == arr.data()); - } } TEST(span_test, from_std_array_const_constructor) @@ -638,13 +509,13 @@ TEST(span_test, from_array_constructor) { span<const int> s{arr}; - EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); + EXPECT_TRUE(s.size() == arr.size()); EXPECT_TRUE(s.data() == arr.data()); } { span<const int, 4> s{arr}; - EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); + EXPECT_TRUE(s.size() == arr.size()); EXPECT_TRUE(s.data() == arr.data()); } @@ -669,12 +540,6 @@ TEST(span_test, from_array_constructor) span<int, 4> s{arr}; } #endif - - { - auto s = make_span(arr); - EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); - EXPECT_TRUE(s.data() == arr.data()); - } } TEST(span_test, from_container_constructor) @@ -684,11 +549,11 @@ TEST(span_test, from_array_constructor) { span<int> s{v}; - EXPECT_TRUE(s.size() == narrow_cast<std::ptrdiff_t>(v.size())); + EXPECT_TRUE(s.size() == v.size()); EXPECT_TRUE(s.data() == v.data()); span<const int> cs{v}; - EXPECT_TRUE(cs.size() == narrow_cast<std::ptrdiff_t>(v.size())); + EXPECT_TRUE(cs.size() == v.size()); EXPECT_TRUE(cs.data() == v.data()); } @@ -698,11 +563,11 @@ TEST(span_test, from_array_constructor) { #ifdef CONFIRM_COMPILATION_ERRORS span<char> s{str}; - EXPECT_TRUE(s.size() == narrow_cast<std::ptrdiff_t>(str.size())); + EXPECT_TRUE(s.size() == str.size()); EXPECT_TRUE(s.data() == str.data())); #endif span<const char> cs{str}; - EXPECT_TRUE(cs.size() == narrow_cast<std::ptrdiff_t>(str.size())); + EXPECT_TRUE(cs.size() == str.size()); EXPECT_TRUE(cs.data() == str.data()); } @@ -711,7 +576,7 @@ TEST(span_test, from_array_constructor) span<char> s{cstr}; #endif span<const char> cs{cstr}; - EXPECT_TRUE(cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size())); + EXPECT_TRUE(cs.size() == cstr.size()); EXPECT_TRUE(cs.data() == cstr.data()); } @@ -763,16 +628,6 @@ TEST(span_test, from_array_constructor) span<int> s{m}; #endif } - - { - auto s = make_span(v); - EXPECT_TRUE(s.size() == narrow_cast<std::ptrdiff_t>(v.size())); - EXPECT_TRUE(s.data() == v.data()); - - auto cs = make_span(cv); - EXPECT_TRUE(cs.size() == narrow_cast<std::ptrdiff_t>(cv.size())); - EXPECT_TRUE(cs.data() == cv.data()); - } } TEST(span_test, from_convertible_span_constructor){{span<DerivedClass> avd; @@ -987,7 +842,7 @@ TEST(span_test, from_array_constructor) EXPECT_TRUE(av.subspan(5).size() == 0); EXPECT_DEATH(av.subspan(6).size(), deathstring); const auto av2 = av.subspan(1); - for (int i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == i + 2); + for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2); } { @@ -998,53 +853,7 @@ TEST(span_test, from_array_constructor) EXPECT_TRUE(av.subspan(5).size() == 0); EXPECT_DEATH(av.subspan(6).size(), deathstring); const auto av2 = av.subspan(1); - for (int i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == i + 2); - } - } - - TEST(span_test, at_call) - { - std::set_terminate([] { - std::cerr << "Expected Death. at_call"; - std::abort(); - }); - int arr[4] = {1, 2, 3, 4}; - - { - span<int> s = arr; - EXPECT_TRUE(s.at(0) == 1); - EXPECT_DEATH(s.at(5), deathstring); - } - - { - int arr2d[2] = {1, 6}; - span<int, 2> s = arr2d; - EXPECT_TRUE(s.at(0) == 1); - EXPECT_TRUE(s.at(1) == 6); - EXPECT_DEATH(s.at(2), deathstring); - } - } - - TEST(span_test, operator_function_call) - { - std::set_terminate([] { - std::cerr << "Expected Death. operator_function_call"; - std::abort(); - }); - int arr[4] = {1, 2, 3, 4}; - - { - span<int> s = arr; - EXPECT_TRUE(s(0) == 1); - EXPECT_DEATH(s(5), deathstring); - } - - { - int arr2d[2] = {1, 6}; - span<int, 2> s = arr2d; - EXPECT_TRUE(s(0) == 1); - EXPECT_TRUE(s(1) == 6); - EXPECT_DEATH(s(2), deathstring); + for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2); } } @@ -1083,46 +892,6 @@ TEST(span_test, from_array_constructor) span<int>::const_iterator cit3 = it + 4; EXPECT_TRUE(cit3 == s.cend()); } - - TEST(span_test, iterator_free_functions) - { - int a[] = {1, 2, 3, 4}; - span<int> s{a}; - - EXPECT_TRUE((std::is_same<decltype(s.begin()), decltype(begin(s))>::value)); - EXPECT_TRUE((std::is_same<decltype(s.end()), decltype(end(s))>::value)); - - EXPECT_TRUE((std::is_same<decltype(s.cbegin()), decltype(cbegin(s))>::value)); - EXPECT_TRUE((std::is_same<decltype(s.cend()), decltype(cend(s))>::value)); - - EXPECT_TRUE((std::is_same<decltype(s.rbegin()), decltype(rbegin(s))>::value)); - EXPECT_TRUE((std::is_same<decltype(s.rend()), decltype(rend(s))>::value)); - - EXPECT_TRUE((std::is_same<decltype(s.crbegin()), decltype(crbegin(s))>::value)); - EXPECT_TRUE((std::is_same<decltype(s.crend()), decltype(crend(s))>::value)); - - EXPECT_TRUE(s.begin() == begin(s)); - EXPECT_TRUE(s.end() == end(s)); - - EXPECT_TRUE(s.cbegin() == cbegin(s)); - EXPECT_TRUE(s.cend() == cend(s)); - - EXPECT_TRUE(s.rbegin() == rbegin(s)); - EXPECT_TRUE(s.rend() == rend(s)); - - EXPECT_TRUE(s.crbegin() == crbegin(s)); - EXPECT_TRUE(s.crend() == crend(s)); - } - - TEST(span_test, ssize_free_function) - { - int a[] = {1, 2, 3, 4}; - span<int> s{a}; - - EXPECT_TRUE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value)); - EXPECT_TRUE(s.size() == ssize(s)); - } - TEST(span_test, iterator_comparisons) { int a[] = {1, 2, 3, 4}; @@ -1170,6 +939,28 @@ TEST(span_test, from_array_constructor) } } + TEST(span_test, incomparable_iterators) + { + std::set_terminate([] { + std::cerr << "Expected Death. incomparable_iterators"; + std::abort(); + }); + + int a[] = {1, 2, 3, 4}; + int b[] = {1, 2, 3, 4}; + { + span<int> s = a; + span<int> s2 = b; +#if (__cplusplus > 201402L) + EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() == s2.begin()), deathstring); + EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() <= s2.begin()), deathstring); +#else + EXPECT_DEATH(bool _ = (s.begin() == s2.begin()), deathstring); + EXPECT_DEATH(bool _ = (s.begin() <= s2.begin()), deathstring); +#endif + } + } + TEST(span_test, begin_end) { std::set_terminate([] { @@ -1302,7 +1093,11 @@ TEST(span_test, from_array_constructor) auto beyond = s.rend(); EXPECT_TRUE(it != beyond); - EXPECT_DEATH(auto _ = *beyond , deathstring); +#if (__cplusplus > 201402L) + EXPECT_DEATH([[maybe_unused]] auto _ = *beyond , deathstring); +#else + EXPECT_DEATH(auto _ = *beyond , deathstring); +#endif EXPECT_TRUE(beyond - first == 4); EXPECT_TRUE(first - first == 0); @@ -1347,7 +1142,11 @@ TEST(span_test, from_array_constructor) auto beyond = s.crend(); EXPECT_TRUE(it != beyond); - EXPECT_DEATH(auto _ = *beyond, deathstring); +#if (__cplusplus > 201402L) + EXPECT_DEATH([[maybe_unused]] auto _ = *beyond, deathstring); +#else + EXPECT_DEATH(auto _ = *beyond, deathstring); +#endif EXPECT_TRUE(beyond - first == 4); EXPECT_TRUE(first - first == 0); @@ -1375,130 +1174,14 @@ TEST(span_test, from_array_constructor) } } - TEST(span_test, comparison_operators) - { - { - span<int> s1; - span<int> s2; - EXPECT_TRUE(s1 == s2); - EXPECT_FALSE(s1 != s2); - EXPECT_FALSE(s1 < s2); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s1 >= s2); - EXPECT_TRUE(s2 == s1); - EXPECT_FALSE(s2 != s1); - EXPECT_FALSE(s2 != s1); - EXPECT_TRUE(s2 <= s1); - EXPECT_FALSE(s2 > s1); - EXPECT_TRUE(s2 >= s1); - } - - { - int arr[] = {2, 1}; - span<int> s1 = arr; - span<int> s2 = arr; - - EXPECT_TRUE(s1 == s2); - EXPECT_FALSE(s1 != s2); - EXPECT_FALSE(s1 < s2); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s1 >= s2); - EXPECT_TRUE(s2 == s1); - EXPECT_FALSE(s2 != s1); - EXPECT_FALSE(s2 < s1); - EXPECT_TRUE(s2 <= s1); - EXPECT_FALSE(s2 > s1); - EXPECT_TRUE(s2 >= s1); - } - - { - int arr[] = {2, 1}; // bigger - - span<int> s1; - span<int> s2 = arr; - - EXPECT_TRUE(s1 != s2); - EXPECT_TRUE(s2 != s1); - EXPECT_FALSE(s1 == s2); - EXPECT_FALSE(s2 == s1); - EXPECT_TRUE(s1 < s2); - EXPECT_FALSE(s2 < s1); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s2 <= s1); - EXPECT_TRUE(s2 > s1); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s2 >= s1); - EXPECT_FALSE(s1 >= s2); - } - - { - int arr1[] = {1, 2}; - int arr2[] = {1, 2}; - span<int> s1 = arr1; - span<int> s2 = arr2; - - EXPECT_TRUE(s1 == s2); - EXPECT_FALSE(s1 != s2); - EXPECT_FALSE(s1 < s2); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s1 >= s2); - EXPECT_TRUE(s2 == s1); - EXPECT_FALSE(s2 != s1); - EXPECT_FALSE(s2 < s1); - EXPECT_TRUE(s2 <= s1); - EXPECT_FALSE(s2 > s1); - EXPECT_TRUE(s2 >= s1); - } - - { - int arr[] = {1, 2, 3}; - - span<int> s1 = {&arr[0], 2}; // shorter - span<int> s2 = arr; // longer - - EXPECT_TRUE(s1 != s2); - EXPECT_TRUE(s2 != s1); - EXPECT_FALSE(s1 == s2); - EXPECT_FALSE(s2 == s1); - EXPECT_TRUE(s1 < s2); - EXPECT_FALSE(s2 < s1); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s2 <= s1); - EXPECT_TRUE(s2 > s1); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s2 >= s1); - EXPECT_FALSE(s1 >= s2); - } - - { - int arr1[] = {1, 2}; // smaller - int arr2[] = {2, 1}; // bigger - - span<int> s1 = arr1; - span<int> s2 = arr2; - - EXPECT_TRUE(s1 != s2); - EXPECT_TRUE(s2 != s1); - EXPECT_FALSE(s1 == s2); - EXPECT_FALSE(s2 == s1); - EXPECT_TRUE(s1 < s2); - EXPECT_FALSE(s2 < s1); - EXPECT_TRUE(s1 <= s2); - EXPECT_FALSE(s2 <= s1); - EXPECT_TRUE(s2 > s1); - EXPECT_FALSE(s1 > s2); - EXPECT_TRUE(s2 >= s1); - EXPECT_FALSE(s1 >= s2); - } - } - TEST(span_test, as_bytes) { - int a[] = {1, 2, 3, 4}; + std::set_terminate([] { + std::cerr << "Expected Death. as_bytes"; + std::abort(); + }); + int a[] = {1, 2, 3, 4}; { const span<const int> s = a; EXPECT_TRUE(s.size() == 4); @@ -1523,9 +1206,15 @@ TEST(span_test, from_array_constructor) EXPECT_TRUE(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data())); EXPECT_TRUE(bs.size() == s.size_bytes()); } + + int b[5] = {1, 2, 3, 4, 5}; + { + span<int> sp(begin(b), static_cast<size_t>(-2)); + EXPECT_DEATH((void) sp.size_bytes(), deathstring); + } } - TEST(span_test, as_writeable_bytes) + TEST(span_test, as_writable_bytes) { int a[] = {1, 2, 3, 4}; @@ -1534,7 +1223,7 @@ TEST(span_test, from_array_constructor) // you should not be able to get writeable bytes for const objects span<const int> s = a; EXPECT_TRUE(s.size() == 4); - span<const byte> bs = as_writeable_bytes(s); + span<const byte> bs = as_writable_bytes(s); EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data())); EXPECT_TRUE(bs.size() == s.size_bytes()); #endif @@ -1542,7 +1231,7 @@ TEST(span_test, from_array_constructor) { span<int> s; - const auto bs = as_writeable_bytes(s); + const auto bs = as_writable_bytes(s); EXPECT_TRUE(bs.size() == s.size()); EXPECT_TRUE(bs.size() == 0); EXPECT_TRUE(bs.size_bytes() == 0); @@ -1552,7 +1241,7 @@ TEST(span_test, from_array_constructor) { span<int> s = a; - const auto bs = as_writeable_bytes(s); + const auto bs = as_writable_bytes(s); EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data())); EXPECT_TRUE(bs.size() == s.size_bytes()); } @@ -1590,12 +1279,16 @@ TEST(span_test, from_array_constructor) // 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<int> s = arr; auto f = [&]() { const span<int, 2> s2 = s; static_cast<void>(s2); }; EXPECT_DEATH(f(), deathstring); + */ } // but doing so explicitly is ok @@ -1610,12 +1303,19 @@ TEST(span_test, from_array_constructor) static_cast<void>(s1); } - // ...or dynamically + /* + // this is not a legal operation in std::span, so we are no longer supporting it + // conversion from span<int, 4> to span<int, dynamic_extent> via call to `first` + // then convert from span<int, dynamic_extent> to span<int, 1> + // The dynamic to fixed extents are not supported in the standard + // to make this work, span<int, 1> would need to be span<int>. { + // NB: implicit conversion to span<int,1> from span<int> span<int, 1> s1 = s4.first(1); static_cast<void>(s1); } + */ // initialization or assignment to static span that requires size INCREASE is not ok. int arr2[2] = {1, 2}; @@ -1637,12 +1337,15 @@ TEST(span_test, from_array_constructor) EXPECT_DEATH(f(), deathstring); } + /* + // 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<int> av = arr2; auto f = [&]() { const span<int, 4> _s4 = av; static_cast<void>(_s4); }; EXPECT_DEATH(f(), deathstring); + */ } TEST(span_test, interop_with_std_regex) @@ -1668,14 +1371,6 @@ TEST(span_test, from_array_constructor) EXPECT_TRUE(match[0].second == (f_it + 1)); } - TEST(span_test, interop_with_gsl_at) - { - int arr[5] = {1, 2, 3, 4, 5}; - span<int> s{arr}; - EXPECT_TRUE(at(s, 0) == 1); - EXPECT_TRUE(at(s, 1) == 2); - } - TEST(span_test, default_constructible) { EXPECT_TRUE((std::is_default_constructible<span<int>>::value)); @@ -1698,7 +1393,3 @@ TEST(span_test, from_array_constructor) EXPECT_DEATH(s2.front(), deathstring); EXPECT_DEATH(s2.back(), deathstring); } - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/strict_notnull_tests.cpp b/tests/strict_notnull_tests.cpp index 3c971db..3cf6911 100644 --- a/tests/strict_notnull_tests.cpp +++ b/tests/strict_notnull_tests.cpp @@ -14,28 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch - -// Fix VS2015 build breaks in Release -#pragma warning(disable : 4702) // unreachable code -#endif - -#if __clang__ || __GNUC__ -//disable warnings from gtest -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/pointers> // for not_null, operator<, operator<=, operator> @@ -210,10 +188,3 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction) #endif } #endif // #if defined(__cplusplus) && (__cplusplus >= 201703L) - -static_assert(std::is_nothrow_move_constructible<strict_not_null<void*>>::value, - "strict_not_null must be no-throw move constructible"); - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/strided_span_tests.cpp b/tests/strided_span_tests.cpp index f5f3704..5a18f1b 100644 --- a/tests/strided_span_tests.cpp +++ b/tests/strided_span_tests.cpp @@ -14,28 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch deprecated -#pragma warning(disable : 4996) // strided_span is in the process of being deprecated. - // Suppressing warnings until it is completely removed -#endif - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -//disable warnings from gtest -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/gsl_byte> // for byte #include <gsl/gsl_util> // for narrow_cast @@ -810,7 +788,3 @@ TEST(strided_span_tests, strided_span_conversion) i++; } } - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/string_span_tests.cpp b/tests/string_span_tests.cpp index 24bf140..7a9f7fb 100644 --- a/tests/string_span_tests.cpp +++ b/tests/string_span_tests.cpp @@ -14,26 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch - -#endif - -#if __clang__ || __GNUC__ -//disable warnings from gtest -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - #include <gtest/gtest.h> #include <gsl/gsl_assert> // for Expects, fail_fast (ptr only) @@ -104,7 +84,7 @@ czstring_span<> CreateTempName(string_span<> span) { Expects(span.size() > 1); - int last = 0; + std::size_t last = 0; if (span.size() > 4) { span[0] = 't'; span[1] = 'm'; @@ -121,7 +101,7 @@ cwzstring_span<> CreateTempNameW(wstring_span<> span) { Expects(span.size() > 1); - int last = 0; + std::size_t last = 0; if (span.size() > 4) { span[0] = L't'; span[1] = L'm'; @@ -138,7 +118,7 @@ cu16zstring_span<> CreateTempNameU16(u16string_span<> span) { Expects(span.size() > 1); - int last = 0; + std::size_t last = 0; if (span.size() > 4) { span[0] = u't'; span[1] = u'm'; @@ -155,7 +135,7 @@ cu32zstring_span<> CreateTempNameU32(u32string_span<> span) { Expects(span.size() > 1); - int last = 0; + std::size_t last = 0; if (span.size() > 4) { span[0] = U't'; span[1] = U'm'; @@ -183,14 +163,14 @@ TEST(string_span_tests, TestConstructFromStdString) { std::string s = "Hello there world"; cstring_span<> v = s; - EXPECT_TRUE(v.length() == static_cast<cstring_span<>::index_type>(s.length())); + EXPECT_TRUE(v.length() == static_cast<cstring_span<>::size_type>(s.length())); } TEST(string_span_tests, TestConstructFromStdVector) { std::vector<char> vec(5, 'h'); string_span<> v{vec}; - EXPECT_TRUE(v.length() == static_cast<string_span<>::index_type>(vec.size())); + EXPECT_TRUE(v.length() == static_cast<string_span<>::size_type>(vec.size())); } TEST(string_span_tests, TestStackArrayConstruction) @@ -252,7 +232,7 @@ TEST(string_span_tests, TestToString) char stack_string[] = "Hello"; cstring_span<> v = ensure_z(stack_string); auto s2 = gsl::to_string(v); - EXPECT_TRUE(static_cast<cstring_span<>::index_type>(s2.length()) == v.length()); + EXPECT_TRUE(static_cast<cstring_span<>::size_type>(s2.length()) == v.length()); EXPECT_TRUE(s2.length() == static_cast<size_t>(5)); } @@ -265,7 +245,7 @@ TEST(string_span_tests, TestToBasicString) 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); - EXPECT_TRUE(static_cast<cstring_span<>::index_type>(s2.length()) == v.length()); + EXPECT_TRUE(static_cast<cstring_span<>::size_type>(s2.length()) == v.length()); EXPECT_TRUE(s2.length() == static_cast<size_t>(5)); } @@ -1226,16 +1206,12 @@ TEST(string_span_tests, as_bytes) EXPECT_TRUE(bs.size() == s.size_bytes()); } -TEST(string_span_tests, as_writeable_bytes) +TEST(string_span_tests, as_writable_bytes) { wchar_t buf[]{L"qwerty"}; wzstring_span<> v(buf); const auto s = v.as_string_span(); - const auto bs = as_writeable_bytes(s); + const auto bs = as_writable_bytes(s); EXPECT_TRUE(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data())); EXPECT_TRUE(bs.size() == s.size_bytes()); } - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp index db6e8c5..f7f7ce3 100644 --- a/tests/utils_tests.cpp +++ b/tests/utils_tests.cpp @@ -14,27 +14,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch - -#endif - -#if __clang__ || __GNUC__ -//disable warnings from gtest -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wundef" -#endif // __clang__ || __GNUC__ - -#if __clang__ -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wused-but-marked-unused" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" -#endif // __clang__ - - #include <gtest/gtest.h> #include <gsl/gsl_util> // for narrow, finally, narrow_cast, narrowing_e... @@ -44,6 +23,7 @@ #include <limits> // for numeric_limits #include <stdint.h> // for uint32_t, int32_t #include <type_traits> // for is_same +#include <cstddef> // for std::ptrdiff_t using namespace gsl; @@ -154,7 +134,3 @@ TEST(utils_tests, narrow) #endif } - -#if __clang__ || __GNUC__ -#pragma GCC diagnostic pop -#endif // __clang__ || __GNUC__ |