From 574e0414854348735333dee459365edfe2e444ca Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 10 Mar 2023 17:45:39 +0000 Subject: [PATCH] #675 Compilation error in optional.h line 405 Changes for compatibility with C++20 Restore C++17 unit test compatibility --- .gitignore | 4 ++ include/etl/char_traits.h | 21 ++++++-- test/UnitTest++/Checks.h | 109 ++++++++++++++++++++++++++++++++++---- test/test_char_traits.cpp | 2 +- test/test_etl_traits.cpp | 6 +++ 5 files changed, 127 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index aa9a698f..23794b31 100644 --- a/.gitignore +++ b/.gitignore @@ -370,3 +370,7 @@ test/vs2022/random_pcg.csv test/vs2022/random_xorshift.csv test/vs2019/MSVC - No STL -O2 test/vs2022/Debug - No STL +test/vs2022/Debug MSVC C++20 +test/vs2022/Debug MSVC - Force C++03 +test/vs2022/Debug MSVC - No STL - Built-ins +test/vs2022/Debug MSVC - No STL - Force Built-ins diff --git a/include/etl/char_traits.h b/include/etl/char_traits.h index da3ed887..8f4261a6 100644 --- a/include/etl/char_traits.h +++ b/include/etl/char_traits.h @@ -65,6 +65,17 @@ namespace etl typedef char state_type; }; +#if ETL_USING_CPP20 + template<> struct char_traits_types + { + typedef char8_t char_type; + typedef unsigned int int_type; + typedef long long off_type; + typedef size_t pos_type; + typedef char state_type; + }; +#endif + template<> struct char_traits_types { typedef char16_t char_type; @@ -186,17 +197,17 @@ namespace etl { for (size_t i = 0UL; i < count; ++i) { - if (*s1 < *s2) + const char_type c1 = *s1++; + const char_type c2 = *s2++; + + if (c1 < c2) { return -1; } - else if (*s1 > *s2) + else if (c1 > c2) { return 1; } - - ++s1; - ++s2; } return 0; diff --git a/test/UnitTest++/Checks.h b/test/UnitTest++/Checks.h index 7fc1f38c..0cf552df 100644 --- a/test/UnitTest++/Checks.h +++ b/test/UnitTest++/Checks.h @@ -31,8 +31,14 @@ namespace UnitTest { return !value; } +#if __cplusplus >= 202002L template< typename Expected, typename Actual > - void CheckEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details) + std::enable_if_t>> || std::is_same_v>> || + + std::is_same_v>> || std::is_same_v>> || + std::is_same_v>> || std::is_same_v>> || + std::is_same_v>> || std::is_same_v>>), void> + CheckEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details) { if (!(expected == actual)) { @@ -43,6 +49,38 @@ namespace UnitTest { } } + template< typename Expected, typename Actual > + std::enable_if_t<(std::is_same_v>> || std::is_same_v>> || + std::is_same_v>> || std::is_same_v>> || + std::is_same_v>> || std::is_same_v>> || + std::is_same_v>> || std::is_same_v>>), void> + CheckEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details) + { + if (!(expected == actual)) + { + using int_type_expected = std::char_traits::int_type; + using int_type_actual = std::char_traits::int_type; + + UnitTest::MemoryOutStream stream; + stream << "Expected " << int_type_expected(expected) << " but was " << int_type_actual(actual); + + results.OnTestFailure(details, stream.GetText()); + } + } +#else + template< typename Expected, typename Actual > + void CheckEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details) + { + if (!(expected == actual)) + { + UnitTest::MemoryOutStream stream; + stream << "Expected " << expected << " but was " << actual; + + results.OnTestFailure(details, stream.GetText()); + } + } +#endif + template< typename Expected, typename Actual > void CheckEqualHex(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details) { @@ -106,11 +144,11 @@ namespace UnitTest { } } - +#if __cplusplus >= 202002L template< typename Expected, typename Actual > void CheckArrayEqual(TestResults& results, Expected const& expected, Actual const& actual, size_t const count, TestDetails const& details) - { + { bool equal = true; for (size_t i = 0; i < count; ++i) equal &= (expected[i] == actual[i]); @@ -121,19 +159,72 @@ namespace UnitTest { stream << "Expected [ "; - for (size_t expectedIndex = 0; expectedIndex < count; ++expectedIndex) - stream << expected[expectedIndex] << " "; + using expected_type = std::remove_cvref_t; + using actual_type = std::remove_cvref_t; - stream << "] but was [ "; + if constexpr (std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v) + { + using int_type_expected = std::char_traits::int_type; + using int_type_actual = std::char_traits::int_type; - for (size_t actualIndex = 0; actualIndex < count; ++actualIndex) - stream << actual[actualIndex] << " "; + for (size_t expectedIndex = 0; expectedIndex < count; ++expectedIndex) + stream << int_type_expected(expected[expectedIndex]) << " "; - stream << "]"; + stream << "] but was [ "; + + for (size_t actualIndex = 0; actualIndex < count; ++actualIndex) + stream << int_type_actual(actual[actualIndex]) << " "; + + stream << "]"; + } + else + { + for (size_t expectedIndex = 0; expectedIndex < count; ++expectedIndex) + stream << expected[expectedIndex] << " "; + + stream << "] but was [ "; + + for (size_t actualIndex = 0; actualIndex < count; ++actualIndex) + stream << actual[actualIndex] << " "; + + stream << "]"; + } results.OnTestFailure(details, stream.GetText()); } } +#else + template< typename Expected, typename Actual > + void CheckArrayEqual(TestResults& results, Expected const& expected, Actual const& actual, + size_t const count, TestDetails const& details) + { + bool equal = true; + for (size_t i = 0; i < count; ++i) + equal &= (expected[i] == actual[i]); + + if (!equal) + { + UnitTest::MemoryOutStream stream; + + stream << "Expected [ "; + + for (size_t expectedIndex = 0; expectedIndex < count; ++expectedIndex) + stream << expected[expectedIndex] << " "; + + stream << "] but was [ "; + + for (size_t actualIndex = 0; actualIndex < count; ++actualIndex) + stream << actual[actualIndex] << " "; + + stream << "]"; + + results.OnTestFailure(details, stream.GetText()); + } + } +#endif template< typename Expected, typename Actual, typename Tolerance > bool ArrayAreClose(Expected const& expected, Actual const& actual, size_t const count, Tolerance const& tolerance) diff --git a/test/test_char_traits.cpp b/test/test_char_traits.cpp index 7898db1b..283e0f80 100644 --- a/test/test_char_traits.cpp +++ b/test/test_char_traits.cpp @@ -136,7 +136,7 @@ namespace char_type* p_dst; char_traits::assign(r, c); - CHECK_EQUAL(r, 'B'); + CHECK_EQUAL(r, L'B'); CHECK(char_traits::eq(1, 1)); CHECK(!char_traits::eq(1, 2)); diff --git a/test/test_etl_traits.cpp b/test/test_etl_traits.cpp index f223626e..b8bfc248 100644 --- a/test/test_etl_traits.cpp +++ b/test/test_etl_traits.cpp @@ -81,7 +81,13 @@ namespace CHECK_EQUAL(ETL_VERSION_MINOR, etl::traits::version_minor); CHECK_EQUAL(ETL_VERSION_PATCH, etl::traits::version_patch); CHECK_EQUAL(ETL_VERSION_VALUE, etl::traits::version); +#if ETL_USING_CPP20 + CHECK_EQUAL(20, etl::traits::language_standard); +#elif ETL_USING_CPP17 CHECK_EQUAL(17, etl::traits::language_standard); +#elif ETL_USING_CPP14 + CHECK_EQUAL(14, etl::traits::language_standard); +#endif CHECK_ARRAY_EQUAL(ETL_VERSION, etl::traits::version_string, etl::strlen(ETL_VERSION)); CHECK_ARRAY_EQUAL(ETL_VERSION, etl::traits::version_wstring, etl::strlen(ETL_VERSION_W));