From 3a4af24ab780638763befde9f5e905114484e82a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 13 Aug 2022 12:15:41 +0100 Subject: [PATCH] Work in progress Added more CHECK macros Added bitset_fast class for bitsets that are the same size as an integral type --- include/etl/private/bitset_fast.h | 97 ++++++++++ include/etl/private/bitset_new.h | 307 ++++++++++++++++++++---------- test/UnitTest++/CheckMacros.h | 50 ++++- test/UnitTest++/Checks.h | 5 + test/test_bitset_new.cpp | 267 +++++++++++++++----------- test/vs2019/etl.vcxproj | 1 + test/vs2019/etl.vcxproj.filters | 3 + 7 files changed, 506 insertions(+), 224 deletions(-) create mode 100644 include/etl/private/bitset_fast.h diff --git a/include/etl/private/bitset_fast.h b/include/etl/private/bitset_fast.h new file mode 100644 index 00000000..ef23cb2e --- /dev/null +++ b/include/etl/private/bitset_fast.h @@ -0,0 +1,97 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. +******************************************************************************/ + +//*************************************************************************** +/// Optimised specialisations. +//*************************************************************************** + +namespace etl +{ + namespace private_bitset + { + template + class bitset_fast + { + public: + + enum + { + npos = etl::integral_limits::max + }; + + typedef TElement element_type; + + ETL_CONSTEXPR14 bitset_fast() + : data(static_cast(0)) + { + } + + ETL_CONSTEXPR14 bitset_fast(unsigned long long v) + : data(static_cast(v)) + { + } + + ETL_CONSTEXPR14 bitset_fast(const char* text) + : data(0) + { + } + + ETL_CONSTEXPR14 bitset_fast(const wchar_t* text) + : data(0) + { + } + + ETL_CONSTEXPR14 bitset_fast(const char16_t* text) + : data(0) + { + } + + ETL_CONSTEXPR14 bitset_fast(const char32_t* text) + : data(0) + { + } + + ETL_CONSTEXPR14 bitset_fast(const bitset_fast& other) + : data(other.data) + { + } + + template + ETL_CONSTEXPR14 T value() const + { + return T(data); + } + + private: + + element_type data; + }; + } +} diff --git a/include/etl/private/bitset_new.h b/include/etl/private/bitset_new.h index 2a406a6e..d3d642dc 100644 --- a/include/etl/private/bitset_new.h +++ b/include/etl/private/bitset_new.h @@ -51,6 +51,9 @@ SOFTWARE. #include "../span.h" #include "../string.h" +// Optimised vversions for when to bitset size equals the number of bits in an integral type. +#include "bitset_fast.h" + #include "minmax_push.h" #if defined(ETL_COMPILER_KEIL) @@ -621,86 +624,80 @@ namespace etl // // return *this; // } -// -// //************************************************************************* -// /// operator <<= -// //************************************************************************* -// ibitset& operator<<=(size_t shift) -// { -// if (shift >= Total_Bits) -// { -// reset(); -// } -// else if (Number_Of_Elements != 0UL) -// { -// // Just one element? -// if (Number_Of_Elements == 1UL) -// { -// pdata[0] <<= shift; -// } -// else if (shift == Bits_Per_Element) -// { -// etl::copy_backward(pdata, pdata + Number_Of_Elements - 1U, pdata + Number_Of_Elements); -// pdata[0] = 0; -// } -// else -// { -// // The place where the elements are split when shifting. -// const size_t split_position = Bits_Per_Element - (shift % Bits_Per_Element); -// -// // Where we are shifting from. -// int src_index = int(Number_Of_Elements - (shift / Bits_Per_Element) - 1U); -// -// // Where we are shifting to. -// int dst_index = int(Number_Of_Elements - 1U); -// -// // Shift control constants. -// const size_t lsb_shift = Bits_Per_Element - split_position; -// const size_t msb_shift = split_position; -// -// const element_type lsb_mask = element_type(etl::integral_limits::max >> (Bits_Per_Element - split_position)); -// const element_type msb_mask = etl::integral_limits::max - lsb_mask; -// const element_type lsb_shifted_mask = element_type(lsb_mask << lsb_shift); -// -// // First lsb. -// element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift); -// pdata[dst_index] = lsb; -// --src_index; -// -// // Now do the shifting. -// while (src_index >= 0) -// { -// // Shift msb. -// element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift); -// pdata[dst_index] = pdata[dst_index] | msb; -// --dst_index; -// -// // Shift lsb. -// element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift); -// pdata[dst_index] = lsb; -// --src_index; -// } -// -// // Clear the remaining bits. -// // First lsb. -// pdata[dst_index] &= lsb_shifted_mask; -// --dst_index; -// -// // The other remaining bytes on the right. -// while (dst_index >= 0) -// { -// pdata[dst_index] = 0; -// --dst_index; -// } -// } -// -// // Truncate any bits shifted to the left. -// clear_unused_bits_in_msb(); -// } -// -// return *this; -// } -// + + //************************************************************************* + /// operator <<= + //************************************************************************* + ETL_CONSTEXPR14 ibitset& shift_left_equals(pointer pdata, size_t number_of_elements, size_t total_bits, size_t shift) + { + if (shift == Bits_Per_Element) + { + etl::copy_backward(pdata, pdata + number_of_elements - 1U, pdata + number_of_elements); + pdata[0] = 0; + } + else if ((shift % Bits_Per_Element) == 0U) + { + size_t element_shift = shift / Bits_Per_Element; + etl::copy_backward(pdata, pdata + number_of_elements - element_shift, pdata + number_of_elements); + do + { + pdata[--element_shift] = 0U; + } while (element_shift > 0U); + } + else + { + // The place where the elements are split when shifting. + const size_t split_position = Bits_Per_Element - (shift % Bits_Per_Element); + + // Where we are shifting from. + int src_index = int(number_of_elements - (shift / Bits_Per_Element) - 1U); + + // Where we are shifting to. + int dst_index = int(number_of_elements - 1U); + + // Shift control constants. + const size_t lsb_shift = Bits_Per_Element - split_position; + const size_t msb_shift = split_position; + + const element_type lsb_mask = element_type(etl::integral_limits::max >> (Bits_Per_Element - split_position)); + const element_type msb_mask = etl::integral_limits::max - lsb_mask; + const element_type lsb_shifted_mask = element_type(lsb_mask << lsb_shift); + + // First lsb. + element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift); + pdata[dst_index] = lsb; + --src_index; + + // Now do the shifting. + while (src_index >= 0) + { + // Shift msb. + element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift); + pdata[dst_index] = pdata[dst_index] | msb; + --dst_index; + + // Shift lsb. + element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift); + pdata[dst_index] = lsb; + --src_index; + } + + // Clear the remaining bits. + // First lsb. + pdata[dst_index] &= lsb_shifted_mask; + --dst_index; + + // The other remaining bytes on the right. + while (dst_index >= 0) + { + pdata[dst_index] = 0; + --dst_index; + } + } + + return *this; + } + // //************************************************************************* // /// operator >>= // //************************************************************************* @@ -932,13 +929,51 @@ namespace etl //#endif }; + template + struct select_element_type; + + template + struct select_element_type + { + typedef typename etl::conditional::type>::type>::type>::type>::type type; + }; + + template + struct select_element_type + { + typedef typename etl::conditional::type>::type>::type>::type type; + }; + + template + struct select_element_type + { + typedef typename etl::conditional::type>::type>::type>::type type; + }; + template + struct select_element_type + { + typedef typename etl::conditional::type>::type>::type type; + }; + //************************************************************************* /// The class emulates an array of bool elements, but optimized for space allocation. /// Will accommodate any number of bits. ///\tparam Total_Bits The number of bits. ///\ingroup bitset //************************************************************************* - template + template ::type> class bitset : public etl::ibitset { public: @@ -1413,28 +1448,39 @@ namespace etl // // return temp; // } -// -// //************************************************************************* -// /// operator << -// //************************************************************************* -// bitset operator<<(size_t shift) const -// { -// etl::bitset temp(*this); -// -// temp <<= shift; -// -// return temp; -// } -// -// //************************************************************************* -// /// operator <<= -// //************************************************************************* -// bitset& operator<<=(size_t shift) -// { -// etl::ibitset::operator <<=(shift); -// return *this; -// } -// + + //************************************************************************* + /// operator << + //************************************************************************* + ETL_CONSTEXPR14 bitset operator<<(size_t shift) const + { + etl::bitset temp(*this); + + temp <<= shift; + + return temp; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator<<=(size_t shift) + { + if (shift >= Total_Bits) + { + reset(); + } + else + { + etl::ibitset::shift_left_equals(data, Number_Of_Elements, Total_Bits, shift); + + // Truncate any bits shifted to the left. + clear_unused_bits_in_msb(); + } + + return *this; + } + // //************************************************************************* // /// operator >> // //************************************************************************* @@ -1479,6 +1525,61 @@ namespace etl element_type data[Number_Of_Elements > 0U ? Number_Of_Elements : 1U]; }; + //*************************************************************************** + /// Specialisation for 0 bits. + //*************************************************************************** + template <> + class bitset<0U, void> + { + public: + + enum + { + npos = etl::integral_limits::max + }; + }; + + template <> + class bitset<8U, uint8_t> : public etl::private_bitset::bitset_fast<8U, uint8_t> + { + public: + + ETL_CONSTEXPR14 bitset() + : bitset_fast<8U, uint8_t>() + { + } + + ETL_CONSTEXPR14 bitset(unsigned long long v) + : bitset_fast<8U, uint8_t>(v) + { + } + + ETL_CONSTEXPR14 bitset(const char* text) + : bitset_fast<8U, uint8_t>(text) + { + } + + ETL_CONSTEXPR14 bitset(const wchar_t* text) + : bitset_fast<8U, uint8_t>(text) + { + } + + ETL_CONSTEXPR14 bitset(const char16_t* text) + : bitset_fast<8U, uint8_t>(text) + { + } + + ETL_CONSTEXPR14 bitset(const char32_t* text) + : bitset_fast<8U, uint8_t>(text) + { + } + + ETL_CONSTEXPR14 bitset(const bitset<8U, uint8_t>& other) + : bitset_fast<8U, uint8_t>(other) + { + } + }; + //*************************************************************************** /// operator & ///\ingroup bitset diff --git a/test/UnitTest++/CheckMacros.h b/test/UnitTest++/CheckMacros.h index bdb9e658..23a8dca9 100644 --- a/test/UnitTest++/CheckMacros.h +++ b/test/UnitTest++/CheckMacros.h @@ -33,6 +33,28 @@ }) \ UNITTEST_MULTILINE_MACRO_END +#define UNITTEST_CHECK_FALSE(value) \ + UNITTEST_MULTILINE_MACRO_BEGIN \ + UNITTEST_IMPL_TRY \ + ({ \ + if (!UnitTest::CheckFalse(value)) \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), #value); \ + }) \ + UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \ + UNITTEST_IMPL_CATCH (std::exception, e, \ + { \ + UnitTest::MemoryOutStream UnitTest_message; \ + UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK(" #value ")"; \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + UnitTest_message.GetText()); \ + }) \ + UNITTEST_IMPL_CATCH_ALL \ + ({ \ + UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ + "Unhandled exception in CHECK(" #value ")"); \ + }) \ + UNITTEST_MULTILINE_MACRO_END + #define UNITTEST_CHECK_EQUAL(expected, actual) \ UNITTEST_MULTILINE_MACRO_BEGIN \ UNITTEST_IMPL_TRY \ @@ -75,7 +97,7 @@ }) \ UNITTEST_MULTILINE_MACRO_END -#define UNITTEST_CHECK_NOT_EQUAL(expected, actual) \ +#define UNITTEST_CHECK_FALSE_EQUAL(expected, actual) \ UNITTEST_MULTILINE_MACRO_BEGIN \ UNITTEST_IMPL_TRY \ ({ \ @@ -96,7 +118,7 @@ }) \ UNITTEST_MULTILINE_MACRO_END -#define UNITTEST_CHECK_NOT_EQUAL_HEX(expected, actual) \ +#define UNITTEST_CHECK_FALSE_EQUAL_HEX(expected, actual) \ UNITTEST_MULTILINE_MACRO_BEGIN \ UNITTEST_IMPL_TRY \ ({ \ @@ -208,6 +230,18 @@ #define CHECK UNITTEST_CHECK #endif + #ifdef CHECK_TRUE + #error CHECK_TRUE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_TRUE instead + #else + #define CHECK_TRUE UNITTEST_CHECK + #endif + + #ifdef CHECK_FALSE + #error CHECK_FALSE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_FALSE instead + #else + #define CHECK_FALSE UNITTEST_CHECK_FALSE + #endif + #ifdef CHECK_EQUAL #error CHECK_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_EQUAL instead #else @@ -220,16 +254,16 @@ #define CHECK_EQUAL_HEX UNITTEST_CHECK_EQUAL_HEX #endif - #ifdef CHECK_NOT_EQUAL - #error CHECK_NOT_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL instead + #ifdef CHECK_FALSE_EQUAL + #error CHECK_FALSE_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_FALSE_EQUAL instead #else - #define CHECK_NOT_EQUAL UNITTEST_CHECK_NOT_EQUAL + #define CHECK_FALSE_EQUAL UNITTEST_CHECK_FALSE_EQUAL #endif - #ifdef CHECK_NOT_EQUAL_HEX - #error CHECK_NOT_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL_HEX instead + #ifdef CHECK_FALSE_EQUAL_HEX + #error CHECK_FALSE_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_FALSE_EQUAL_HEX instead #else - #define CHECK_NOT_EQUAL_HEX UNITTEST_CHECK_NOT_EQUAL_HEX + #define CHECK_FALSE_EQUAL_HEX UNITTEST_CHECK_FALSE_EQUAL_HEX #endif #ifdef CHECK_CLOSE diff --git a/test/UnitTest++/Checks.h b/test/UnitTest++/Checks.h index ee7672d6..7fc1f38c 100644 --- a/test/UnitTest++/Checks.h +++ b/test/UnitTest++/Checks.h @@ -25,6 +25,11 @@ namespace UnitTest { return !!value; // doing double negative to avoid silly VS warnings } + template< typename Value > + bool CheckFalse(Value const& value) + { + return !value; + } template< typename Expected, typename Actual > void CheckEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details) diff --git a/test/test_bitset_new.cpp b/test/test_bitset_new.cpp index af0e6838..ec664218 100644 --- a/test/test_bitset_new.cpp +++ b/test/test_bitset_new.cpp @@ -38,6 +38,35 @@ namespace { using ull = unsigned long long; + //************************************************************************* + template + constexpr etl::bitset generate_shift_left_bitset(ull value, size_t shift) + { + etl::bitset data(value); + + if (shift != 0U) + { + data <<= shift; + } + + return data; + } + + //************************************************************************* + template + constexpr etl::bitset generate_shift_left_bitset_copy(ull value, size_t shift) + { + etl::bitset data1(value); + etl::bitset data2; + + if (shift != 0U) + { + data2 = data1 << shift; + } + + return data2; + } + SUITE(test_bitset_new) { //************************************************************************* @@ -683,88 +712,108 @@ namespace } } - ////************************************************************************* - //TEST(test_index_operator_read) - //{ - // std::bitset<60> compare(0x3123456731234567ULL); - // etl::bitset<60> data(0x3123456731234567ULL); + //************************************************************************* + TEST(test_index_operator_read) + { + constexpr std::bitset<60> compare(0x3123456731234567ULL); + constexpr etl::bitset<60> data(0x3123456731234567ULL); - // for (size_t i = 0UL; i < data.size(); ++i) - // { - // CHECK_EQUAL(compare[i], data[i]); - // } - //} + constexpr bool bc0 = compare[1U]; + constexpr bool bd0 = data[1U]; + CHECK_EQUAL(bc0, bd0); - ////************************************************************************* - //TEST(test_index_operator_write) - //{ - // std::bitset<60> compare; - // etl::bitset<60> data; + constexpr bool bc3 = compare[3U]; + constexpr bool bd3 = data[3U]; + CHECK_EQUAL(bc3, bd3); - // for (size_t i = 0UL; i < data.size(); ++i) - // { - // compare[i] = (i % 2) == 0; - // data[i] = (i % 2) == 0; - // } + constexpr bool bc7 = compare[7U]; + constexpr bool bd7 = data[7U]; + CHECK_EQUAL(bc7, bd7); - // for (size_t i = 0UL; i < data.size(); ++i) - // { - // CHECK_EQUAL(compare[i], data[i]); - // } - //} + constexpr bool bc13 = compare[13U]; + constexpr bool bd13 = data[13U]; + CHECK_EQUAL(bc7, bd7); + } - ////************************************************************************* - //TEST(test_any) - //{ - // std::bitset<60> compare; - // etl::bitset<60> data; + //************************************************************************* + constexpr etl::bitset<60> test_index_operator_write_helper() + { + etl::bitset<60> data; - // // Set all bits - // compare.set(); - // data.set(); + data[1U] = true; + data[3U] = true; + data[7U] = true; + data[13U] = true; - // // Reset them all. - // for (size_t i = 0UL; i < data.size(); ++i) - // { - // compare.reset(i); - // data.reset(i); - // } + return data; + } - // CHECK_EQUAL(compare.any(), data.any()); + TEST(test_index_operator_write) + { + constexpr etl::bitset<60> data(test_index_operator_write_helper()); - // compare.set(3); - // data.set(3); + CHECK(data[1U]); + CHECK(data[3U]); + CHECK(data[7U]); + CHECK(data[13U]); + } - // CHECK_EQUAL(compare.any(), data.any()); - //} + //************************************************************************* + TEST(test_any) + { + constexpr etl::bitset<60> data1(ull(0x0000000000000000)); + constexpr etl::bitset<60> data2(ull(0x0000010000000000)); + constexpr etl::bitset<60> data3(ull(0x0000010001000100)); + constexpr etl::bitset<60> data4(ull(0x0FFFFFFFFFFFFFFF)); - ////************************************************************************* - //TEST(test_none) - //{ - // std::bitset<62> compare; - // etl::bitset<62> data; + constexpr bool bd1 = data1.any(); + constexpr bool bd2 = data2.any(); + constexpr bool bd3 = data3.any(); + constexpr bool bd4 = data4.any(); - // CHECK_EQUAL(compare.none(), data.none()); + CHECK_FALSE(bd1); + CHECK_TRUE(bd2); + CHECK_TRUE(bd3); + CHECK_TRUE(bd4); + } - // compare.set(3); - // data.set(3); + //************************************************************************* + TEST(test_none) + { + constexpr etl::bitset<60> data1(ull(0x0000000000000000)); + constexpr etl::bitset<60> data2(ull(0x0000010000000000)); + constexpr etl::bitset<60> data3(ull(0x0000010001000100)); + constexpr etl::bitset<60> data4(ull(0x0FFFFFFFFFFFFFFF)); - // CHECK_EQUAL(compare.none(), data.none()); - //} + constexpr bool bd1 = data1.none(); + constexpr bool bd2 = data2.none(); + constexpr bool bd3 = data3.none(); + constexpr bool bd4 = data4.none(); - ////************************************************************************* - //TEST(test_all) - //{ - // std::bitset<60> compare; - // etl::bitset<60> data; + CHECK_TRUE(bd1); + CHECK_FALSE(bd2); + CHECK_FALSE(bd3); + CHECK_FALSE(bd4); + } - // CHECK_EQUAL(compare.all(), data.all()); + //************************************************************************* + TEST(test_all) + { + constexpr etl::bitset<60> data1(ull(0x0000000000000000)); + constexpr etl::bitset<60> data2(ull(0x0000010000000000)); + constexpr etl::bitset<60> data3(ull(0x0000010001000100)); + constexpr etl::bitset<60> data4(ull(0x0FFFFFFFFFFFFFFF)); - // compare.set(); - // data.set(); + constexpr bool bd1 = data1.all(); + constexpr bool bd2 = data2.all(); + constexpr bool bd3 = data3.all(); + constexpr bool bd4 = data4.all(); - // CHECK_EQUAL(compare.all(), data.all()); - //} + CHECK_FALSE(bd1); + CHECK_FALSE(bd2); + CHECK_FALSE(bd3); + CHECK_TRUE(bd4); + } //************************************************************************* constexpr etl::bitset<60> test_flip_helper() @@ -898,66 +947,58 @@ namespace CHECK(data1 != data3); } - ////************************************************************************* - //TEST(test_shift_left_operator) - //{ - // etl::bitset<60> data1(0x12345678UL); - // etl::bitset<60> data2; - // etl::bitset<60> shift1(0x2468ACF0UL); - // etl::bitset<60> shift2(0x48D159E0UL); - // etl::bitset<60> shift11(0x91A2B3C000ULL); + //************************************************************************* + TEST(test_shift_left_operator) + { + constexpr etl::bitset<60> shift1(0x2468ACF0ULL); + constexpr etl::bitset<60> shift2(0x48D159E0ULL); + constexpr etl::bitset<60> shift11(0x91A2B3C000ULL); - // data2 = data1; - // data2 <<= 1U; - // CHECK(data2 == shift1); + CHECK(generate_shift_left_bitset<60>(0x12345678ULL, 1U) == shift1); + CHECK(generate_shift_left_bitset<60>(0x12345678ULL, 2U) == shift2); + CHECK(generate_shift_left_bitset<60>(0x12345678ULL, 11U) == shift11); + } - // data2 = data1; - // data2 <<= 2U; - // CHECK(data2 == shift2); + //************************************************************************* + TEST(test_shift_left_operator_shift_element_size) + { + constexpr etl::bitset<60> shift8(0x1234567800ULL); + CHECK_EQUAL_HEX(shift8.value(), generate_shift_left_bitset<60>(0x12345678UL, 8U).value()); - // data2 = data1; - // data2 <<= 11U; - // CHECK(data2 == shift11); - //} + constexpr etl::bitset<60> shift16(0x123456780000ULL); + CHECK_EQUAL_HEX(shift16.value(), generate_shift_left_bitset<60>(0x12345678UL, 16U).value()); - ////************************************************************************* - //TEST(test_shift_left_operator_shift_element_size) - //{ - // etl::bitset<60> data(0x12345678UL); - // etl::bitset<60> shift(0x1234567800UL); + constexpr etl::bitset<60> shift24(0x12345678000000ULL); + CHECK_EQUAL_HEX(shift24.value(), generate_shift_left_bitset<60>(0x12345678UL, 24U).value()); - // data <<= 8U; - // CHECK_EQUAL_HEX(shift.value(), data.value()); - //} + constexpr etl::bitset<60> shift60(0x0000000000000000ULL); + CHECK_EQUAL_HEX(shift60.value(), generate_shift_left_bitset<60>(0x12345678UL, 60U).value()); + } - ////************************************************************************* - //TEST(test_shift_left_operator_overflow) - //{ - // etl::bitset<31> data(0x7FFFFFFFUL); - // etl::bitset<31> shifted(0x7FFFFFFEUL); + //************************************************************************* + TEST(test_shift_left_operator_overflow) + { + constexpr etl::bitset<31> data(generate_shift_left_bitset<31>(0x7FFFFFFFULL, 1U)); + constexpr etl::bitset<31> shifted(0x7FFFFFFEUL); - // data <<= 1U; - // CHECK(data == shifted); - //} + CHECK(data == shifted); + } - ////************************************************************************* - //TEST(test_shift_left_copy_operator) - //{ - // etl::bitset<60> data1(0x12345678UL); - // etl::bitset<60> data2; - // etl::bitset<60> shift1(0x2468ACF0UL); - // etl::bitset<60> shift2(0x48D159E0UL); - // etl::bitset<60> shift11(0x91A2B3C000ULL); + //************************************************************************* + TEST(test_shift_left_copy_operator) + { + constexpr etl::bitset<60> shift8(0x1234567800ULL); + CHECK_EQUAL_HEX(shift8.value(), generate_shift_left_bitset_copy<60>(0x12345678UL, 8U).value()); - // data2 = data1 << 1U; - // CHECK(data2 == shift1); + constexpr etl::bitset<60> shift16(0x123456780000ULL); + CHECK_EQUAL_HEX(shift16.value(), generate_shift_left_bitset_copy<60>(0x12345678UL, 16U).value()); - // data2 = data1 << 2U; - // CHECK(data2 == shift2); + constexpr etl::bitset<60> shift24(0x12345678000000ULL); + CHECK_EQUAL_HEX(shift24.value(), generate_shift_left_bitset_copy<60>(0x12345678UL, 24U).value()); - // data2 = data1 << 11U; - // CHECK(data2 == shift11); - //} + constexpr etl::bitset<60> shift60(0x0000000000000000ULL); + CHECK_EQUAL_HEX(shift60.value(), generate_shift_left_bitset_copy<60>(0x12345678UL, 60U).value()); + } ////************************************************************************* //TEST(test_shift_left_operator_all_shifts_full_size) diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index 286677b2..d1254d99 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -2441,6 +2441,7 @@ + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index b0773cc1..d6f0f113 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -1329,6 +1329,9 @@ ETL\Private + + ETL\Private +