From c3603c4d7e29a275be81c3918fcc05a83d528e4c Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 29 Nov 2023 18:21:47 +0000 Subject: [PATCH 1/8] Improved display of CHECK_EQUAL_HEX in unittest++ --- test/UnitTest++/Checks.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/UnitTest++/Checks.h b/test/UnitTest++/Checks.h index a2571e02..88f1a1c3 100644 --- a/test/UnitTest++/Checks.h +++ b/test/UnitTest++/Checks.h @@ -190,7 +190,9 @@ namespace UnitTest if (!(expected == actual)) { UnitTest::MemoryOutStream stream; - stream << std::hex << std::uppercase << std::setfill('0') << "Expected 0x" << std::setw(2 * sizeof(Expected)) << expected << " but was 0x" << std::setw(2 * sizeof(Actual)) << actual; + stream << std::hex << std::uppercase << std::setfill('0') + << "Expected 0x" << std::setw(2 * sizeof(Expected)) << (expected & ~(typename std::make_unsigned::type(0))) + << " but was 0x" << std::setw(2 * sizeof(Actual)) << (actual & ~(typename std::make_unsigned::type(0))); results.OnTestFailure(details, stream.GetText()); } @@ -214,7 +216,8 @@ namespace UnitTest if (expected == actual) { UnitTest::MemoryOutStream stream; - stream << std::hex << std::uppercase << std::setfill('0') << std::setw(2 * sizeof(Actual)) << "Expected not equal, but both values are " << actual; + stream << std::hex << std::uppercase << std::setfill('0') << std::setw(2 * sizeof(Actual)) + << "Expected not equal, but both values are " << (actual & ~(typename std::make_unsigned::type(0))); results.OnTestFailure(details, stream.GetText()); } From 863dd24cc4713225d45f3ede0bc03103c684f18a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 29 Nov 2023 18:22:34 +0000 Subject: [PATCH 2/8] Work in progress for etl::bitset::extract --- include/etl/private/bitset_new.h | 309 +++++++++++++++++- test/test_bitset_new_default_element_type.cpp | 70 ++++ ...itset_new_explicit_single_element_type.cpp | 69 ++++ ...st_bitset_new_ext_default_element_type.cpp | 74 +++++ ...t_new_ext_explicit_single_element_type.cpp | 74 +++++ test/vs2022/etl.vcxproj | 22 +- test/vs2022/etl.vcxproj.filters | 14 +- 7 files changed, 597 insertions(+), 35 deletions(-) diff --git a/include/etl/private/bitset_new.h b/include/etl/private/bitset_new.h index 63462f21..058d8f45 100644 --- a/include/etl/private/bitset_new.h +++ b/include/etl/private/bitset_new.h @@ -192,7 +192,7 @@ namespace etl size_t index = 0; element_type bit = 0; - if (number_of_elements == 0) + if (number_of_elements == 0) ETL_UNLIKELY { return; } @@ -229,12 +229,12 @@ namespace etl else { size_t string_length = etl::strlen(text); - size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + size_t index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); // Only reset elements we need to. - while (element_index != number_of_elements) + while (index != number_of_elements) { - pbuffer[element_index++] = All_Clear_Element; + pbuffer[index++] = All_Clear_Element; } // Build from the string. @@ -259,12 +259,12 @@ namespace etl else { size_t string_length = etl::strlen(text); - size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + size_t index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); // Only reset elements we need to. - while (element_index != number_of_elements) + while (index != number_of_elements) { - pbuffer[element_index++] = All_Clear_Element; + pbuffer[index++] = All_Clear_Element; } // Build from the string. @@ -289,12 +289,12 @@ namespace etl else { size_t string_length = etl::strlen(text); - size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + size_t index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); // Only reset elements we need to. - while (element_index != number_of_elements) + while (index != number_of_elements) { - pbuffer[element_index++] = All_Clear_Element; + pbuffer[index++] = All_Clear_Element; } // Build from the string. @@ -319,12 +319,12 @@ namespace etl else { size_t string_length = etl::strlen(text); - size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + size_t index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); // Only reset elements we need to. - while (element_index != number_of_elements) + while (index != number_of_elements) { - pbuffer[element_index++] = All_Clear_Element; + pbuffer[index++] = All_Clear_Element; } // Build from the string. @@ -395,6 +395,141 @@ namespace etl return v; } + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template + ETL_CONSTEXPR14 + T extract_from_single_element(const_pointer pbuffer, size_t position, size_t length) const ETL_NOEXCEPT + { + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value(0); + + const unsigned_t value_mask = etl::integral_limits::max; + const int element_index = (position + length - 1) >> etl::log2::value; + const unsigned_t Shift = position % Bits_Per_Element; + + value = static_cast(pbuffer[element_index] >> Shift) & value_mask; + + return static_cast(value); + } + + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template + ETL_CONSTEXPR14 + T extract_from_multi_element(const_pointer pbuffer, size_t position, size_t length) const ETL_NOEXCEPT + { + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value(0); + + // The mask for the value type. + const unsigned_t value_mask = etl::integral_limits::max; + + // Find the index of the element containing the msb. + int element_index = (position + length - 1) >> etl::log2::value; + + // The value is spread over multiple elements. + element_type bit_mask = element_type(1) << ((position + length - 1) % Bits_Per_Element); + + while (length != 0) + { + // TODO Optimise this to read whole element values. + + value <<= 1; + + const bool is_set = (pbuffer[element_index] & bit_mask) != 0; + + if (is_set) + { + value |= unsigned_t(1); + } + + bit_mask >>= 1; + + if (bit_mask == 0) + { + bit_mask = element_type(1) << (Bits_Per_Element - 1); + --element_index; + } + + --length; + } + + return static_cast(value); + } + + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template + ETL_CONSTEXPR14 + T extract_from_single_element(const_pointer pbuffer) const + { + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value(0); + + const unsigned_t value_mask = etl::integral_limits::max; + const int element_index = (Position + Length - 1) >> etl::log2::value; + const unsigned_t Shift = Position % Bits_Per_Element; + + value = static_cast(pbuffer[element_index] >> Shift) & value_mask; + + return static_cast(value); + } + + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template + ETL_CONSTEXPR14 + T extract_from_multi_element(const_pointer pbuffer) const + { + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value(0); + + // The mask for the value type. + const unsigned_t value_mask = etl::integral_limits::max; + + // Find the index of the element containing the msb. + int element_index = (Position + Length - 1) >> etl::log2::value; + + // The value is spread over multiple elements. + size_t length = Length; + element_type bit_mask = element_type(1) << ((Position + Length - 1) % Bits_Per_Element); + + while (length != 0) + { + // TODO Optimise this to read whole element values. + + value <<= 1; + + const bool is_set = (pbuffer[element_index] & bit_mask) != 0; + + if (is_set) + { + value |= unsigned_t(1); + } + + bit_mask >>= 1; + + if (bit_mask == 0) + { + bit_mask = element_type(1) << (Bits_Per_Element - 1); + --element_index; + } + + --length; + } + + return static_cast(value); + } + //************************************************************************* /// Reset the bit at the position. //************************************************************************* @@ -403,7 +538,7 @@ namespace etl size_t index = 0U; element_type bit = element_type(0); - if (number_of_elements == 0) + if (number_of_elements == 0) ETL_UNLIKELY { return; } @@ -440,7 +575,7 @@ namespace etl size_t index = 0U; element_type bit = element_type(0); - if (number_of_elements == 0) + if (number_of_elements == 0) ETL_UNLIKELY { return; } @@ -1251,7 +1386,7 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - typename etl::enable_if::value, T>::type + typename etl::enable_if::value, T>::type value() const ETL_NOEXCEPT { ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); @@ -1269,6 +1404,40 @@ namespace etl return v; } + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + extract(size_t position, size_t length = etl::integral_limits::bits) const + { + ETL_ASSERT_OR_RETURN_VALUE(length <= etl::integral_limits::bits, ETL_ERROR(bitset_overflow), 0); + ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); + + element_type mask = (~(~0u << length) << position); + T value((buffer & mask) >> position); + + return value; + } + + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template ::bits> + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + extract() const ETL_NOEXCEPT + { + ETL_STATIC_ASSERT(Length <= etl::integral_limits::bits, "Length is larger that the required type"); + ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); + + element_type mask = (~(~0u << Length) << Position); + T value((buffer & mask) >> Position); + + return value; + } + //************************************************************************* /// Get as an unsigned long. //************************************************************************* @@ -2027,6 +2196,42 @@ namespace etl return ibitset.template value(buffer, Number_Of_Elements); } + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + extract(size_t position, size_t length = etl::integral_limits::bits) const + { + ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); + + return ibitset.extract_from_multi_element(buffer, position, length); + } + + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template ::bits> + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + extract() const ETL_NOEXCEPT + { + ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); + + const int active_bits_in_element = ((Position + Length) % Bits_Per_Element); + + // Is the value contained within one element? + if (active_bits_in_element == Length) + { + return ibitset.extract_from_single_element(buffer); + } + else + { + return ibitset.extract_from_multi_element(buffer); + } + } + //************************************************************************* /// Get as an unsigned long. //************************************************************************* @@ -2963,7 +3168,7 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - typename etl::enable_if::value, T>::type + typename etl::enable_if::value, T>::type value() const ETL_NOEXCEPT { ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); @@ -2981,6 +3186,38 @@ namespace etl return v; } + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + extract(size_t position, size_t length = etl::integral_limits::bits) const + { + ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); + + element_type mask = (~(~0u << length) << position); + T v((*pbuffer & mask) >> position); + + return v; + } + + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template ::bits> + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + extract() const ETL_NOEXCEPT + { + ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); + + element_type mask = (~(~0u << Length) << Position); + T v((*pbuffer & mask) >> Position); + + return v; + } + //************************************************************************* /// Get as an unsigned long. //************************************************************************* @@ -3733,7 +3970,7 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - typename etl::enable_if::value, T>::type + typename etl::enable_if::value, T>::type value() const ETL_NOEXCEPT { ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); @@ -3742,6 +3979,42 @@ namespace etl return ibitset.template value(pbuffer, Number_Of_Elements); } + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + extract(size_t position, size_t length = etl::integral_limits::bits) const + { + ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); + + return ibitset.extract_from_multi_element(pbuffer, position, length); + } + + //************************************************************************* + /// Extract an integral value from an arbitary position and length. + //************************************************************************* + template ::bits> + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + extract() const ETL_NOEXCEPT + { + ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); + + const int active_bits_in_element = ((Position + Length) % Bits_Per_Element); + + // Is the value contained within one element? + if (active_bits_in_element == Length) + { + return ibitset.extract_from_single_element(pbuffer); + } + else + { + return ibitset.extract_from_multi_element(pbuffer); + } + } + //************************************************************************* /// Get as an unsigned long. //************************************************************************* diff --git a/test/test_bitset_new_default_element_type.cpp b/test/test_bitset_new_default_element_type.cpp index 67f703a3..f41ac262 100644 --- a/test/test_bitset_new_default_element_type.cpp +++ b/test/test_bitset_new_default_element_type.cpp @@ -2096,5 +2096,75 @@ namespace CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(text.c_str())); CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(stdtext.c_str())); } + + //************************************************************************* + TEST(test_extract_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint8_t(0x78), b.extract( 0, 8)); + CHECK_EQUAL_HEX(uint8_t(0x3C), b.extract( 1, 8)); + CHECK_EQUAL_HEX(uint8_t(0x9E), b.extract( 2, 8)); + CHECK_EQUAL_HEX(uint8_t(0xCF), b.extract( 3, 8)); + CHECK_EQUAL_HEX(uint8_t(0x67), b.extract( 4, 8)); + CHECK_EQUAL_HEX(uint8_t(0xB3), b.extract( 5, 8)); + CHECK_EQUAL_HEX(uint8_t(0x59), b.extract( 6, 8)); + CHECK_EQUAL_HEX(uint8_t(0xAC), b.extract( 7, 8)); + CHECK_EQUAL_HEX(uint8_t(0x56), b.extract( 8, 8)); + CHECK_EQUAL_HEX(uint8_t(0x2B), b.extract( 9, 8)); + CHECK_EQUAL_HEX(uint8_t(0x15), b.extract(10, 8)); + CHECK_EQUAL_HEX(uint8_t(0x8A), b.extract(11, 8)); + CHECK_EQUAL_HEX(uint8_t(0x45), b.extract(12, 8)); + CHECK_EQUAL_HEX(uint8_t(0xA2), b.extract(13, 8)); + CHECK_EQUAL_HEX(uint8_t(0xD1), b.extract(14, 8)); + CHECK_EQUAL_HEX(uint8_t(0x68), b.extract(15, 8)); + CHECK_EQUAL_HEX(uint8_t(0x34), b.extract(16, 8)); + CHECK_EQUAL_HEX(uint8_t(0x1A), b.extract(17, 8)); + CHECK_EQUAL_HEX(uint8_t(0x8D), b.extract(18, 8)); + CHECK_EQUAL_HEX(uint8_t(0x46), b.extract(19, 8)); + CHECK_EQUAL_HEX(uint8_t(0x23), b.extract(20, 8)); + CHECK_EQUAL_HEX(uint8_t(0x91), b.extract(21, 8)); + CHECK_EQUAL_HEX(uint8_t(0x48), b.extract(22, 8)); + CHECK_EQUAL_HEX(uint8_t(0x24), b.extract(23, 8)); + CHECK_EQUAL_HEX(uint8_t(0x12), b.extract(24, 8)); + + CHECK_THROW(b.extract(25, 8), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint8_t(0x78), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x9E), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xCF), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x67), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xB3), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x59), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xAC), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x56), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x8A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x45), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xA2), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xD1), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x68), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x8D), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x46), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x91), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x48), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); + + // The lines below should static assert. + //uint8_t v = b.extract(); + //uint8_t v = b.extract(); + } }; } diff --git a/test/test_bitset_new_explicit_single_element_type.cpp b/test/test_bitset_new_explicit_single_element_type.cpp index b9c0c84b..0f25e6da 100644 --- a/test/test_bitset_new_explicit_single_element_type.cpp +++ b/test/test_bitset_new_explicit_single_element_type.cpp @@ -1585,5 +1585,74 @@ namespace CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(text.c_str())); CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(stdtext.c_str())); } + + //************************************************************************* + TEST(test_extract_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL(0x78, b.extract(0, 8)); + CHECK_EQUAL(0x3C, b.extract(1, 8)); + CHECK_EQUAL(0x9E, b.extract(2, 8)); + CHECK_EQUAL(0xCF, b.extract(3, 8)); + CHECK_EQUAL(0x67, b.extract(4, 8)); + CHECK_EQUAL(0xB3, b.extract(5, 8)); + CHECK_EQUAL(0x59, b.extract(6, 8)); + CHECK_EQUAL(0xAC, b.extract(7, 8)); + CHECK_EQUAL(0x56, b.extract(8, 8)); + CHECK_EQUAL(0x2B, b.extract(9, 8)); + CHECK_EQUAL(0x15, b.extract(10, 8)); + CHECK_EQUAL(0x8A, b.extract(11, 8)); + CHECK_EQUAL(0x45, b.extract(12, 8)); + CHECK_EQUAL(0xA2, b.extract(13, 8)); + CHECK_EQUAL(0xD1, b.extract(14, 8)); + CHECK_EQUAL(0x68, b.extract(15, 8)); + CHECK_EQUAL(0x34, b.extract(16, 8)); + CHECK_EQUAL(0x1A, b.extract(17, 8)); + CHECK_EQUAL(0x8D, b.extract(18, 8)); + CHECK_EQUAL(0x46, b.extract(19, 8)); + CHECK_EQUAL(0x23, b.extract(20, 8)); + CHECK_EQUAL(0x91, b.extract(21, 8)); + CHECK_EQUAL(0x48, b.extract(22, 8)); + CHECK_EQUAL(0x24, b.extract(23, 8)); + CHECK_EQUAL(0x12, b.extract(24, 8)); + CHECK_THROW(b.extract(25, 8), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL(0x78, (b.extract())); + CHECK_EQUAL(0x3C, (b.extract())); + CHECK_EQUAL(0x9E, (b.extract())); + CHECK_EQUAL(0xCF, (b.extract())); + CHECK_EQUAL(0x67, (b.extract())); + CHECK_EQUAL(0xB3, (b.extract())); + CHECK_EQUAL(0x59, (b.extract())); + CHECK_EQUAL(0xAC, (b.extract())); + CHECK_EQUAL(0x56, (b.extract())); + CHECK_EQUAL(0x2B, (b.extract())); + CHECK_EQUAL(0x15, (b.extract())); + CHECK_EQUAL(0x8A, (b.extract())); + CHECK_EQUAL(0x45, (b.extract())); + CHECK_EQUAL(0xA2, (b.extract())); + CHECK_EQUAL(0xD1, (b.extract())); + CHECK_EQUAL(0x68, (b.extract())); + CHECK_EQUAL(0x34, (b.extract())); + CHECK_EQUAL(0x1A, (b.extract())); + CHECK_EQUAL(0x8D, (b.extract())); + CHECK_EQUAL(0x46, (b.extract())); + CHECK_EQUAL(0x23, (b.extract())); + CHECK_EQUAL(0x91, (b.extract())); + CHECK_EQUAL(0x48, (b.extract())); + CHECK_EQUAL(0x24, (b.extract())); + CHECK_EQUAL(0x12, (b.extract())); + + // The lines below should static assert. + //uint8_t v = b.extract(); + //uint8_t v = b.extract(); + } }; } diff --git a/test/test_bitset_new_ext_default_element_type.cpp b/test/test_bitset_new_ext_default_element_type.cpp index aeeea766..c5e12541 100644 --- a/test/test_bitset_new_ext_default_element_type.cpp +++ b/test/test_bitset_new_ext_default_element_type.cpp @@ -1957,5 +1957,79 @@ namespace CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(text.c_str())); CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(stdtext.c_str())); } + + //************************************************************************* + TEST(test_extract_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint8_t(0x78), b.extract( 0, 8)); + CHECK_EQUAL_HEX(uint8_t(0x3C), b.extract( 1, 8)); + CHECK_EQUAL_HEX(uint8_t(0x9E), b.extract( 2, 8)); + CHECK_EQUAL_HEX(uint8_t(0xCF), b.extract( 3, 8)); + CHECK_EQUAL_HEX(uint8_t(0x67), b.extract( 4, 8)); + CHECK_EQUAL_HEX(uint8_t(0xB3), b.extract( 5, 8)); + CHECK_EQUAL_HEX(uint8_t(0x59), b.extract( 6, 8)); + CHECK_EQUAL_HEX(uint8_t(0xAC), b.extract( 7, 8)); + CHECK_EQUAL_HEX(uint8_t(0x56), b.extract( 8, 8)); + CHECK_EQUAL_HEX(uint8_t(0x2B), b.extract( 9, 8)); + CHECK_EQUAL_HEX(uint8_t(0x15), b.extract(10, 8)); + CHECK_EQUAL_HEX(uint8_t(0x8A), b.extract(11, 8)); + CHECK_EQUAL_HEX(uint8_t(0x45), b.extract(12, 8)); + CHECK_EQUAL_HEX(uint8_t(0xA2), b.extract(13, 8)); + CHECK_EQUAL_HEX(uint8_t(0xD1), b.extract(14, 8)); + CHECK_EQUAL_HEX(uint8_t(0x68), b.extract(15, 8)); + CHECK_EQUAL_HEX(uint8_t(0x34), b.extract(16, 8)); + CHECK_EQUAL_HEX(uint8_t(0x1A), b.extract(17, 8)); + CHECK_EQUAL_HEX(uint8_t(0x8D), b.extract(18, 8)); + CHECK_EQUAL_HEX(uint8_t(0x46), b.extract(19, 8)); + CHECK_EQUAL_HEX(uint8_t(0x23), b.extract(20, 8)); + CHECK_EQUAL_HEX(uint8_t(0x91), b.extract(21, 8)); + CHECK_EQUAL_HEX(uint8_t(0x48), b.extract(22, 8)); + CHECK_EQUAL_HEX(uint8_t(0x24), b.extract(23, 8)); + CHECK_EQUAL_HEX(uint8_t(0x12), b.extract(24, 8)); + } + + //************************************************************************* + TEST(test_extract_with_template_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint8_t(0x78), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x9E), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xCF), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x67), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xB3), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x59), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xAC), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x56), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x8A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x45), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xA2), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xD1), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x68), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x8D), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x46), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x91), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x48), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); + + // The line below should static assert. + //uint8_t v = b.extract(); + //uint8_t v = b.extract(); + } }; } diff --git a/test/test_bitset_new_ext_explicit_single_element_type.cpp b/test/test_bitset_new_ext_explicit_single_element_type.cpp index b7bc74ef..308259a4 100644 --- a/test/test_bitset_new_ext_explicit_single_element_type.cpp +++ b/test/test_bitset_new_ext_explicit_single_element_type.cpp @@ -1309,5 +1309,79 @@ namespace CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(text.c_str())); CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(stdtext.c_str())); } + + //************************************************************************* + TEST(test_extract_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32, int32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint8_t(0x78), b.extract( 0, 8)); + CHECK_EQUAL_HEX(uint8_t(0x3C), b.extract( 1, 8)); + CHECK_EQUAL_HEX(uint8_t(0x9E), b.extract( 2, 8)); + CHECK_EQUAL_HEX(uint8_t(0xCF), b.extract( 3, 8)); + CHECK_EQUAL_HEX(uint8_t(0x67), b.extract( 4, 8)); + CHECK_EQUAL_HEX(uint8_t(0xB3), b.extract( 5, 8)); + CHECK_EQUAL_HEX(uint8_t(0x59), b.extract( 6, 8)); + CHECK_EQUAL_HEX(uint8_t(0xAC), b.extract( 7, 8)); + CHECK_EQUAL_HEX(uint8_t(0x56), b.extract( 8, 8)); + CHECK_EQUAL_HEX(uint8_t(0x2B), b.extract( 9, 8)); + CHECK_EQUAL_HEX(uint8_t(0x15), b.extract(10, 8)); + CHECK_EQUAL_HEX(uint8_t(0x8A), b.extract(11, 8)); + CHECK_EQUAL_HEX(uint8_t(0x45), b.extract(12, 8)); + CHECK_EQUAL_HEX(uint8_t(0xA2), b.extract(13, 8)); + CHECK_EQUAL_HEX(uint8_t(0xD1), b.extract(14, 8)); + CHECK_EQUAL_HEX(uint8_t(0x68), b.extract(15, 8)); + CHECK_EQUAL_HEX(uint8_t(0x34), b.extract(16, 8)); + CHECK_EQUAL_HEX(uint8_t(0x1A), b.extract(17, 8)); + CHECK_EQUAL_HEX(uint8_t(0x8D), b.extract(18, 8)); + CHECK_EQUAL_HEX(uint8_t(0x46), b.extract(19, 8)); + CHECK_EQUAL_HEX(uint8_t(0x23), b.extract(20, 8)); + CHECK_EQUAL_HEX(uint8_t(0x91), b.extract(21, 8)); + CHECK_EQUAL_HEX(uint8_t(0x48), b.extract(22, 8)); + CHECK_EQUAL_HEX(uint8_t(0x24), b.extract(23, 8)); + CHECK_EQUAL_HEX(uint8_t(0x12), b.extract(24, 8)); + } + + //************************************************************************* + TEST(test_extract_with_template_parameters) + { + using bs32 = etl::bitset_ext<32, int32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint8_t(0x78), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x9E), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xCF), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x67), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xB3), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x59), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xAC), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x56), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x8A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x45), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xA2), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xD1), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x68), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x8D), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x46), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x91), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x48), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); + + // The line below should static assert. + //uint8_t v = b.extract(); + //uint8_t v = b.extract(); + } }; } diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index 50d71f98..346223ed 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -839,17 +839,17 @@ $(Configuration)\ - false + true true $(Configuration)\ - false + true true $(Configuration)\ - false + true true $(Configuration)\ @@ -859,37 +859,37 @@ $(Configuration)\ - false + true true $(Configuration)\ - false + true true $(Configuration)\ - false + true true $(Configuration)\ - false + true true $(Configuration)\ - false + true true $(Configuration)\ - false + true true $(Configuration)\ - false + true true $(Configuration)\ @@ -935,7 +935,7 @@ $(Configuration)\ - false + true true $(Configuration)\ diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index d4dfc25b..cea19458 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -3334,12 +3334,6 @@ Resource Files\CI\Appveyor - - Resource Files\CI\Github - - - Resource Files\CI\Github - Resource Files @@ -3406,6 +3400,14 @@ Tests\Scripts + + + + + + + + From 3d3f87564dc964ea8f55d01175f75a1d9583d663 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 1 Dec 2023 17:21:48 +0000 Subject: [PATCH 3/8] Work in progress for etl::bitset::extract --- include/etl/private/bitset_new.h | 186 +++++----- test/test_bitset_new_default_element_type.cpp | 326 +++++++++++++++++- ...itset_new_explicit_single_element_type.cpp | 4 +- ...st_bitset_new_ext_default_element_type.cpp | 4 +- ...t_new_ext_explicit_single_element_type.cpp | 4 +- 5 files changed, 412 insertions(+), 112 deletions(-) diff --git a/include/etl/private/bitset_new.h b/include/etl/private/bitset_new.h index 058d8f45..4dbfbef8 100644 --- a/include/etl/private/bitset_new.h +++ b/include/etl/private/bitset_new.h @@ -145,6 +145,12 @@ namespace etl static ETL_CONSTANT element_type All_Set_Element = etl::integral_limits::max; static ETL_CONSTANT element_type All_Clear_Element = element_type(0); + template + struct value_is_in_one_element + { + static ETL_CONSTANT bool value = ((Position + Length - 1) >> etl::log2::value) == (Position >> etl::log2::value); + }; + //************************************************************************* /// Count the number of bits set. //************************************************************************* @@ -400,63 +406,56 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - T extract_from_single_element(const_pointer pbuffer, size_t position, size_t length) const ETL_NOEXCEPT + T extract_from_buffer(const_pointer pbuffer, size_t position, size_t length) const ETL_NOEXCEPT { typedef typename etl::make_unsigned::type unsigned_t; unsigned_t value(0); - const unsigned_t value_mask = etl::integral_limits::max; - const int element_index = (position + length - 1) >> etl::log2::value; - const unsigned_t Shift = position % Bits_Per_Element; + const int Msb_Element_Index = (position + length - 1) >> etl::log2::value; + const int Lsb_Element_Index = position >> etl::log2::value; - value = static_cast(pbuffer[element_index] >> Shift) & value_mask; - - return static_cast(value); - } - - //************************************************************************* - /// Extract an integral value from an arbitary position and length. - //************************************************************************* - template - ETL_CONSTEXPR14 - T extract_from_multi_element(const_pointer pbuffer, size_t position, size_t length) const ETL_NOEXCEPT - { - typedef typename etl::make_unsigned::type unsigned_t; - - unsigned_t value(0); - - // The mask for the value type. - const unsigned_t value_mask = etl::integral_limits::max; - - // Find the index of the element containing the msb. - int element_index = (position + length - 1) >> etl::log2::value; - - // The value is spread over multiple elements. - element_type bit_mask = element_type(1) << ((position + length - 1) % Bits_Per_Element); - - while (length != 0) + // Is the value contained within one element? + if (Msb_Element_Index == Lsb_Element_Index) { - // TODO Optimise this to read whole element values. + const unsigned_t Mask = ~(~0 << length); + const unsigned_t Shift = position % Bits_Per_Element; - value <<= 1; + value = static_cast(pbuffer[Msb_Element_Index] >> Shift) & Mask; + } + else + { + // Get the number of active bits in the msb element + size_t active_bits_in_msb = (position + length) - (Msb_Element_Index * Bits_Per_Element); - const bool is_set = (pbuffer[element_index] & bit_mask) != 0; + // Extract the first element if partially filled. + // Start with index of the element containing the msb. + int element_index = Msb_Element_Index; - if (is_set) + if (active_bits_in_msb < Bits_Per_Element) { - value |= unsigned_t(1); - } - - bit_mask >>= 1; - - if (bit_mask == 0) - { - bit_mask = element_type(1) << (Bits_Per_Element - 1); + element_type mask = ~(~element_type(0) << active_bits_in_msb); + value |= pbuffer[element_index] & mask; + length -= active_bits_in_msb; --element_index; } - --length; + // Loop through the fully filled elements + while (length >= Bits_Per_Element) + { + value <<= Bits_Per_Element; + value |= pbuffer[element_index]; + length -= Bits_Per_Element; + --element_index; + } + + // Check if the last element is partially filled and extract. + if (length != 0) + { + value <<= length; + element_type mask = ~(~element_type(0) << length); + value |= (pbuffer[element_index] >> (Bits_Per_Element - length)) & mask; + } } return static_cast(value); @@ -467,17 +466,16 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - T extract_from_single_element(const_pointer pbuffer) const + typename etl::enable_if::value, T>::type + extract_from_buffer(const_pointer pbuffer) const { typedef typename etl::make_unsigned::type unsigned_t; - unsigned_t value(0); - - const unsigned_t value_mask = etl::integral_limits::max; - const int element_index = (Position + Length - 1) >> etl::log2::value; + const int Element_Index = (Position + Length - 1) >> etl::log2::value; + const unsigned_t Mask = ~(~0 << Length); const unsigned_t Shift = Position % Bits_Per_Element; - - value = static_cast(pbuffer[element_index] >> Shift) & value_mask; + + unsigned_t value = static_cast(pbuffer[Element_Index] >> Shift) & Mask; return static_cast(value); } @@ -487,44 +485,48 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - T extract_from_multi_element(const_pointer pbuffer) const + typename etl::enable_if::value, T>::type + extract_from_buffer(const_pointer pbuffer) const { typedef typename etl::make_unsigned::type unsigned_t; unsigned_t value(0); - // The mask for the value type. - const unsigned_t value_mask = etl::integral_limits::max; + const int Msb_Element_Index = (Position + Length - 1) >> etl::log2::value; - // Find the index of the element containing the msb. - int element_index = (Position + Length - 1) >> etl::log2::value; + // Start with index of the element containing the msb. + int element_index = Msb_Element_Index; // The value is spread over multiple elements. - size_t length = Length; - element_type bit_mask = element_type(1) << ((Position + Length - 1) % Bits_Per_Element); + size_t length = Length; - while (length != 0) + // Get the number of active bits in the first element + size_t active_bits_in_element = ((Position + Length - 1) % Bits_Per_Element) + 1; + + // Extract the first element if partially filled. + if (active_bits_in_element < Bits_Per_Element) { - // TODO Optimise this to read whole element values. + element_type mask = ~(~element_type(0) << active_bits_in_element); + value |= pbuffer[element_index] & mask; + length -= active_bits_in_element; + --element_index; + } - value <<= 1; + // Loop through the fully filled elements + while (length >= Bits_Per_Element) + { + value <<= Bits_Per_Element; + value |= pbuffer[element_index]; + length -= Bits_Per_Element; + --element_index; + } - const bool is_set = (pbuffer[element_index] & bit_mask) != 0; - - if (is_set) - { - value |= unsigned_t(1); - } - - bit_mask >>= 1; - - if (bit_mask == 0) - { - bit_mask = element_type(1) << (Bits_Per_Element - 1); - --element_index; - } - - --length; + // Check if the last element is partially filled and extract. + if (length != 0) + { + value <<= length; + element_type mask = ~(~element_type(0) << length); + value |= (pbuffer[element_index] >> (Bits_Per_Element - length)) & mask; } return static_cast(value); @@ -2187,7 +2189,7 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - typename etl::enable_if::value, T>::type + typename etl::enable_if::value, T>::type value() const ETL_NOEXCEPT { ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); @@ -2206,7 +2208,7 @@ namespace etl { ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); - return ibitset.extract_from_multi_element(buffer, position, length); + return ibitset.extract_from_buffer(buffer, position, length); } //************************************************************************* @@ -2214,22 +2216,12 @@ namespace etl //************************************************************************* template ::bits> ETL_CONSTEXPR14 - typename etl::enable_if::value, T>::type + typename etl::enable_if::value, T>::type extract() const ETL_NOEXCEPT { ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); - const int active_bits_in_element = ((Position + Length) % Bits_Per_Element); - - // Is the value contained within one element? - if (active_bits_in_element == Length) - { - return ibitset.extract_from_single_element(buffer); - } - else - { - return ibitset.extract_from_multi_element(buffer); - } + return ibitset.extract_from_buffer(buffer); } //************************************************************************* @@ -3989,7 +3981,7 @@ namespace etl { ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); - return ibitset.extract_from_multi_element(pbuffer, position, length); + return ibitset.extract_from_buffer(pbuffer, position, length); } //************************************************************************* @@ -4002,17 +3994,7 @@ namespace etl { ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); - const int active_bits_in_element = ((Position + Length) % Bits_Per_Element); - - // Is the value contained within one element? - if (active_bits_in_element == Length) - { - return ibitset.extract_from_single_element(pbuffer); - } - else - { - return ibitset.extract_from_multi_element(pbuffer); - } + return ibitset.extract_from_buffer(pbuffer); } //************************************************************************* diff --git a/test/test_bitset_new_default_element_type.cpp b/test/test_bitset_new_default_element_type.cpp index f41ac262..199e18a0 100644 --- a/test/test_bitset_new_default_element_type.cpp +++ b/test/test_bitset_new_default_element_type.cpp @@ -2098,7 +2098,82 @@ namespace } //************************************************************************* - TEST(test_extract_with_run_time_parameters) + TEST(test_extract_6_bit_uint8_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint8_t(0x38), (b.extract( 0, 6))); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract( 1, 6))); + CHECK_EQUAL_HEX(uint8_t(0x1E), (b.extract( 2, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0F), (b.extract( 3, 6))); + CHECK_EQUAL_HEX(uint8_t(0x27), (b.extract( 4, 6))); + CHECK_EQUAL_HEX(uint8_t(0x33), (b.extract( 5, 6))); + CHECK_EQUAL_HEX(uint8_t(0x19), (b.extract( 6, 6))); + CHECK_EQUAL_HEX(uint8_t(0x2C), (b.extract( 7, 6))); + CHECK_EQUAL_HEX(uint8_t(0x16), (b.extract( 8, 6))); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract( 9, 6))); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract(10, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0A), (b.extract(11, 6))); + CHECK_EQUAL_HEX(uint8_t(0x05), (b.extract(12, 6))); + CHECK_EQUAL_HEX(uint8_t(0x22), (b.extract(13, 6))); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract(14, 6))); + CHECK_EQUAL_HEX(uint8_t(0x28), (b.extract(15, 6))); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract(16, 6))); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract(17, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0D), (b.extract(18, 6))); + CHECK_EQUAL_HEX(uint8_t(0x06), (b.extract(19, 6))); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract(20, 6))); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract(21, 6))); + CHECK_EQUAL_HEX(uint8_t(0x08), (b.extract(22, 6))); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract(23, 6))); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract(24, 6))); + CHECK_EQUAL_HEX(uint8_t(0x09), (b.extract(25, 6))); + CHECK_EQUAL_HEX(uint8_t(0x04), (b.extract(26, 6))); + + CHECK_THROW(b.extract(26, 7), etl::bitset_overflow); + CHECK_THROW(b.extract(27, 6), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_6_bit_uint8_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint8_t(0x38), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1E), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0F), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x27), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x33), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x19), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x16), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x05), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x22), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x28), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0D), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x06), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x08), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x09), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x04), (b.extract())); + + // The lines below should static assert. + //uint8_t v1 = b.extract(); + //uint8_t v1 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_uint8_t_with_run_time_parameters) { ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); @@ -2128,11 +2203,12 @@ namespace CHECK_EQUAL_HEX(uint8_t(0x24), b.extract(23, 8)); CHECK_EQUAL_HEX(uint8_t(0x12), b.extract(24, 8)); + CHECK_THROW(b.extract(24, 9), etl::bitset_overflow); CHECK_THROW(b.extract(25, 8), etl::bitset_overflow); } //************************************************************************* - TEST(test_extract_with_template_parameters) + TEST(test_extract_uint8_t_with_template_parameters) { ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); @@ -2163,8 +2239,250 @@ namespace CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); // The lines below should static assert. - //uint8_t v = b.extract(); - //uint8_t v = b.extract(); + //uint8_t v1 = b.extract(); + //uint8_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_int8_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(int8_t(0x78), b.extract( 0, 8)); + CHECK_EQUAL_HEX(int8_t(0x3C), b.extract( 1, 8)); + CHECK_EQUAL_HEX(int8_t(0x9E), b.extract( 2, 8)); + CHECK_EQUAL_HEX(int8_t(0xCF), b.extract( 3, 8)); + CHECK_EQUAL_HEX(int8_t(0x67), b.extract( 4, 8)); + CHECK_EQUAL_HEX(int8_t(0xB3), b.extract( 5, 8)); + CHECK_EQUAL_HEX(int8_t(0x59), b.extract( 6, 8)); + CHECK_EQUAL_HEX(int8_t(0xAC), b.extract( 7, 8)); + CHECK_EQUAL_HEX(int8_t(0x56), b.extract( 8, 8)); + CHECK_EQUAL_HEX(int8_t(0x2B), b.extract( 9, 8)); + CHECK_EQUAL_HEX(int8_t(0x15), b.extract(10, 8)); + CHECK_EQUAL_HEX(int8_t(0x8A), b.extract(11, 8)); + CHECK_EQUAL_HEX(int8_t(0x45), b.extract(12, 8)); + CHECK_EQUAL_HEX(int8_t(0xA2), b.extract(13, 8)); + CHECK_EQUAL_HEX(int8_t(0xD1), b.extract(14, 8)); + CHECK_EQUAL_HEX(int8_t(0x68), b.extract(15, 8)); + CHECK_EQUAL_HEX(int8_t(0x34), b.extract(16, 8)); + CHECK_EQUAL_HEX(int8_t(0x1A), b.extract(17, 8)); + CHECK_EQUAL_HEX(int8_t(0x8D), b.extract(18, 8)); + CHECK_EQUAL_HEX(int8_t(0x46), b.extract(19, 8)); + CHECK_EQUAL_HEX(int8_t(0x23), b.extract(20, 8)); + CHECK_EQUAL_HEX(int8_t(0x91), b.extract(21, 8)); + CHECK_EQUAL_HEX(int8_t(0x48), b.extract(22, 8)); + CHECK_EQUAL_HEX(int8_t(0x24), b.extract(23, 8)); + CHECK_EQUAL_HEX(int8_t(0x12), b.extract(24, 8)); + + CHECK_THROW(b.extract(24, 9), etl::bitset_overflow); + CHECK_THROW(b.extract(25, 8), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_int8_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(int8_t(0x78), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x9E), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xCF), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x67), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xB3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x59), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xAC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x56), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x8A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x45), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xA2), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xD1), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x68), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x8D), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x46), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x91), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x48), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract())); + + // The lines below should static assert. + //int8_t v1 = b.extract(); + //int8_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_13_bits_uint16_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint16_t(0x1678), b.extract( 0, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0B3C), b.extract( 1, 13)); + CHECK_EQUAL_HEX(uint16_t(0x159E), b.extract( 2, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0ACF), b.extract( 3, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0567), b.extract( 4, 13)); + CHECK_EQUAL_HEX(uint16_t(0x02B3), b.extract( 5, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1159), b.extract( 6, 13)); + CHECK_EQUAL_HEX(uint16_t(0x08AC), b.extract( 7, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1456), b.extract( 8, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), b.extract( 9, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0D15), b.extract(10, 13)); + CHECK_EQUAL_HEX(uint16_t(0x068A), b.extract(11, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0345), b.extract(12, 13)); + CHECK_EQUAL_HEX(uint16_t(0x11A2), b.extract(13, 13)); + CHECK_EQUAL_HEX(uint16_t(0x08D1), b.extract(14, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0468), b.extract(15, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1234), b.extract(16, 13)); + CHECK_EQUAL_HEX(uint16_t(0x091A), b.extract(17, 13)); + CHECK_EQUAL_HEX(uint16_t(0x048D), b.extract(18, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0246), b.extract(19, 13)); + + CHECK_THROW(b.extract(19, 14), etl::bitset_overflow); + CHECK_THROW(b.extract(20, 13), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_13_bits_uint16_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint16_t(0x1678), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0B3C), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0ACF), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0567), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x02B3), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1159), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x08AC), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1456), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0D15), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x068A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0345), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x11A2), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x08D1), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0468), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1234), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x091A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x048D), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0246), (b.extract())); + + // The lines below should static assert. + //uint16_t v1 = b.extract b(0x12345678UL); + + CHECK_EQUAL_HEX(uint16_t(0x5678), b.extract( 0, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2B3C), b.extract( 1, 16)); + CHECK_EQUAL_HEX(uint16_t(0x159E), b.extract( 2, 16)); + CHECK_EQUAL_HEX(uint16_t(0x8ACF), b.extract( 3, 16)); + CHECK_EQUAL_HEX(uint16_t(0x4567), b.extract( 4, 16)); + CHECK_EQUAL_HEX(uint16_t(0xA2B3), b.extract( 5, 16)); + CHECK_EQUAL_HEX(uint16_t(0xD159), b.extract( 6, 16)); + CHECK_EQUAL_HEX(uint16_t(0x68AC), b.extract( 7, 16)); + CHECK_EQUAL_HEX(uint16_t(0x3456), b.extract( 8, 16)); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), b.extract( 9, 16)); + CHECK_EQUAL_HEX(uint16_t(0x8D15), b.extract(10, 16)); + CHECK_EQUAL_HEX(uint16_t(0x468A), b.extract(11, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2345), b.extract(12, 16)); + CHECK_EQUAL_HEX(uint16_t(0x91A2), b.extract(13, 16)); + CHECK_EQUAL_HEX(uint16_t(0x48D1), b.extract(14, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2468), b.extract(15, 16)); + CHECK_EQUAL_HEX(uint16_t(0x1234), b.extract(16, 16)); + + CHECK_THROW(b.extract(16, 17), etl::bitset_overflow); + CHECK_THROW(b.extract(17, 16), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_uint16_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint16_t(0x5678), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2B3C), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x8ACF), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x4567), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0xA2B3), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0xD159), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x68AC), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x3456), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x8D15), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x468A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2345), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x91A2), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x48D1), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2468), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1234), (b.extract())); + + // The lines below should static assert. + //uint16_t v1 = b.extract(); + //uint16_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_int16_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(int16_t(0x5678), b.extract(0, 16)); + CHECK_EQUAL_HEX(int16_t(0x2B3C), b.extract(1, 16)); + CHECK_EQUAL_HEX(int16_t(0x159E), b.extract(2, 16)); + CHECK_EQUAL_HEX(int16_t(0x8ACF), b.extract(3, 16)); + CHECK_EQUAL_HEX(int16_t(0x4567), b.extract(4, 16)); + CHECK_EQUAL_HEX(int16_t(0xA2B3), b.extract(5, 16)); + CHECK_EQUAL_HEX(int16_t(0xD159), b.extract(6, 16)); + CHECK_EQUAL_HEX(int16_t(0x68AC), b.extract(7, 16)); + CHECK_EQUAL_HEX(int16_t(0x3456), b.extract(8, 16)); + CHECK_EQUAL_HEX(int16_t(0x1A2B), b.extract(9, 16)); + CHECK_EQUAL_HEX(int16_t(0x8D15), b.extract(10, 16)); + CHECK_EQUAL_HEX(int16_t(0x468A), b.extract(11, 16)); + CHECK_EQUAL_HEX(int16_t(0x2345), b.extract(12, 16)); + CHECK_EQUAL_HEX(int16_t(0x91A2), b.extract(13, 16)); + CHECK_EQUAL_HEX(int16_t(0x48D1), b.extract(14, 16)); + CHECK_EQUAL_HEX(int16_t(0x2468), b.extract(15, 16)); + CHECK_EQUAL_HEX(int16_t(0x1234), b.extract(16, 16)); + + CHECK_THROW(b.extract(16, 17), etl::bitset_overflow); + CHECK_THROW(b.extract(17, 16), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_int16_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(int16_t(0x5678), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2B3C), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x8ACF), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x4567), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0xA2B3), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0xD159), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x68AC), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x3456), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x8D15), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x468A), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2345), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x91A2), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x48D1), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2468), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x1234), (b.extract())); + + // The lines below should static assert. + //int16_t v1 = b.extract()); + //int16_t v2 = b.extract()); } }; } diff --git a/test/test_bitset_new_explicit_single_element_type.cpp b/test/test_bitset_new_explicit_single_element_type.cpp index 0f25e6da..8e161389 100644 --- a/test/test_bitset_new_explicit_single_element_type.cpp +++ b/test/test_bitset_new_explicit_single_element_type.cpp @@ -1587,7 +1587,7 @@ namespace } //************************************************************************* - TEST(test_extract_with_run_time_parameters) + TEST(test_extract_uint8_t_with_run_time_parameters) { ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); @@ -1620,7 +1620,7 @@ namespace } //************************************************************************* - TEST(test_extract_with_template_parameters) + TEST(test_extract_uint8_t_with_template_parameters) { ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); diff --git a/test/test_bitset_new_ext_default_element_type.cpp b/test/test_bitset_new_ext_default_element_type.cpp index c5e12541..7e377a95 100644 --- a/test/test_bitset_new_ext_default_element_type.cpp +++ b/test/test_bitset_new_ext_default_element_type.cpp @@ -1959,7 +1959,7 @@ namespace } //************************************************************************* - TEST(test_extract_with_run_time_parameters) + TEST(test_extract_uint8_t_with_run_time_parameters) { using bs32 = etl::bitset_ext<32>; @@ -1994,7 +1994,7 @@ namespace } //************************************************************************* - TEST(test_extract_with_template_parameters) + TEST(test_extract_uint8_t_with_template_parameters) { using bs32 = etl::bitset_ext<32>; diff --git a/test/test_bitset_new_ext_explicit_single_element_type.cpp b/test/test_bitset_new_ext_explicit_single_element_type.cpp index 308259a4..d0b489be 100644 --- a/test/test_bitset_new_ext_explicit_single_element_type.cpp +++ b/test/test_bitset_new_ext_explicit_single_element_type.cpp @@ -1311,7 +1311,7 @@ namespace } //************************************************************************* - TEST(test_extract_with_run_time_parameters) + TEST(test_extract_uint8_t_with_run_time_parameters) { using bs32 = etl::bitset_ext<32, int32_t>; @@ -1346,7 +1346,7 @@ namespace } //************************************************************************* - TEST(test_extract_with_template_parameters) + TEST(test_extract_uint8_t_with_template_parameters) { using bs32 = etl::bitset_ext<32, int32_t>; From 9064eecee2b11e2faab861856dd6d3497f1d9405 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 2 Dec 2023 17:46:38 +0000 Subject: [PATCH 4/8] Work in progress for etl::bitset::extract --- include/etl/private/bitset_new.h | 148 ++++++++++-------- test/test_bitset_new_default_element_type.cpp | 77 +++++++++ test/vs2022/etl.vcxproj.filters | 32 +++- 3 files changed, 182 insertions(+), 75 deletions(-) diff --git a/include/etl/private/bitset_new.h b/include/etl/private/bitset_new.h index 4dbfbef8..65128c75 100644 --- a/include/etl/private/bitset_new.h +++ b/include/etl/private/bitset_new.h @@ -401,12 +401,62 @@ namespace etl return v; } + //************************************************************************* + /// Extract an value from multiple elements. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::make_unsigned::type extract_from_multiple_elements(const element_type* pbuffer, + int element_index, + size_t active_bits_in_msb, + size_t length) const ETL_NOEXCEPT + { + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value(0); + + // Extract the first element, if partially filled. + if (active_bits_in_msb < Bits_Per_Element) + { + element_type mask = ~(~element_type(0) << active_bits_in_msb); + value = pbuffer[element_index] & mask; + length -= active_bits_in_msb; + if (length >= Bits_Per_Element) + { + value = value << Bits_Per_Element; + } + --element_index; + } + + // Loop through the fully filled elements + while (length >= Bits_Per_Element) + { + value |= pbuffer[element_index]; + length -= Bits_Per_Element; + if (length >= Bits_Per_Element) + { + value = value << Bits_Per_Element; + } + --element_index; + } + + // Extract the last element, if partially filled. + if (length != 0) + { + value = value << length; + element_type mask = ~(~element_type(0) << length); + value |= (pbuffer[element_index] >> (Bits_Per_Element - length)) & mask; + } + + return value; + } + //************************************************************************* /// Extract an integral value from an arbitary position and length. //************************************************************************* template ETL_CONSTEXPR14 - T extract_from_buffer(const_pointer pbuffer, size_t position, size_t length) const ETL_NOEXCEPT + typename etl::make_unsigned::type extract_from_buffer(const_pointer pbuffer, size_t position, size_t length) const ETL_NOEXCEPT { typedef typename etl::make_unsigned::type unsigned_t; @@ -428,37 +478,13 @@ namespace etl // Get the number of active bits in the msb element size_t active_bits_in_msb = (position + length) - (Msb_Element_Index * Bits_Per_Element); - // Extract the first element if partially filled. // Start with index of the element containing the msb. int element_index = Msb_Element_Index; - if (active_bits_in_msb < Bits_Per_Element) - { - element_type mask = ~(~element_type(0) << active_bits_in_msb); - value |= pbuffer[element_index] & mask; - length -= active_bits_in_msb; - --element_index; - } - - // Loop through the fully filled elements - while (length >= Bits_Per_Element) - { - value <<= Bits_Per_Element; - value |= pbuffer[element_index]; - length -= Bits_Per_Element; - --element_index; - } - - // Check if the last element is partially filled and extract. - if (length != 0) - { - value <<= length; - element_type mask = ~(~element_type(0) << length); - value |= (pbuffer[element_index] >> (Bits_Per_Element - length)) & mask; - } + value = extract_from_multiple_elements(pbuffer, element_index, active_bits_in_msb, length); } - return static_cast(value); + return value; } //************************************************************************* @@ -466,7 +492,7 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - typename etl::enable_if::value, T>::type + typename etl::enable_if::value, typename etl::make_unsigned::type>::type extract_from_buffer(const_pointer pbuffer) const { typedef typename etl::make_unsigned::type unsigned_t; @@ -475,9 +501,7 @@ namespace etl const unsigned_t Mask = ~(~0 << Length); const unsigned_t Shift = Position % Bits_Per_Element; - unsigned_t value = static_cast(pbuffer[Element_Index] >> Shift) & Mask; - - return static_cast(value); + return static_cast(pbuffer[Element_Index] >> Shift) & Mask; } //************************************************************************* @@ -485,13 +509,11 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - typename etl::enable_if::value, T>::type + typename etl::enable_if::value, typename etl::make_unsigned::type>::type extract_from_buffer(const_pointer pbuffer) const { typedef typename etl::make_unsigned::type unsigned_t; - - unsigned_t value(0); - + const int Msb_Element_Index = (Position + Length - 1) >> etl::log2::value; // Start with index of the element containing the msb. @@ -501,35 +523,9 @@ namespace etl size_t length = Length; // Get the number of active bits in the first element - size_t active_bits_in_element = ((Position + Length - 1) % Bits_Per_Element) + 1; + size_t active_bits_in_msb = ((Position + Length - 1) % Bits_Per_Element) + 1; - // Extract the first element if partially filled. - if (active_bits_in_element < Bits_Per_Element) - { - element_type mask = ~(~element_type(0) << active_bits_in_element); - value |= pbuffer[element_index] & mask; - length -= active_bits_in_element; - --element_index; - } - - // Loop through the fully filled elements - while (length >= Bits_Per_Element) - { - value <<= Bits_Per_Element; - value |= pbuffer[element_index]; - length -= Bits_Per_Element; - --element_index; - } - - // Check if the last element is partially filled and extract. - if (length != 0) - { - value <<= length; - element_type mask = ~(~element_type(0) << length); - value |= (pbuffer[element_index] >> (Bits_Per_Element - length)) & mask; - } - - return static_cast(value); + return extract_from_multiple_elements(pbuffer, element_index, active_bits_in_msb, length); } //************************************************************************* @@ -2208,7 +2204,16 @@ namespace etl { ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); - return ibitset.extract_from_buffer(buffer, position, length); + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value = ibitset.template extract_from_buffer(buffer, position, length);; + + if ((length != etl::integral_limits::bits) && etl::integral_limits::is_signed) + { + value = etl::sign_extend(value, length); + } + + return value; } //************************************************************************* @@ -2221,7 +2226,16 @@ namespace etl { ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); - return ibitset.extract_from_buffer(buffer); + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value = ibitset.template extract_from_buffer(buffer); + + if ETL_IF_CONSTEXPR((Length != etl::integral_limits::bits) && etl::integral_limits::is_signed) + { + value = etl::sign_extend(value); + } + + return value; } //************************************************************************* @@ -3981,7 +3995,7 @@ namespace etl { ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); - return ibitset.extract_from_buffer(pbuffer, position, length); + return ibitset.template extract_from_buffer(pbuffer, position, length); } //************************************************************************* @@ -3994,7 +4008,7 @@ namespace etl { ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); - return ibitset.extract_from_buffer(pbuffer); + return ibitset.template extract_from_buffer(pbuffer); } //************************************************************************* diff --git a/test/test_bitset_new_default_element_type.cpp b/test/test_bitset_new_default_element_type.cpp index 199e18a0..a0980425 100644 --- a/test/test_bitset_new_default_element_type.cpp +++ b/test/test_bitset_new_default_element_type.cpp @@ -2172,6 +2172,83 @@ namespace //uint8_t v1 = b.extract(); } + //************************************************************************* + TEST(test_extract_6_bit_int8_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + auto v = b.extract(1, 6); + + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract(0, 6))); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract(1, 6))); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract(2, 6))); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract(3, 6))); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract(4, 6))); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract(5, 6))); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract(6, 6))); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract(7, 6))); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract(8, 6))); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract(9, 6))); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract(10, 6))); + CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract(11, 6))); + CHECK_EQUAL_HEX(int8_t(0x05), (b.extract(12, 6))); + CHECK_EQUAL_HEX(int8_t(0xE2), (b.extract(13, 6))); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract(14, 6))); + CHECK_EQUAL_HEX(int8_t(0xE8), (b.extract(15, 6))); + CHECK_EQUAL_HEX(int8_t(0xF4), (b.extract(16, 6))); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract(17, 6))); + CHECK_EQUAL_HEX(int8_t(0x0D), (b.extract(18, 6))); + CHECK_EQUAL_HEX(int8_t(0x06), (b.extract(19, 6))); + CHECK_EQUAL_HEX(int8_t(0xE3), (b.extract(20, 6))); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract(21, 6))); + CHECK_EQUAL_HEX(int8_t(0x08), (b.extract(22, 6))); + CHECK_EQUAL_HEX(int8_t(0xE4), (b.extract(23, 6))); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract(24, 6))); + CHECK_EQUAL_HEX(int8_t(0x09), (b.extract(25, 6))); + CHECK_EQUAL_HEX(int8_t(0x04), (b.extract(26, 6))); + + CHECK_THROW(b.extract(26, 7), etl::bitset_overflow); + CHECK_THROW(b.extract(27, 6), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_6_bit_int8_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x05), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE2), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF4), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0D), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x06), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x08), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE4), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x09), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x04), (b.extract())); + + // The lines below should static assert. + //int8_t v1 = b.extract(); + //int8_t v1 = b.extract(); + } + //************************************************************************* TEST(test_extract_uint8_t_with_run_time_parameters) { diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index cea19458..5430cd00 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -3400,14 +3400,30 @@ Tests\Scripts - - - - - - - - + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + From 18a1c76ec67531e170e0e218db1f5bdc8d0a473e Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 2 Dec 2023 17:46:38 +0000 Subject: [PATCH 5/8] Work in progress for etl::bitset::extract --- include/etl/private/bitset_new.h | 148 ++++++++++-------- test/run-tests.sh | 2 +- test/test_bitset_new_default_element_type.cpp | 77 +++++++++ test/vs2022/etl.vcxproj.filters | 32 +++- 4 files changed, 183 insertions(+), 76 deletions(-) diff --git a/include/etl/private/bitset_new.h b/include/etl/private/bitset_new.h index 4dbfbef8..65128c75 100644 --- a/include/etl/private/bitset_new.h +++ b/include/etl/private/bitset_new.h @@ -401,12 +401,62 @@ namespace etl return v; } + //************************************************************************* + /// Extract an value from multiple elements. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::make_unsigned::type extract_from_multiple_elements(const element_type* pbuffer, + int element_index, + size_t active_bits_in_msb, + size_t length) const ETL_NOEXCEPT + { + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value(0); + + // Extract the first element, if partially filled. + if (active_bits_in_msb < Bits_Per_Element) + { + element_type mask = ~(~element_type(0) << active_bits_in_msb); + value = pbuffer[element_index] & mask; + length -= active_bits_in_msb; + if (length >= Bits_Per_Element) + { + value = value << Bits_Per_Element; + } + --element_index; + } + + // Loop through the fully filled elements + while (length >= Bits_Per_Element) + { + value |= pbuffer[element_index]; + length -= Bits_Per_Element; + if (length >= Bits_Per_Element) + { + value = value << Bits_Per_Element; + } + --element_index; + } + + // Extract the last element, if partially filled. + if (length != 0) + { + value = value << length; + element_type mask = ~(~element_type(0) << length); + value |= (pbuffer[element_index] >> (Bits_Per_Element - length)) & mask; + } + + return value; + } + //************************************************************************* /// Extract an integral value from an arbitary position and length. //************************************************************************* template ETL_CONSTEXPR14 - T extract_from_buffer(const_pointer pbuffer, size_t position, size_t length) const ETL_NOEXCEPT + typename etl::make_unsigned::type extract_from_buffer(const_pointer pbuffer, size_t position, size_t length) const ETL_NOEXCEPT { typedef typename etl::make_unsigned::type unsigned_t; @@ -428,37 +478,13 @@ namespace etl // Get the number of active bits in the msb element size_t active_bits_in_msb = (position + length) - (Msb_Element_Index * Bits_Per_Element); - // Extract the first element if partially filled. // Start with index of the element containing the msb. int element_index = Msb_Element_Index; - if (active_bits_in_msb < Bits_Per_Element) - { - element_type mask = ~(~element_type(0) << active_bits_in_msb); - value |= pbuffer[element_index] & mask; - length -= active_bits_in_msb; - --element_index; - } - - // Loop through the fully filled elements - while (length >= Bits_Per_Element) - { - value <<= Bits_Per_Element; - value |= pbuffer[element_index]; - length -= Bits_Per_Element; - --element_index; - } - - // Check if the last element is partially filled and extract. - if (length != 0) - { - value <<= length; - element_type mask = ~(~element_type(0) << length); - value |= (pbuffer[element_index] >> (Bits_Per_Element - length)) & mask; - } + value = extract_from_multiple_elements(pbuffer, element_index, active_bits_in_msb, length); } - return static_cast(value); + return value; } //************************************************************************* @@ -466,7 +492,7 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - typename etl::enable_if::value, T>::type + typename etl::enable_if::value, typename etl::make_unsigned::type>::type extract_from_buffer(const_pointer pbuffer) const { typedef typename etl::make_unsigned::type unsigned_t; @@ -475,9 +501,7 @@ namespace etl const unsigned_t Mask = ~(~0 << Length); const unsigned_t Shift = Position % Bits_Per_Element; - unsigned_t value = static_cast(pbuffer[Element_Index] >> Shift) & Mask; - - return static_cast(value); + return static_cast(pbuffer[Element_Index] >> Shift) & Mask; } //************************************************************************* @@ -485,13 +509,11 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR14 - typename etl::enable_if::value, T>::type + typename etl::enable_if::value, typename etl::make_unsigned::type>::type extract_from_buffer(const_pointer pbuffer) const { typedef typename etl::make_unsigned::type unsigned_t; - - unsigned_t value(0); - + const int Msb_Element_Index = (Position + Length - 1) >> etl::log2::value; // Start with index of the element containing the msb. @@ -501,35 +523,9 @@ namespace etl size_t length = Length; // Get the number of active bits in the first element - size_t active_bits_in_element = ((Position + Length - 1) % Bits_Per_Element) + 1; + size_t active_bits_in_msb = ((Position + Length - 1) % Bits_Per_Element) + 1; - // Extract the first element if partially filled. - if (active_bits_in_element < Bits_Per_Element) - { - element_type mask = ~(~element_type(0) << active_bits_in_element); - value |= pbuffer[element_index] & mask; - length -= active_bits_in_element; - --element_index; - } - - // Loop through the fully filled elements - while (length >= Bits_Per_Element) - { - value <<= Bits_Per_Element; - value |= pbuffer[element_index]; - length -= Bits_Per_Element; - --element_index; - } - - // Check if the last element is partially filled and extract. - if (length != 0) - { - value <<= length; - element_type mask = ~(~element_type(0) << length); - value |= (pbuffer[element_index] >> (Bits_Per_Element - length)) & mask; - } - - return static_cast(value); + return extract_from_multiple_elements(pbuffer, element_index, active_bits_in_msb, length); } //************************************************************************* @@ -2208,7 +2204,16 @@ namespace etl { ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); - return ibitset.extract_from_buffer(buffer, position, length); + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value = ibitset.template extract_from_buffer(buffer, position, length);; + + if ((length != etl::integral_limits::bits) && etl::integral_limits::is_signed) + { + value = etl::sign_extend(value, length); + } + + return value; } //************************************************************************* @@ -2221,7 +2226,16 @@ namespace etl { ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); - return ibitset.extract_from_buffer(buffer); + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value = ibitset.template extract_from_buffer(buffer); + + if ETL_IF_CONSTEXPR((Length != etl::integral_limits::bits) && etl::integral_limits::is_signed) + { + value = etl::sign_extend(value); + } + + return value; } //************************************************************************* @@ -3981,7 +3995,7 @@ namespace etl { ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); - return ibitset.extract_from_buffer(pbuffer, position, length); + return ibitset.template extract_from_buffer(pbuffer, position, length); } //************************************************************************* @@ -3994,7 +4008,7 @@ namespace etl { ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); - return ibitset.extract_from_buffer(pbuffer); + return ibitset.template extract_from_buffer(pbuffer); } //************************************************************************* diff --git a/test/run-tests.sh b/test/run-tests.sh index 90433c4e..0fa5d720 100644 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -165,7 +165,7 @@ etl_version=$(echo $etl_version_raw | sed -e 's/\r//g') # Remove trailing \r # Get the compiler versions #****************************************************************************** gcc_compiler=$(g++ --version | grep g++) -clang_compiler=$(clang++ --version | grep clang++) +clang_compiler=$(clang++ --version | grep clang) #****************************************************************************** # GCC diff --git a/test/test_bitset_new_default_element_type.cpp b/test/test_bitset_new_default_element_type.cpp index 199e18a0..a0980425 100644 --- a/test/test_bitset_new_default_element_type.cpp +++ b/test/test_bitset_new_default_element_type.cpp @@ -2172,6 +2172,83 @@ namespace //uint8_t v1 = b.extract(); } + //************************************************************************* + TEST(test_extract_6_bit_int8_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + auto v = b.extract(1, 6); + + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract(0, 6))); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract(1, 6))); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract(2, 6))); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract(3, 6))); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract(4, 6))); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract(5, 6))); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract(6, 6))); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract(7, 6))); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract(8, 6))); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract(9, 6))); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract(10, 6))); + CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract(11, 6))); + CHECK_EQUAL_HEX(int8_t(0x05), (b.extract(12, 6))); + CHECK_EQUAL_HEX(int8_t(0xE2), (b.extract(13, 6))); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract(14, 6))); + CHECK_EQUAL_HEX(int8_t(0xE8), (b.extract(15, 6))); + CHECK_EQUAL_HEX(int8_t(0xF4), (b.extract(16, 6))); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract(17, 6))); + CHECK_EQUAL_HEX(int8_t(0x0D), (b.extract(18, 6))); + CHECK_EQUAL_HEX(int8_t(0x06), (b.extract(19, 6))); + CHECK_EQUAL_HEX(int8_t(0xE3), (b.extract(20, 6))); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract(21, 6))); + CHECK_EQUAL_HEX(int8_t(0x08), (b.extract(22, 6))); + CHECK_EQUAL_HEX(int8_t(0xE4), (b.extract(23, 6))); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract(24, 6))); + CHECK_EQUAL_HEX(int8_t(0x09), (b.extract(25, 6))); + CHECK_EQUAL_HEX(int8_t(0x04), (b.extract(26, 6))); + + CHECK_THROW(b.extract(26, 7), etl::bitset_overflow); + CHECK_THROW(b.extract(27, 6), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_6_bit_int8_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); + + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x05), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE2), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF4), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0D), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x06), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x08), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE4), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x09), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x04), (b.extract())); + + // The lines below should static assert. + //int8_t v1 = b.extract(); + //int8_t v1 = b.extract(); + } + //************************************************************************* TEST(test_extract_uint8_t_with_run_time_parameters) { diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index cea19458..5430cd00 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -3400,14 +3400,30 @@ Tests\Scripts - - - - - - - - + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + + + Resource Files\CI\Github + From 5b4e991ee8f978bff79fb93825d92c4ad872695b Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 4 Dec 2023 08:37:10 +0000 Subject: [PATCH 6/8] Added additional etl::make_lsb_mask and etl::make_msb_mask binary functions --- include/etl/binary.h | 35 ++++++- test/test_binary.cpp | 218 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 207 insertions(+), 46 deletions(-) diff --git a/include/etl/binary.h b/include/etl/binary.h index 1efd5f15..f6388562 100644 --- a/include/etl/binary.h +++ b/include/etl/binary.h @@ -2216,20 +2216,31 @@ namespace etl { public: + ETL_STATIC_ASSERT(NBits <= etl::integral_limits::bits, "Mask exceeds type size"); + static ETL_CONSTANT T value = static_cast(etl::max_value_for_nbits::value); }; template ETL_CONSTANT T lsb_mask::value; + //*********************************** + template + ETL_CONSTEXPR T make_lsb_mask() + { + ETL_STATIC_ASSERT(NBits <= etl::integral_limits::bits, "Mask exceeds type size"); + + return lsb_mask::value; + } + //*********************************** template - ETL_CONSTEXPR14 T make_lsb_mask(size_t nbits) + ETL_CONSTEXPR T make_lsb_mask(size_t nbits) { typedef typename etl::make_unsigned::type type; - return (nbits == etl::integral_limits::bits) ? static_cast(etl::integral_limits::max) - : static_cast((static_cast(1U) << nbits) - 1U); + return (nbits == 0U) ? static_cast(0) + : static_cast(static_cast(~0) >> (etl::integral_limits::bits - nbits)); } //*********************************** @@ -2238,6 +2249,8 @@ namespace etl { public: + ETL_STATIC_ASSERT(NBits <= etl::integral_limits::bits, "Mask exceeds type size"); + static ETL_CONSTANT T value = static_cast(etl::reverse_bits_const::value>::value); }; @@ -2246,9 +2259,21 @@ namespace etl //*********************************** template - ETL_CONSTEXPR14 T make_msb_mask(size_t nbits) + ETL_CONSTEXPR T make_msb_mask(size_t nbits) { - return static_cast(etl::reverse_bits(make_lsb_mask(nbits))); + typedef typename etl::make_unsigned::type type; + + return (nbits == 0U) ? static_cast(0) + : static_cast(static_cast(~0) << (etl::integral_limits::bits - nbits)); + } + + //*********************************** + template + ETL_CONSTEXPR T make_msb_mask() + { + ETL_STATIC_ASSERT(NBits <= etl::integral_limits::bits, "Mask exceeds type size"); + + return msb_mask::value; } //*************************************************************************** diff --git a/test/test_binary.cpp b/test/test_binary.cpp index 468758cd..56e5157d 100644 --- a/test/test_binary.cpp +++ b/test/test_binary.cpp @@ -2584,8 +2584,8 @@ namespace //************************************************************************* TEST(test_lsb_mask_64_bit) { - CHECK(int64_t(0x0000000000000000) == (etl::lsb_mask::value)); - CHECK(int64_t(0x00000000000000FF) == (etl::lsb_mask::value)); + CHECK(int64_t(0x0000000000000000) == (etl::lsb_mask::value)); + CHECK(int64_t(0x00000000000000FF) == (etl::lsb_mask::value)); CHECK(int64_t(0x000000000000FFFF) == (etl::lsb_mask::value)); CHECK(int64_t(0x0000000000FFFFFF) == (etl::lsb_mask::value)); CHECK(int64_t(0x00000000FFFFFFFF) == (etl::lsb_mask::value)); @@ -2598,15 +2598,15 @@ namespace //************************************************************************* TEST(test_make_lsb_mask_8_bit) { - ETL_CONSTEXPR14 int8_t mask0 = etl::make_lsb_mask(0); - ETL_CONSTEXPR14 int8_t mask1 = etl::make_lsb_mask(1); - ETL_CONSTEXPR14 int8_t mask2 = etl::make_lsb_mask(2); - ETL_CONSTEXPR14 int8_t mask3 = etl::make_lsb_mask(3); - ETL_CONSTEXPR14 int8_t mask4 = etl::make_lsb_mask(4); - ETL_CONSTEXPR14 int8_t mask5 = etl::make_lsb_mask(5); - ETL_CONSTEXPR14 int8_t mask6 = etl::make_lsb_mask(6); - ETL_CONSTEXPR14 int8_t mask7 = etl::make_lsb_mask(7); - ETL_CONSTEXPR14 int8_t mask8 = etl::make_lsb_mask(8); + ETL_CONSTEXPR int8_t mask0 = etl::make_lsb_mask(0); + ETL_CONSTEXPR int8_t mask1 = etl::make_lsb_mask(1); + ETL_CONSTEXPR int8_t mask2 = etl::make_lsb_mask(2); + ETL_CONSTEXPR int8_t mask3 = etl::make_lsb_mask(3); + ETL_CONSTEXPR int8_t mask4 = etl::make_lsb_mask(4); + ETL_CONSTEXPR int8_t mask5 = etl::make_lsb_mask(5); + ETL_CONSTEXPR int8_t mask6 = etl::make_lsb_mask(6); + ETL_CONSTEXPR int8_t mask7 = etl::make_lsb_mask(7); + ETL_CONSTEXPR int8_t mask8 = etl::make_lsb_mask(8); CHECK(int8_t(etl::b00000000) == mask0); CHECK(int8_t(etl::b00000001) == mask1); @@ -2629,18 +2629,52 @@ namespace CHECK(int8_t(etl::b11111111) == etl::make_lsb_mask(8)); } + //************************************************************************* + TEST(test_make_lsb_mask_template_nbits_8_bit) + { + ETL_CONSTEXPR int8_t mask0 = etl::make_lsb_mask(); + ETL_CONSTEXPR int8_t mask1 = etl::make_lsb_mask(); + ETL_CONSTEXPR int8_t mask2 = etl::make_lsb_mask(); + ETL_CONSTEXPR int8_t mask3 = etl::make_lsb_mask(); + ETL_CONSTEXPR int8_t mask4 = etl::make_lsb_mask(); + ETL_CONSTEXPR int8_t mask5 = etl::make_lsb_mask(); + ETL_CONSTEXPR int8_t mask6 = etl::make_lsb_mask(); + ETL_CONSTEXPR int8_t mask7 = etl::make_lsb_mask(); + ETL_CONSTEXPR int8_t mask8 = etl::make_lsb_mask(); + + CHECK(int8_t(etl::b00000000) == mask0); + CHECK(int8_t(etl::b00000001) == mask1); + CHECK(int8_t(etl::b00000011) == mask2); + CHECK(int8_t(etl::b00000111) == mask3); + CHECK(int8_t(etl::b00001111) == mask4); + CHECK(int8_t(etl::b00011111) == mask5); + CHECK(int8_t(etl::b00111111) == mask6); + CHECK(int8_t(etl::b01111111) == mask7); + CHECK(int8_t(etl::b11111111) == mask8); + + CHECK(int8_t(etl::b00000000) == (etl::make_lsb_mask())); + CHECK(int8_t(etl::b00000001) == (etl::make_lsb_mask())); + CHECK(int8_t(etl::b00000011) == (etl::make_lsb_mask())); + CHECK(int8_t(etl::b00000111) == (etl::make_lsb_mask())); + CHECK(int8_t(etl::b00001111) == (etl::make_lsb_mask())); + CHECK(int8_t(etl::b00011111) == (etl::make_lsb_mask())); + CHECK(int8_t(etl::b00111111) == (etl::make_lsb_mask())); + CHECK(int8_t(etl::b01111111) == (etl::make_lsb_mask())); + CHECK(int8_t(etl::b11111111) == (etl::make_lsb_mask())); + } + //************************************************************************* TEST(test_make_lsb_mask_64_bit) { - ETL_CONSTEXPR14 int64_t mask0 = etl::make_lsb_mask(0); - ETL_CONSTEXPR14 int64_t mask1 = etl::make_lsb_mask(8); - ETL_CONSTEXPR14 int64_t mask2 = etl::make_lsb_mask(16); - ETL_CONSTEXPR14 int64_t mask3 = etl::make_lsb_mask(24); - ETL_CONSTEXPR14 int64_t mask4 = etl::make_lsb_mask(32); - ETL_CONSTEXPR14 int64_t mask5 = etl::make_lsb_mask(40); - ETL_CONSTEXPR14 int64_t mask6 = etl::make_lsb_mask(48); - ETL_CONSTEXPR14 int64_t mask7 = etl::make_lsb_mask(56); - ETL_CONSTEXPR14 int64_t mask8 = etl::make_lsb_mask(64); + ETL_CONSTEXPR int64_t mask0 = etl::make_lsb_mask(0); + ETL_CONSTEXPR int64_t mask1 = etl::make_lsb_mask(8); + ETL_CONSTEXPR int64_t mask2 = etl::make_lsb_mask(16); + ETL_CONSTEXPR int64_t mask3 = etl::make_lsb_mask(24); + ETL_CONSTEXPR int64_t mask4 = etl::make_lsb_mask(32); + ETL_CONSTEXPR int64_t mask5 = etl::make_lsb_mask(40); + ETL_CONSTEXPR int64_t mask6 = etl::make_lsb_mask(48); + ETL_CONSTEXPR int64_t mask7 = etl::make_lsb_mask(56); + ETL_CONSTEXPR int64_t mask8 = etl::make_lsb_mask(64); CHECK_EQUAL(int64_t(0x0000000000000000), mask0); CHECK_EQUAL(int64_t(0x00000000000000FF), mask1); @@ -2664,7 +2698,41 @@ namespace } //************************************************************************* - TEST(test_msb_mask_8_bit_8_bit) + TEST(test_make_lsb_mask_template_nbits_64_bit) + { + ETL_CONSTEXPR int64_t mask0 = etl::make_lsb_mask(); + ETL_CONSTEXPR int64_t mask1 = etl::make_lsb_mask(); + ETL_CONSTEXPR int64_t mask2 = etl::make_lsb_mask(); + ETL_CONSTEXPR int64_t mask3 = etl::make_lsb_mask(); + ETL_CONSTEXPR int64_t mask4 = etl::make_lsb_mask(); + ETL_CONSTEXPR int64_t mask5 = etl::make_lsb_mask(); + ETL_CONSTEXPR int64_t mask6 = etl::make_lsb_mask(); + ETL_CONSTEXPR int64_t mask7 = etl::make_lsb_mask(); + ETL_CONSTEXPR int64_t mask8 = etl::make_lsb_mask(); + + CHECK_EQUAL(int64_t(0x0000000000000000), mask0); + CHECK_EQUAL(int64_t(0x00000000000000FF), mask1); + CHECK_EQUAL(int64_t(0x000000000000FFFF), mask2); + CHECK_EQUAL(int64_t(0x0000000000FFFFFF), mask3); + CHECK_EQUAL(int64_t(0x00000000FFFFFFFF), mask4); + CHECK_EQUAL(int64_t(0x000000FFFFFFFFFF), mask5); + CHECK_EQUAL(int64_t(0x0000FFFFFFFFFFFF), mask6); + CHECK_EQUAL(int64_t(0x00FFFFFFFFFFFFFF), mask7); + CHECK_EQUAL(int64_t(0xFFFFFFFFFFFFFFFF), mask8); + + CHECK_EQUAL(int64_t(0x0000000000000000), (etl::make_lsb_mask())); + CHECK_EQUAL(int64_t(0x00000000000000FF), (etl::make_lsb_mask())); + CHECK_EQUAL(int64_t(0x000000000000FFFF), (etl::make_lsb_mask())); + CHECK_EQUAL(int64_t(0x0000000000FFFFFF), (etl::make_lsb_mask())); + CHECK_EQUAL(int64_t(0x00000000FFFFFFFF), (etl::make_lsb_mask())); + CHECK_EQUAL(int64_t(0x000000FFFFFFFFFF), (etl::make_lsb_mask())); + CHECK_EQUAL(int64_t(0x0000FFFFFFFFFFFF), (etl::make_lsb_mask())); + CHECK_EQUAL(int64_t(0x00FFFFFFFFFFFFFF), (etl::make_lsb_mask())); + CHECK_EQUAL(int64_t(0xFFFFFFFFFFFFFFFF), (etl::make_lsb_mask())); + } + + //************************************************************************* + TEST(test_msb_mask_8_bit) { CHECK(int8_t(etl::b00000000) == (etl::msb_mask::value)); CHECK(int8_t(etl::b10000000) == (etl::msb_mask::value)); @@ -2680,8 +2748,8 @@ namespace //************************************************************************* TEST(test_msb_mask_64_bit) { - CHECK(int64_t(0x0000000000000000) == (etl::msb_mask::value)); - CHECK(int64_t(0xFF00000000000000) == (etl::msb_mask::value)); + CHECK(int64_t(0x0000000000000000) == (etl::msb_mask::value)); + CHECK(int64_t(0xFF00000000000000) == (etl::msb_mask::value)); CHECK(int64_t(0xFFFF000000000000) == (etl::msb_mask::value)); CHECK(int64_t(0xFFFFFF0000000000) == (etl::msb_mask::value)); CHECK(int64_t(0xFFFFFFFF00000000) == (etl::msb_mask::value)); @@ -2694,15 +2762,15 @@ namespace //************************************************************************* TEST(test_make_msb_mask_8_bit) { - ETL_CONSTEXPR14 int8_t mask0 = etl::make_msb_mask(0); - ETL_CONSTEXPR14 int8_t mask1 = etl::make_msb_mask(1); - ETL_CONSTEXPR14 int8_t mask2 = etl::make_msb_mask(2); - ETL_CONSTEXPR14 int8_t mask3 = etl::make_msb_mask(3); - ETL_CONSTEXPR14 int8_t mask4 = etl::make_msb_mask(4); - ETL_CONSTEXPR14 int8_t mask5 = etl::make_msb_mask(5); - ETL_CONSTEXPR14 int8_t mask6 = etl::make_msb_mask(6); - ETL_CONSTEXPR14 int8_t mask7 = etl::make_msb_mask(7); - ETL_CONSTEXPR14 int8_t mask8 = etl::make_msb_mask(8); + ETL_CONSTEXPR int8_t mask0 = etl::make_msb_mask(0); + ETL_CONSTEXPR int8_t mask1 = etl::make_msb_mask(1); + ETL_CONSTEXPR int8_t mask2 = etl::make_msb_mask(2); + ETL_CONSTEXPR int8_t mask3 = etl::make_msb_mask(3); + ETL_CONSTEXPR int8_t mask4 = etl::make_msb_mask(4); + ETL_CONSTEXPR int8_t mask5 = etl::make_msb_mask(5); + ETL_CONSTEXPR int8_t mask6 = etl::make_msb_mask(6); + ETL_CONSTEXPR int8_t mask7 = etl::make_msb_mask(7); + ETL_CONSTEXPR int8_t mask8 = etl::make_msb_mask(8); CHECK(int8_t(etl::b00000000) == mask0); CHECK(int8_t(etl::b10000000) == mask1); @@ -2725,18 +2793,52 @@ namespace CHECK(int8_t(etl::b11111111) == etl::make_msb_mask(8)); } + //************************************************************************* + TEST(test_make_msb_mask_template_nbits_8_bit) + { + ETL_CONSTEXPR int8_t mask0 = etl::make_msb_mask(); + ETL_CONSTEXPR int8_t mask1 = etl::make_msb_mask(); + ETL_CONSTEXPR int8_t mask2 = etl::make_msb_mask(); + ETL_CONSTEXPR int8_t mask3 = etl::make_msb_mask(); + ETL_CONSTEXPR int8_t mask4 = etl::make_msb_mask(); + ETL_CONSTEXPR int8_t mask5 = etl::make_msb_mask(); + ETL_CONSTEXPR int8_t mask6 = etl::make_msb_mask(); + ETL_CONSTEXPR int8_t mask7 = etl::make_msb_mask(); + ETL_CONSTEXPR int8_t mask8 = etl::make_msb_mask(); + + CHECK(int8_t(etl::b00000000) == mask0); + CHECK(int8_t(etl::b10000000) == mask1); + CHECK(int8_t(etl::b11000000) == mask2); + CHECK(int8_t(etl::b11100000) == mask3); + CHECK(int8_t(etl::b11110000) == mask4); + CHECK(int8_t(etl::b11111000) == mask5); + CHECK(int8_t(etl::b11111100) == mask6); + CHECK(int8_t(etl::b11111110) == mask7); + CHECK(int8_t(etl::b11111111) == mask8); + + CHECK(int8_t(etl::b00000000) == (etl::make_msb_mask())); + CHECK(int8_t(etl::b10000000) == (etl::make_msb_mask())); + CHECK(int8_t(etl::b11000000) == (etl::make_msb_mask())); + CHECK(int8_t(etl::b11100000) == (etl::make_msb_mask())); + CHECK(int8_t(etl::b11110000) == (etl::make_msb_mask())); + CHECK(int8_t(etl::b11111000) == (etl::make_msb_mask())); + CHECK(int8_t(etl::b11111100) == (etl::make_msb_mask())); + CHECK(int8_t(etl::b11111110) == (etl::make_msb_mask())); + CHECK(int8_t(etl::b11111111) == (etl::make_msb_mask())); + } + //************************************************************************* TEST(test_make_msb_mask_64_bit) { - ETL_CONSTEXPR14 int64_t mask0 = etl::make_msb_mask(0); - ETL_CONSTEXPR14 int64_t mask1 = etl::make_msb_mask(8); - ETL_CONSTEXPR14 int64_t mask2 = etl::make_msb_mask(16); - ETL_CONSTEXPR14 int64_t mask3 = etl::make_msb_mask(24); - ETL_CONSTEXPR14 int64_t mask4 = etl::make_msb_mask(32); - ETL_CONSTEXPR14 int64_t mask5 = etl::make_msb_mask(40); - ETL_CONSTEXPR14 int64_t mask6 = etl::make_msb_mask(48); - ETL_CONSTEXPR14 int64_t mask7 = etl::make_msb_mask(56); - ETL_CONSTEXPR14 int64_t mask8 = etl::make_msb_mask(64); + ETL_CONSTEXPR int64_t mask0 = etl::make_msb_mask(0); + ETL_CONSTEXPR int64_t mask1 = etl::make_msb_mask(8); + ETL_CONSTEXPR int64_t mask2 = etl::make_msb_mask(16); + ETL_CONSTEXPR int64_t mask3 = etl::make_msb_mask(24); + ETL_CONSTEXPR int64_t mask4 = etl::make_msb_mask(32); + ETL_CONSTEXPR int64_t mask5 = etl::make_msb_mask(40); + ETL_CONSTEXPR int64_t mask6 = etl::make_msb_mask(48); + ETL_CONSTEXPR int64_t mask7 = etl::make_msb_mask(56); + ETL_CONSTEXPR int64_t mask8 = etl::make_msb_mask(64); CHECK_EQUAL(int64_t(0x0000000000000000), mask0); CHECK_EQUAL(int64_t(0xFF00000000000000), mask1); @@ -2758,6 +2860,40 @@ namespace CHECK_EQUAL(int64_t(0xFFFFFFFFFFFFFF00), etl::make_msb_mask(56)); CHECK_EQUAL(int64_t(0xFFFFFFFFFFFFFFFF), etl::make_msb_mask(64)); } + + //************************************************************************* + TEST(test_make_msb_mask_template_nbits_64_bit) + { + ETL_CONSTEXPR int64_t mask0 = etl::make_msb_mask(); + ETL_CONSTEXPR int64_t mask1 = etl::make_msb_mask(); + ETL_CONSTEXPR int64_t mask2 = etl::make_msb_mask(); + ETL_CONSTEXPR int64_t mask3 = etl::make_msb_mask(); + ETL_CONSTEXPR int64_t mask4 = etl::make_msb_mask(); + ETL_CONSTEXPR int64_t mask5 = etl::make_msb_mask(); + ETL_CONSTEXPR int64_t mask6 = etl::make_msb_mask(); + ETL_CONSTEXPR int64_t mask7 = etl::make_msb_mask(); + ETL_CONSTEXPR int64_t mask8 = etl::make_msb_mask(); + + CHECK_EQUAL(int64_t(0x0000000000000000), mask0); + CHECK_EQUAL(int64_t(0xFF00000000000000), mask1); + CHECK_EQUAL(int64_t(0xFFFF000000000000), mask2); + CHECK_EQUAL(int64_t(0xFFFFFF0000000000), mask3); + CHECK_EQUAL(int64_t(0xFFFFFFFF00000000), mask4); + CHECK_EQUAL(int64_t(0xFFFFFFFFFF000000), mask5); + CHECK_EQUAL(int64_t(0xFFFFFFFFFFFF0000), mask6); + CHECK_EQUAL(int64_t(0xFFFFFFFFFFFFFF00), mask7); + CHECK_EQUAL(int64_t(0xFFFFFFFFFFFFFFFF), mask8); + + CHECK_EQUAL(int64_t(0x0000000000000000), (etl::make_msb_mask())); + CHECK_EQUAL(int64_t(0xFF00000000000000), (etl::make_msb_mask())); + CHECK_EQUAL(int64_t(0xFFFF000000000000), (etl::make_msb_mask())); + CHECK_EQUAL(int64_t(0xFFFFFF0000000000), (etl::make_msb_mask())); + CHECK_EQUAL(int64_t(0xFFFFFFFF00000000), (etl::make_msb_mask())); + CHECK_EQUAL(int64_t(0xFFFFFFFFFF000000), (etl::make_msb_mask())); + CHECK_EQUAL(int64_t(0xFFFFFFFFFFFF0000), (etl::make_msb_mask())); + CHECK_EQUAL(int64_t(0xFFFFFFFFFFFFFF00), (etl::make_msb_mask())); + CHECK_EQUAL(int64_t(0xFFFFFFFFFFFFFFFF), (etl::make_msb_mask())); + } }; } From 11491333844ef7a7b39e1e047a9793a94040881a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 4 Dec 2023 08:37:42 +0000 Subject: [PATCH 7/8] Updated script text --- test/run-syntax-checks.sh | 2 +- test/run-tests.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/run-syntax-checks.sh b/test/run-syntax-checks.sh index 76b5a7eb..2e62336e 100644 --- a/test/run-syntax-checks.sh +++ b/test/run-syntax-checks.sh @@ -32,7 +32,7 @@ PrintHeader() echo " Configuration : $configuration_name " | tee -a log.txt echo " Compiler : $compiler " | tee -a log.txt echo " Language standard : C++$cxx_standard " | tee -a log.txt - echo " ETL Version : $etl_version " | tee -a log.txt + echo " ETL version : $etl_version " | tee -a log.txt echo " Git branch : $(ParseGitBranch) " | tee -a log.txt echo " Processes : ${CMAKE_BUILD_PARALLEL_LEVEL} " | tee -a log.txt echo "============================================================================" | tee -a log.txt diff --git a/test/run-tests.sh b/test/run-tests.sh index 0fa5d720..956d9838 100644 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -43,7 +43,7 @@ PrintHeader() echo " Language standard : C++$cxx_standard " | tee -a log.txt echo " Optimisation : $opt " | tee -a log.txt echo " Sanitizer : $sanitize " | tee -a log.txt - echo " ETL Version : $etl_version " | tee -a log.txt + echo " ETL version : $etl_version " | tee -a log.txt echo " Git branch : $(ParseGitBranch) " | tee -a log.txt echo " Processes : ${CMAKE_BUILD_PARALLEL_LEVEL} " | tee -a log.txt echo "============================================================================" | tee -a log.txt From 305f34fbede50ffa2927c198ca27da6b230a66ba Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 4 Dec 2023 08:37:59 +0000 Subject: [PATCH 8/8] Work in progress for etl::bitset::extract --- include/etl/private/bitset_new.h | 100 +++- test/test_bitset_new_default_element_type.cpp | 82 ++- ...itset_new_explicit_single_element_type.cpp | 498 ++++++++++++++++-- ...st_bitset_new_ext_default_element_type.cpp | 437 ++++++++++++++- ...t_new_ext_explicit_single_element_type.cpp | 441 +++++++++++++++- 5 files changed, 1432 insertions(+), 126 deletions(-) diff --git a/include/etl/private/bitset_new.h b/include/etl/private/bitset_new.h index 65128c75..6894feb9 100644 --- a/include/etl/private/bitset_new.h +++ b/include/etl/private/bitset_new.h @@ -418,7 +418,7 @@ namespace etl // Extract the first element, if partially filled. if (active_bits_in_msb < Bits_Per_Element) { - element_type mask = ~(~element_type(0) << active_bits_in_msb); + element_type mask = etl::make_lsb_mask< element_type>(active_bits_in_msb); value = pbuffer[element_index] & mask; length -= active_bits_in_msb; if (length >= Bits_Per_Element) @@ -444,7 +444,7 @@ namespace etl if (length != 0) { value = value << length; - element_type mask = ~(~element_type(0) << length); + element_type mask = etl::make_lsb_mask< element_type>(length); value |= (pbuffer[element_index] >> (Bits_Per_Element - length)) & mask; } @@ -468,7 +468,7 @@ namespace etl // Is the value contained within one element? if (Msb_Element_Index == Lsb_Element_Index) { - const unsigned_t Mask = ~(~0 << length); + const unsigned_t Mask = etl::make_lsb_mask< unsigned_t>(length); const unsigned_t Shift = position % Bits_Per_Element; value = static_cast(pbuffer[Msb_Element_Index] >> Shift) & Mask; @@ -498,7 +498,7 @@ namespace etl typedef typename etl::make_unsigned::type unsigned_t; const int Element_Index = (Position + Length - 1) >> etl::log2::value; - const unsigned_t Mask = ~(~0 << Length); + const unsigned_t Mask = etl::lsb_mask::value; const unsigned_t Shift = Position % Bits_Per_Element; return static_cast(pbuffer[Element_Index] >> Shift) & Mask; @@ -511,9 +511,7 @@ namespace etl ETL_CONSTEXPR14 typename etl::enable_if::value, typename etl::make_unsigned::type>::type extract_from_buffer(const_pointer pbuffer) const - { - typedef typename etl::make_unsigned::type unsigned_t; - + { const int Msb_Element_Index = (Position + Length - 1) >> etl::log2::value; // Start with index of the element containing the msb. @@ -978,7 +976,7 @@ namespace etl /// Specialisation that uses a single element if the element type is the /// same size as the number of active bits. //*************************************************************************** - template + template class bitset : public bitset_constants<> { public: @@ -1413,10 +1411,19 @@ namespace etl ETL_ASSERT_OR_RETURN_VALUE(length <= etl::integral_limits::bits, ETL_ERROR(bitset_overflow), 0); ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); - element_type mask = (~(~0u << length) << position); - T value((buffer & mask) >> position); + typedef typename etl::make_unsigned::type unsigned_t; - return value; + const unsigned_t Mask = etl::make_lsb_mask< unsigned_t>(length); + const unsigned_t Shift = position % Bits_Per_Element; + + unsigned_t value = static_cast(buffer >> Shift) & Mask; + + if ((length != etl::integral_limits::bits) && etl::integral_limits::is_signed) + { + value = etl::sign_extend(value, length); + } + + return static_cast(value); } //************************************************************************* @@ -1430,10 +1437,19 @@ namespace etl ETL_STATIC_ASSERT(Length <= etl::integral_limits::bits, "Length is larger that the required type"); ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); - element_type mask = (~(~0u << Length) << Position); - T value((buffer & mask) >> Position); + typedef typename etl::make_unsigned::type unsigned_t; - return value; + const unsigned_t Mask = etl::make_lsb_mask(); + const unsigned_t Shift = Position % Bits_Per_Element; + + unsigned_t value = static_cast(buffer >> Shift) & Mask; + + if ETL_IF_CONSTEXPR((Length != etl::integral_limits::bits) && etl::integral_limits::is_signed) + { + value = etl::sign_extend(value); + } + + return static_cast(value); } //************************************************************************* @@ -2213,7 +2229,7 @@ namespace etl value = etl::sign_extend(value, length); } - return value; + return static_cast(value); } //************************************************************************* @@ -2235,7 +2251,7 @@ namespace etl value = etl::sign_extend(value); } - return value; + return static_cast(value); } //************************************************************************* @@ -3202,10 +3218,19 @@ namespace etl { ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); - element_type mask = (~(~0u << length) << position); - T v((*pbuffer & mask) >> position); + typedef typename etl::make_unsigned::type unsigned_t; - return v; + const unsigned_t Mask = etl::make_lsb_mask(length); + const unsigned_t Shift = position % Bits_Per_Element; + + unsigned_t value = static_cast(*pbuffer >> Shift) & Mask; + + if ((length != etl::integral_limits::bits) && etl::integral_limits::is_signed) + { + value = etl::sign_extend(value, length); + } + + return static_cast(value); } //************************************************************************* @@ -3218,10 +3243,19 @@ namespace etl { ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); - element_type mask = (~(~0u << Length) << Position); - T v((*pbuffer & mask) >> Position); + typedef typename etl::make_unsigned::type unsigned_t; - return v; + const unsigned_t Mask = etl::make_lsb_mask(); + const unsigned_t Shift = Position % Bits_Per_Element; + + unsigned_t value = static_cast(*pbuffer >> Shift) & Mask; + + if ETL_IF_CONSTEXPR((Length != etl::integral_limits::bits) && etl::integral_limits::is_signed) + { + value = etl::sign_extend(value); + } + + return static_cast(value); } //************************************************************************* @@ -3995,7 +4029,16 @@ namespace etl { ETL_ASSERT_OR_RETURN_VALUE((position + length) <= Active_Bits, ETL_ERROR(bitset_overflow), 0); - return ibitset.template extract_from_buffer(pbuffer, position, length); + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value = ibitset.template extract_from_buffer(pbuffer, position, length); + + if ((length != etl::integral_limits::bits) && etl::integral_limits::is_signed) + { + value = etl::sign_extend(value, length); + } + + return static_cast(value); } //************************************************************************* @@ -4008,7 +4051,16 @@ namespace etl { ETL_STATIC_ASSERT((Position + Length) <= Active_Bits, "Position/Length overflows bitset"); - return ibitset.template extract_from_buffer(pbuffer); + typedef typename etl::make_unsigned::type unsigned_t; + + unsigned_t value = ibitset.template extract_from_buffer(pbuffer); + + if ETL_IF_CONSTEXPR((Length != etl::integral_limits::bits) && etl::integral_limits::is_signed) + { + value = etl::sign_extend(value); + } + + return static_cast(value); } //************************************************************************* diff --git a/test/test_bitset_new_default_element_type.cpp b/test/test_bitset_new_default_element_type.cpp index a0980425..266243f7 100644 --- a/test/test_bitset_new_default_element_type.cpp +++ b/test/test_bitset_new_default_element_type.cpp @@ -2177,18 +2177,16 @@ namespace { ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); - auto v = b.extract(1, 6); - - CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract(0, 6))); - CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract(1, 6))); - CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract(2, 6))); - CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract(3, 6))); - CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract(4, 6))); - CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract(5, 6))); - CHECK_EQUAL_HEX(int8_t(0x19), (b.extract(6, 6))); - CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract(7, 6))); - CHECK_EQUAL_HEX(int8_t(0x16), (b.extract(8, 6))); - CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract(9, 6))); + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract( 0, 6))); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract( 1, 6))); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract( 2, 6))); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract( 3, 6))); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract( 4, 6))); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract( 5, 6))); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract( 6, 6))); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract( 7, 6))); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract( 8, 6))); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract( 9, 6))); CHECK_EQUAL_HEX(int8_t(0x15), (b.extract(10, 6))); CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract(11, 6))); CHECK_EQUAL_HEX(int8_t(0x05), (b.extract(12, 6))); @@ -2216,16 +2214,16 @@ namespace { ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); - CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract())); - CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract())); - CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract())); - CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract())); - CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract())); - CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract())); - CHECK_EQUAL_HEX(int8_t(0x19), (b.extract())); - CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract())); - CHECK_EQUAL_HEX(int8_t(0x16), (b.extract())); - CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract())); CHECK_EQUAL_HEX(int8_t(0x15), (b.extract())); CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract())); CHECK_EQUAL_HEX(int8_t(0x05), (b.extract())); @@ -2512,16 +2510,16 @@ namespace { ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); - CHECK_EQUAL_HEX(int16_t(0x5678), b.extract(0, 16)); - CHECK_EQUAL_HEX(int16_t(0x2B3C), b.extract(1, 16)); - CHECK_EQUAL_HEX(int16_t(0x159E), b.extract(2, 16)); - CHECK_EQUAL_HEX(int16_t(0x8ACF), b.extract(3, 16)); - CHECK_EQUAL_HEX(int16_t(0x4567), b.extract(4, 16)); - CHECK_EQUAL_HEX(int16_t(0xA2B3), b.extract(5, 16)); - CHECK_EQUAL_HEX(int16_t(0xD159), b.extract(6, 16)); - CHECK_EQUAL_HEX(int16_t(0x68AC), b.extract(7, 16)); - CHECK_EQUAL_HEX(int16_t(0x3456), b.extract(8, 16)); - CHECK_EQUAL_HEX(int16_t(0x1A2B), b.extract(9, 16)); + CHECK_EQUAL_HEX(int16_t(0x5678), b.extract( 0, 16)); + CHECK_EQUAL_HEX(int16_t(0x2B3C), b.extract( 1, 16)); + CHECK_EQUAL_HEX(int16_t(0x159E), b.extract( 2, 16)); + CHECK_EQUAL_HEX(int16_t(0x8ACF), b.extract( 3, 16)); + CHECK_EQUAL_HEX(int16_t(0x4567), b.extract( 4, 16)); + CHECK_EQUAL_HEX(int16_t(0xA2B3), b.extract( 5, 16)); + CHECK_EQUAL_HEX(int16_t(0xD159), b.extract( 6, 16)); + CHECK_EQUAL_HEX(int16_t(0x68AC), b.extract( 7, 16)); + CHECK_EQUAL_HEX(int16_t(0x3456), b.extract( 8, 16)); + CHECK_EQUAL_HEX(int16_t(0x1A2B), b.extract( 9, 16)); CHECK_EQUAL_HEX(int16_t(0x8D15), b.extract(10, 16)); CHECK_EQUAL_HEX(int16_t(0x468A), b.extract(11, 16)); CHECK_EQUAL_HEX(int16_t(0x2345), b.extract(12, 16)); @@ -2539,16 +2537,16 @@ namespace { ETL_CONSTEXPR14 etl::bitset<32> b(0x12345678UL); - CHECK_EQUAL_HEX(int16_t(0x5678), (b.extract())); - CHECK_EQUAL_HEX(int16_t(0x2B3C), (b.extract())); - CHECK_EQUAL_HEX(int16_t(0x159E), (b.extract())); - CHECK_EQUAL_HEX(int16_t(0x8ACF), (b.extract())); - CHECK_EQUAL_HEX(int16_t(0x4567), (b.extract())); - CHECK_EQUAL_HEX(int16_t(0xA2B3), (b.extract())); - CHECK_EQUAL_HEX(int16_t(0xD159), (b.extract())); - CHECK_EQUAL_HEX(int16_t(0x68AC), (b.extract())); - CHECK_EQUAL_HEX(int16_t(0x3456), (b.extract())); - CHECK_EQUAL_HEX(int16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x5678), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2B3C), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x8ACF), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x4567), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0xA2B3), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0xD159), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x68AC), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x3456), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x1A2B), (b.extract())); CHECK_EQUAL_HEX(int16_t(0x8D15), (b.extract())); CHECK_EQUAL_HEX(int16_t(0x468A), (b.extract())); CHECK_EQUAL_HEX(int16_t(0x2345), (b.extract())); diff --git a/test/test_bitset_new_explicit_single_element_type.cpp b/test/test_bitset_new_explicit_single_element_type.cpp index 8e161389..ad8f8fe1 100644 --- a/test/test_bitset_new_explicit_single_element_type.cpp +++ b/test/test_bitset_new_explicit_single_element_type.cpp @@ -1586,36 +1586,188 @@ namespace CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(stdtext.c_str())); } + //************************************************************************* + TEST(test_extract_6_bit_uint8_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint8_t(0x38), (b.extract( 0, 6))); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract( 1, 6))); + CHECK_EQUAL_HEX(uint8_t(0x1E), (b.extract( 2, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0F), (b.extract( 3, 6))); + CHECK_EQUAL_HEX(uint8_t(0x27), (b.extract( 4, 6))); + CHECK_EQUAL_HEX(uint8_t(0x33), (b.extract( 5, 6))); + CHECK_EQUAL_HEX(uint8_t(0x19), (b.extract( 6, 6))); + CHECK_EQUAL_HEX(uint8_t(0x2C), (b.extract( 7, 6))); + CHECK_EQUAL_HEX(uint8_t(0x16), (b.extract( 8, 6))); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract( 9, 6))); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract(10, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0A), (b.extract(11, 6))); + CHECK_EQUAL_HEX(uint8_t(0x05), (b.extract(12, 6))); + CHECK_EQUAL_HEX(uint8_t(0x22), (b.extract(13, 6))); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract(14, 6))); + CHECK_EQUAL_HEX(uint8_t(0x28), (b.extract(15, 6))); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract(16, 6))); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract(17, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0D), (b.extract(18, 6))); + CHECK_EQUAL_HEX(uint8_t(0x06), (b.extract(19, 6))); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract(20, 6))); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract(21, 6))); + CHECK_EQUAL_HEX(uint8_t(0x08), (b.extract(22, 6))); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract(23, 6))); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract(24, 6))); + CHECK_EQUAL_HEX(uint8_t(0x09), (b.extract(25, 6))); + CHECK_EQUAL_HEX(uint8_t(0x04), (b.extract(26, 6))); + + CHECK_THROW(b.extract(26, 7), etl::bitset_overflow); + CHECK_THROW(b.extract(27, 6), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_6_bit_uint8_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint8_t(0x38), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1E), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0F), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x27), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x33), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x19), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x16), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x05), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x22), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x28), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0D), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x06), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x08), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x09), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x04), (b.extract())); + + // The lines below should static assert. + //uint8_t v1 = b.extract(); + //uint8_t v1 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_6_bit_int8_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract( 0, 6))); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract( 1, 6))); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract( 2, 6))); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract( 3, 6))); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract( 4, 6))); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract( 5, 6))); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract( 6, 6))); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract( 7, 6))); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract( 8, 6))); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract( 9, 6))); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract(10, 6))); + CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract(11, 6))); + CHECK_EQUAL_HEX(int8_t(0x05), (b.extract(12, 6))); + CHECK_EQUAL_HEX(int8_t(0xE2), (b.extract(13, 6))); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract(14, 6))); + CHECK_EQUAL_HEX(int8_t(0xE8), (b.extract(15, 6))); + CHECK_EQUAL_HEX(int8_t(0xF4), (b.extract(16, 6))); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract(17, 6))); + CHECK_EQUAL_HEX(int8_t(0x0D), (b.extract(18, 6))); + CHECK_EQUAL_HEX(int8_t(0x06), (b.extract(19, 6))); + CHECK_EQUAL_HEX(int8_t(0xE3), (b.extract(20, 6))); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract(21, 6))); + CHECK_EQUAL_HEX(int8_t(0x08), (b.extract(22, 6))); + CHECK_EQUAL_HEX(int8_t(0xE4), (b.extract(23, 6))); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract(24, 6))); + CHECK_EQUAL_HEX(int8_t(0x09), (b.extract(25, 6))); + CHECK_EQUAL_HEX(int8_t(0x04), (b.extract(26, 6))); + + CHECK_THROW(b.extract(26, 7), etl::bitset_overflow); + CHECK_THROW(b.extract(27, 6), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_6_bit_int8_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x05), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE2), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF4), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0D), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x06), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x08), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE4), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x09), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x04), (b.extract())); + + // The lines below should static assert. + //int8_t v1 = b.extract(); + //int8_t v1 = b.extract(); + } + //************************************************************************* TEST(test_extract_uint8_t_with_run_time_parameters) { ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); - CHECK_EQUAL(0x78, b.extract(0, 8)); - CHECK_EQUAL(0x3C, b.extract(1, 8)); - CHECK_EQUAL(0x9E, b.extract(2, 8)); - CHECK_EQUAL(0xCF, b.extract(3, 8)); - CHECK_EQUAL(0x67, b.extract(4, 8)); - CHECK_EQUAL(0xB3, b.extract(5, 8)); - CHECK_EQUAL(0x59, b.extract(6, 8)); - CHECK_EQUAL(0xAC, b.extract(7, 8)); - CHECK_EQUAL(0x56, b.extract(8, 8)); - CHECK_EQUAL(0x2B, b.extract(9, 8)); - CHECK_EQUAL(0x15, b.extract(10, 8)); - CHECK_EQUAL(0x8A, b.extract(11, 8)); - CHECK_EQUAL(0x45, b.extract(12, 8)); - CHECK_EQUAL(0xA2, b.extract(13, 8)); - CHECK_EQUAL(0xD1, b.extract(14, 8)); - CHECK_EQUAL(0x68, b.extract(15, 8)); - CHECK_EQUAL(0x34, b.extract(16, 8)); - CHECK_EQUAL(0x1A, b.extract(17, 8)); - CHECK_EQUAL(0x8D, b.extract(18, 8)); - CHECK_EQUAL(0x46, b.extract(19, 8)); - CHECK_EQUAL(0x23, b.extract(20, 8)); - CHECK_EQUAL(0x91, b.extract(21, 8)); - CHECK_EQUAL(0x48, b.extract(22, 8)); - CHECK_EQUAL(0x24, b.extract(23, 8)); - CHECK_EQUAL(0x12, b.extract(24, 8)); + CHECK_EQUAL_HEX(uint8_t(0x78), b.extract( 0, 8)); + CHECK_EQUAL_HEX(uint8_t(0x3C), b.extract( 1, 8)); + CHECK_EQUAL_HEX(uint8_t(0x9E), b.extract( 2, 8)); + CHECK_EQUAL_HEX(uint8_t(0xCF), b.extract( 3, 8)); + CHECK_EQUAL_HEX(uint8_t(0x67), b.extract( 4, 8)); + CHECK_EQUAL_HEX(uint8_t(0xB3), b.extract( 5, 8)); + CHECK_EQUAL_HEX(uint8_t(0x59), b.extract( 6, 8)); + CHECK_EQUAL_HEX(uint8_t(0xAC), b.extract( 7, 8)); + CHECK_EQUAL_HEX(uint8_t(0x56), b.extract( 8, 8)); + CHECK_EQUAL_HEX(uint8_t(0x2B), b.extract( 9, 8)); + CHECK_EQUAL_HEX(uint8_t(0x15), b.extract(10, 8)); + CHECK_EQUAL_HEX(uint8_t(0x8A), b.extract(11, 8)); + CHECK_EQUAL_HEX(uint8_t(0x45), b.extract(12, 8)); + CHECK_EQUAL_HEX(uint8_t(0xA2), b.extract(13, 8)); + CHECK_EQUAL_HEX(uint8_t(0xD1), b.extract(14, 8)); + CHECK_EQUAL_HEX(uint8_t(0x68), b.extract(15, 8)); + CHECK_EQUAL_HEX(uint8_t(0x34), b.extract(16, 8)); + CHECK_EQUAL_HEX(uint8_t(0x1A), b.extract(17, 8)); + CHECK_EQUAL_HEX(uint8_t(0x8D), b.extract(18, 8)); + CHECK_EQUAL_HEX(uint8_t(0x46), b.extract(19, 8)); + CHECK_EQUAL_HEX(uint8_t(0x23), b.extract(20, 8)); + CHECK_EQUAL_HEX(uint8_t(0x91), b.extract(21, 8)); + CHECK_EQUAL_HEX(uint8_t(0x48), b.extract(22, 8)); + CHECK_EQUAL_HEX(uint8_t(0x24), b.extract(23, 8)); + CHECK_EQUAL_HEX(uint8_t(0x12), b.extract(24, 8)); + + CHECK_THROW(b.extract(24, 9), etl::bitset_overflow); CHECK_THROW(b.extract(25, 8), etl::bitset_overflow); } @@ -1624,35 +1776,277 @@ namespace { ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); - CHECK_EQUAL(0x78, (b.extract())); - CHECK_EQUAL(0x3C, (b.extract())); - CHECK_EQUAL(0x9E, (b.extract())); - CHECK_EQUAL(0xCF, (b.extract())); - CHECK_EQUAL(0x67, (b.extract())); - CHECK_EQUAL(0xB3, (b.extract())); - CHECK_EQUAL(0x59, (b.extract())); - CHECK_EQUAL(0xAC, (b.extract())); - CHECK_EQUAL(0x56, (b.extract())); - CHECK_EQUAL(0x2B, (b.extract())); - CHECK_EQUAL(0x15, (b.extract())); - CHECK_EQUAL(0x8A, (b.extract())); - CHECK_EQUAL(0x45, (b.extract())); - CHECK_EQUAL(0xA2, (b.extract())); - CHECK_EQUAL(0xD1, (b.extract())); - CHECK_EQUAL(0x68, (b.extract())); - CHECK_EQUAL(0x34, (b.extract())); - CHECK_EQUAL(0x1A, (b.extract())); - CHECK_EQUAL(0x8D, (b.extract())); - CHECK_EQUAL(0x46, (b.extract())); - CHECK_EQUAL(0x23, (b.extract())); - CHECK_EQUAL(0x91, (b.extract())); - CHECK_EQUAL(0x48, (b.extract())); - CHECK_EQUAL(0x24, (b.extract())); - CHECK_EQUAL(0x12, (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x78), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x9E), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xCF), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x67), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xB3), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x59), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xAC), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x56), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x8A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x45), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xA2), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0xD1), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x68), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x8D), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x46), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x91), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x48), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); // The lines below should static assert. - //uint8_t v = b.extract(); - //uint8_t v = b.extract(); + //uint8_t v1 = b.extract(); + //uint8_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_int8_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(int8_t(0x78), b.extract( 0, 8)); + CHECK_EQUAL_HEX(int8_t(0x3C), b.extract( 1, 8)); + CHECK_EQUAL_HEX(int8_t(0x9E), b.extract( 2, 8)); + CHECK_EQUAL_HEX(int8_t(0xCF), b.extract( 3, 8)); + CHECK_EQUAL_HEX(int8_t(0x67), b.extract( 4, 8)); + CHECK_EQUAL_HEX(int8_t(0xB3), b.extract( 5, 8)); + CHECK_EQUAL_HEX(int8_t(0x59), b.extract( 6, 8)); + CHECK_EQUAL_HEX(int8_t(0xAC), b.extract( 7, 8)); + CHECK_EQUAL_HEX(int8_t(0x56), b.extract( 8, 8)); + CHECK_EQUAL_HEX(int8_t(0x2B), b.extract( 9, 8)); + CHECK_EQUAL_HEX(int8_t(0x15), b.extract(10, 8)); + CHECK_EQUAL_HEX(int8_t(0x8A), b.extract(11, 8)); + CHECK_EQUAL_HEX(int8_t(0x45), b.extract(12, 8)); + CHECK_EQUAL_HEX(int8_t(0xA2), b.extract(13, 8)); + CHECK_EQUAL_HEX(int8_t(0xD1), b.extract(14, 8)); + CHECK_EQUAL_HEX(int8_t(0x68), b.extract(15, 8)); + CHECK_EQUAL_HEX(int8_t(0x34), b.extract(16, 8)); + CHECK_EQUAL_HEX(int8_t(0x1A), b.extract(17, 8)); + CHECK_EQUAL_HEX(int8_t(0x8D), b.extract(18, 8)); + CHECK_EQUAL_HEX(int8_t(0x46), b.extract(19, 8)); + CHECK_EQUAL_HEX(int8_t(0x23), b.extract(20, 8)); + CHECK_EQUAL_HEX(int8_t(0x91), b.extract(21, 8)); + CHECK_EQUAL_HEX(int8_t(0x48), b.extract(22, 8)); + CHECK_EQUAL_HEX(int8_t(0x24), b.extract(23, 8)); + CHECK_EQUAL_HEX(int8_t(0x12), b.extract(24, 8)); + + CHECK_THROW(b.extract(24, 9), etl::bitset_overflow); + CHECK_THROW(b.extract(25, 8), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_int8_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(int8_t(0x78), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x9E), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xCF), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x67), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xB3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x59), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xAC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x56), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x8A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x45), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xA2), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xD1), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x68), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x8D), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x46), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x91), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x48), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract())); + + // The lines below should static assert. + //int8_t v1 = b.extract(); + //int8_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_13_bits_uint16_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint16_t(0x1678), b.extract( 0, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0B3C), b.extract( 1, 13)); + CHECK_EQUAL_HEX(uint16_t(0x159E), b.extract( 2, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0ACF), b.extract( 3, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0567), b.extract( 4, 13)); + CHECK_EQUAL_HEX(uint16_t(0x02B3), b.extract( 5, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1159), b.extract( 6, 13)); + CHECK_EQUAL_HEX(uint16_t(0x08AC), b.extract( 7, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1456), b.extract( 8, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), b.extract( 9, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0D15), b.extract(10, 13)); + CHECK_EQUAL_HEX(uint16_t(0x068A), b.extract(11, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0345), b.extract(12, 13)); + CHECK_EQUAL_HEX(uint16_t(0x11A2), b.extract(13, 13)); + CHECK_EQUAL_HEX(uint16_t(0x08D1), b.extract(14, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0468), b.extract(15, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1234), b.extract(16, 13)); + CHECK_EQUAL_HEX(uint16_t(0x091A), b.extract(17, 13)); + CHECK_EQUAL_HEX(uint16_t(0x048D), b.extract(18, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0246), b.extract(19, 13)); + + CHECK_THROW(b.extract(19, 14), etl::bitset_overflow); + CHECK_THROW(b.extract(20, 13), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_13_bits_uint16_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint16_t(0x1678), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0B3C), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0ACF), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0567), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x02B3), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1159), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x08AC), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1456), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0D15), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x068A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0345), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x11A2), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x08D1), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0468), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1234), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x091A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x048D), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0246), (b.extract())); + + // The lines below should static assert. + //uint16_t v1 = b.extract b(0x12345678UL); + + CHECK_EQUAL_HEX(uint16_t(0x5678), b.extract( 0, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2B3C), b.extract( 1, 16)); + CHECK_EQUAL_HEX(uint16_t(0x159E), b.extract( 2, 16)); + CHECK_EQUAL_HEX(uint16_t(0x8ACF), b.extract( 3, 16)); + CHECK_EQUAL_HEX(uint16_t(0x4567), b.extract( 4, 16)); + CHECK_EQUAL_HEX(uint16_t(0xA2B3), b.extract( 5, 16)); + CHECK_EQUAL_HEX(uint16_t(0xD159), b.extract( 6, 16)); + CHECK_EQUAL_HEX(uint16_t(0x68AC), b.extract( 7, 16)); + CHECK_EQUAL_HEX(uint16_t(0x3456), b.extract( 8, 16)); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), b.extract( 9, 16)); + CHECK_EQUAL_HEX(uint16_t(0x8D15), b.extract(10, 16)); + CHECK_EQUAL_HEX(uint16_t(0x468A), b.extract(11, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2345), b.extract(12, 16)); + CHECK_EQUAL_HEX(uint16_t(0x91A2), b.extract(13, 16)); + CHECK_EQUAL_HEX(uint16_t(0x48D1), b.extract(14, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2468), b.extract(15, 16)); + CHECK_EQUAL_HEX(uint16_t(0x1234), b.extract(16, 16)); + + CHECK_THROW(b.extract(16, 17), etl::bitset_overflow); + CHECK_THROW(b.extract(17, 16), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_uint16_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(uint16_t(0x5678), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2B3C), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x8ACF), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x4567), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0xA2B3), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0xD159), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x68AC), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x3456), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x8D15), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x468A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2345), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x91A2), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x48D1), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2468), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1234), (b.extract())); + + // The lines below should static assert. + //uint16_t v1 = b.extract(); + //uint16_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_int16_t_with_run_time_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(int16_t(0x5678), b.extract( 0, 16)); + CHECK_EQUAL_HEX(int16_t(0x2B3C), b.extract( 1, 16)); + CHECK_EQUAL_HEX(int16_t(0x159E), b.extract( 2, 16)); + CHECK_EQUAL_HEX(int16_t(0x8ACF), b.extract( 3, 16)); + CHECK_EQUAL_HEX(int16_t(0x4567), b.extract( 4, 16)); + CHECK_EQUAL_HEX(int16_t(0xA2B3), b.extract( 5, 16)); + CHECK_EQUAL_HEX(int16_t(0xD159), b.extract( 6, 16)); + CHECK_EQUAL_HEX(int16_t(0x68AC), b.extract( 7, 16)); + CHECK_EQUAL_HEX(int16_t(0x3456), b.extract( 8, 16)); + CHECK_EQUAL_HEX(int16_t(0x1A2B), b.extract( 9, 16)); + CHECK_EQUAL_HEX(int16_t(0x8D15), b.extract(10, 16)); + CHECK_EQUAL_HEX(int16_t(0x468A), b.extract(11, 16)); + CHECK_EQUAL_HEX(int16_t(0x2345), b.extract(12, 16)); + CHECK_EQUAL_HEX(int16_t(0x91A2), b.extract(13, 16)); + CHECK_EQUAL_HEX(int16_t(0x48D1), b.extract(14, 16)); + CHECK_EQUAL_HEX(int16_t(0x2468), b.extract(15, 16)); + CHECK_EQUAL_HEX(int16_t(0x1234), b.extract(16, 16)); + + CHECK_THROW(b.extract(16, 17), etl::bitset_overflow); + CHECK_THROW(b.extract(17, 16), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_int16_t_with_template_parameters) + { + ETL_CONSTEXPR14 etl::bitset<32, uint32_t> b(0x12345678UL); + + CHECK_EQUAL_HEX(int16_t(0x5678), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2B3C), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x8ACF), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x4567), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0xA2B3), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0xD159), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x68AC), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x3456), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x8D15), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x468A), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2345), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x91A2), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x48D1), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2468), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x1234), (b.extract())); + + // The lines below should static assert. + //int16_t v1 = b.extract()); + //int16_t v2 = b.extract()); } }; } diff --git a/test/test_bitset_new_ext_default_element_type.cpp b/test/test_bitset_new_ext_default_element_type.cpp index 7e377a95..201e98e6 100644 --- a/test/test_bitset_new_ext_default_element_type.cpp +++ b/test/test_bitset_new_ext_default_element_type.cpp @@ -1958,6 +1958,168 @@ namespace CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(stdtext.c_str())); } + //************************************************************************* + TEST(test_extract_6_bit_uint8_t_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint8_t(0x38), (b.extract( 0, 6))); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract( 1, 6))); + CHECK_EQUAL_HEX(uint8_t(0x1E), (b.extract( 2, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0F), (b.extract( 3, 6))); + CHECK_EQUAL_HEX(uint8_t(0x27), (b.extract( 4, 6))); + CHECK_EQUAL_HEX(uint8_t(0x33), (b.extract( 5, 6))); + CHECK_EQUAL_HEX(uint8_t(0x19), (b.extract( 6, 6))); + CHECK_EQUAL_HEX(uint8_t(0x2C), (b.extract( 7, 6))); + CHECK_EQUAL_HEX(uint8_t(0x16), (b.extract( 8, 6))); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract( 9, 6))); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract(10, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0A), (b.extract(11, 6))); + CHECK_EQUAL_HEX(uint8_t(0x05), (b.extract(12, 6))); + CHECK_EQUAL_HEX(uint8_t(0x22), (b.extract(13, 6))); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract(14, 6))); + CHECK_EQUAL_HEX(uint8_t(0x28), (b.extract(15, 6))); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract(16, 6))); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract(17, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0D), (b.extract(18, 6))); + CHECK_EQUAL_HEX(uint8_t(0x06), (b.extract(19, 6))); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract(20, 6))); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract(21, 6))); + CHECK_EQUAL_HEX(uint8_t(0x08), (b.extract(22, 6))); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract(23, 6))); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract(24, 6))); + CHECK_EQUAL_HEX(uint8_t(0x09), (b.extract(25, 6))); + CHECK_EQUAL_HEX(uint8_t(0x04), (b.extract(26, 6))); + + CHECK_THROW(b.extract(26, 7), etl::bitset_overflow); + CHECK_THROW(b.extract(27, 6), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_6_bit_uint8_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint8_t(0x38), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1E), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0F), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x27), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x33), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x19), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x16), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x05), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x22), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x28), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0D), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x06), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x08), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x09), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x04), (b.extract())); + + // The lines below should static assert. + //uint8_t v1 = b.extract(); + //uint8_t v1 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_6_bit_int8_t_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract( 0, 6))); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract( 1, 6))); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract( 2, 6))); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract( 3, 6))); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract( 4, 6))); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract( 5, 6))); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract( 6, 6))); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract( 7, 6))); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract( 8, 6))); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract( 9, 6))); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract(10, 6))); + CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract(11, 6))); + CHECK_EQUAL_HEX(int8_t(0x05), (b.extract(12, 6))); + CHECK_EQUAL_HEX(int8_t(0xE2), (b.extract(13, 6))); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract(14, 6))); + CHECK_EQUAL_HEX(int8_t(0xE8), (b.extract(15, 6))); + CHECK_EQUAL_HEX(int8_t(0xF4), (b.extract(16, 6))); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract(17, 6))); + CHECK_EQUAL_HEX(int8_t(0x0D), (b.extract(18, 6))); + CHECK_EQUAL_HEX(int8_t(0x06), (b.extract(19, 6))); + CHECK_EQUAL_HEX(int8_t(0xE3), (b.extract(20, 6))); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract(21, 6))); + CHECK_EQUAL_HEX(int8_t(0x08), (b.extract(22, 6))); + CHECK_EQUAL_HEX(int8_t(0xE4), (b.extract(23, 6))); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract(24, 6))); + CHECK_EQUAL_HEX(int8_t(0x09), (b.extract(25, 6))); + CHECK_EQUAL_HEX(int8_t(0x04), (b.extract(26, 6))); + + CHECK_THROW(b.extract(26, 7), etl::bitset_overflow); + CHECK_THROW(b.extract(27, 6), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_6_bit_int8_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x05), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE2), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF4), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0D), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x06), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x08), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE4), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x09), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x04), (b.extract())); + + // The lines below should static assert. + //int8_t v1 = b.extract(); + //int8_t v1 = b.extract(); + } + //************************************************************************* TEST(test_extract_uint8_t_with_run_time_parameters) { @@ -1991,6 +2153,9 @@ namespace CHECK_EQUAL_HEX(uint8_t(0x48), b.extract(22, 8)); CHECK_EQUAL_HEX(uint8_t(0x24), b.extract(23, 8)); CHECK_EQUAL_HEX(uint8_t(0x12), b.extract(24, 8)); + + CHECK_THROW(b.extract(24, 9), etl::bitset_overflow); + CHECK_THROW(b.extract(25, 8), etl::bitset_overflow); } //************************************************************************* @@ -2027,9 +2192,275 @@ namespace CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract())); CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); - // The line below should static assert. - //uint8_t v = b.extract(); - //uint8_t v = b.extract(); + // The lines below should static assert. + //uint8_t v1 = b.extract(); + //uint8_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_int8_t_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int8_t(0x78), b.extract( 0, 8)); + CHECK_EQUAL_HEX(int8_t(0x3C), b.extract( 1, 8)); + CHECK_EQUAL_HEX(int8_t(0x9E), b.extract( 2, 8)); + CHECK_EQUAL_HEX(int8_t(0xCF), b.extract( 3, 8)); + CHECK_EQUAL_HEX(int8_t(0x67), b.extract( 4, 8)); + CHECK_EQUAL_HEX(int8_t(0xB3), b.extract( 5, 8)); + CHECK_EQUAL_HEX(int8_t(0x59), b.extract( 6, 8)); + CHECK_EQUAL_HEX(int8_t(0xAC), b.extract( 7, 8)); + CHECK_EQUAL_HEX(int8_t(0x56), b.extract( 8, 8)); + CHECK_EQUAL_HEX(int8_t(0x2B), b.extract( 9, 8)); + CHECK_EQUAL_HEX(int8_t(0x15), b.extract(10, 8)); + CHECK_EQUAL_HEX(int8_t(0x8A), b.extract(11, 8)); + CHECK_EQUAL_HEX(int8_t(0x45), b.extract(12, 8)); + CHECK_EQUAL_HEX(int8_t(0xA2), b.extract(13, 8)); + CHECK_EQUAL_HEX(int8_t(0xD1), b.extract(14, 8)); + CHECK_EQUAL_HEX(int8_t(0x68), b.extract(15, 8)); + CHECK_EQUAL_HEX(int8_t(0x34), b.extract(16, 8)); + CHECK_EQUAL_HEX(int8_t(0x1A), b.extract(17, 8)); + CHECK_EQUAL_HEX(int8_t(0x8D), b.extract(18, 8)); + CHECK_EQUAL_HEX(int8_t(0x46), b.extract(19, 8)); + CHECK_EQUAL_HEX(int8_t(0x23), b.extract(20, 8)); + CHECK_EQUAL_HEX(int8_t(0x91), b.extract(21, 8)); + CHECK_EQUAL_HEX(int8_t(0x48), b.extract(22, 8)); + CHECK_EQUAL_HEX(int8_t(0x24), b.extract(23, 8)); + CHECK_EQUAL_HEX(int8_t(0x12), b.extract(24, 8)); + + CHECK_THROW(b.extract(24, 9), etl::bitset_overflow); + CHECK_THROW(b.extract(25, 8), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_int8_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int8_t(0x78), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x9E), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xCF), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x67), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xB3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x59), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xAC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x56), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x8A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x45), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xA2), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xD1), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x68), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x8D), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x46), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x91), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x48), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract())); + + // The lines below should static assert. + //int8_t v1 = b.extract(); + //int8_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_13_bits_uint16_t_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint16_t(0x1678), b.extract( 0, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0B3C), b.extract( 1, 13)); + CHECK_EQUAL_HEX(uint16_t(0x159E), b.extract( 2, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0ACF), b.extract( 3, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0567), b.extract( 4, 13)); + CHECK_EQUAL_HEX(uint16_t(0x02B3), b.extract( 5, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1159), b.extract( 6, 13)); + CHECK_EQUAL_HEX(uint16_t(0x08AC), b.extract( 7, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1456), b.extract( 8, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), b.extract( 9, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0D15), b.extract(10, 13)); + CHECK_EQUAL_HEX(uint16_t(0x068A), b.extract(11, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0345), b.extract(12, 13)); + CHECK_EQUAL_HEX(uint16_t(0x11A2), b.extract(13, 13)); + CHECK_EQUAL_HEX(uint16_t(0x08D1), b.extract(14, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0468), b.extract(15, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1234), b.extract(16, 13)); + CHECK_EQUAL_HEX(uint16_t(0x091A), b.extract(17, 13)); + CHECK_EQUAL_HEX(uint16_t(0x048D), b.extract(18, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0246), b.extract(19, 13)); + + CHECK_THROW(b.extract(19, 14), etl::bitset_overflow); + CHECK_THROW(b.extract(20, 13), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_13_bits_uint16_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint16_t(0x1678), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0B3C), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0ACF), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0567), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x02B3), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1159), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x08AC), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1456), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0D15), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x068A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0345), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x11A2), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x08D1), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0468), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1234), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x091A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x048D), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0246), (b.extract())); + + // The lines below should static assert. + //uint16_t v1 = b.extract; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint16_t(0x5678), b.extract( 0, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2B3C), b.extract( 1, 16)); + CHECK_EQUAL_HEX(uint16_t(0x159E), b.extract( 2, 16)); + CHECK_EQUAL_HEX(uint16_t(0x8ACF), b.extract( 3, 16)); + CHECK_EQUAL_HEX(uint16_t(0x4567), b.extract( 4, 16)); + CHECK_EQUAL_HEX(uint16_t(0xA2B3), b.extract( 5, 16)); + CHECK_EQUAL_HEX(uint16_t(0xD159), b.extract( 6, 16)); + CHECK_EQUAL_HEX(uint16_t(0x68AC), b.extract( 7, 16)); + CHECK_EQUAL_HEX(uint16_t(0x3456), b.extract( 8, 16)); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), b.extract( 9, 16)); + CHECK_EQUAL_HEX(uint16_t(0x8D15), b.extract(10, 16)); + CHECK_EQUAL_HEX(uint16_t(0x468A), b.extract(11, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2345), b.extract(12, 16)); + CHECK_EQUAL_HEX(uint16_t(0x91A2), b.extract(13, 16)); + CHECK_EQUAL_HEX(uint16_t(0x48D1), b.extract(14, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2468), b.extract(15, 16)); + CHECK_EQUAL_HEX(uint16_t(0x1234), b.extract(16, 16)); + + CHECK_THROW(b.extract(16, 17), etl::bitset_overflow); + CHECK_THROW(b.extract(17, 16), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_uint16_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint16_t(0x5678), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2B3C), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x8ACF), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x4567), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0xA2B3), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0xD159), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x68AC), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x3456), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x8D15), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x468A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2345), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x91A2), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x48D1), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2468), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1234), (b.extract())); + + // The lines below should static assert. + //uint16_t v1 = b.extract(); + //uint16_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_int16_t_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int16_t(0x5678), b.extract( 0, 16)); + CHECK_EQUAL_HEX(int16_t(0x2B3C), b.extract( 1, 16)); + CHECK_EQUAL_HEX(int16_t(0x159E), b.extract( 2, 16)); + CHECK_EQUAL_HEX(int16_t(0x8ACF), b.extract( 3, 16)); + CHECK_EQUAL_HEX(int16_t(0x4567), b.extract( 4, 16)); + CHECK_EQUAL_HEX(int16_t(0xA2B3), b.extract( 5, 16)); + CHECK_EQUAL_HEX(int16_t(0xD159), b.extract( 6, 16)); + CHECK_EQUAL_HEX(int16_t(0x68AC), b.extract( 7, 16)); + CHECK_EQUAL_HEX(int16_t(0x3456), b.extract( 8, 16)); + CHECK_EQUAL_HEX(int16_t(0x1A2B), b.extract( 9, 16)); + CHECK_EQUAL_HEX(int16_t(0x8D15), b.extract(10, 16)); + CHECK_EQUAL_HEX(int16_t(0x468A), b.extract(11, 16)); + CHECK_EQUAL_HEX(int16_t(0x2345), b.extract(12, 16)); + CHECK_EQUAL_HEX(int16_t(0x91A2), b.extract(13, 16)); + CHECK_EQUAL_HEX(int16_t(0x48D1), b.extract(14, 16)); + CHECK_EQUAL_HEX(int16_t(0x2468), b.extract(15, 16)); + CHECK_EQUAL_HEX(int16_t(0x1234), b.extract(16, 16)); + + CHECK_THROW(b.extract(16, 17), etl::bitset_overflow); + CHECK_THROW(b.extract(17, 16), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_int16_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int16_t(0x5678), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2B3C), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x8ACF), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x4567), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0xA2B3), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0xD159), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x68AC), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x3456), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x8D15), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x468A), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2345), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x91A2), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x48D1), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2468), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x1234), (b.extract())); + + // The lines below should static assert. + //int16_t v1 = b.extract()); + //int16_t v2 = b.extract()); } }; } diff --git a/test/test_bitset_new_ext_explicit_single_element_type.cpp b/test/test_bitset_new_ext_explicit_single_element_type.cpp index d0b489be..163d1865 100644 --- a/test/test_bitset_new_ext_explicit_single_element_type.cpp +++ b/test/test_bitset_new_ext_explicit_single_element_type.cpp @@ -1310,10 +1310,172 @@ namespace CHECK(std::u32string(U"...*..*...**.*...*.*.**..****...") == std::u32string(stdtext.c_str())); } + //************************************************************************* + TEST(test_extract_6_bit_uint8_t_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint8_t(0x38), (b.extract( 0, 6))); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract( 1, 6))); + CHECK_EQUAL_HEX(uint8_t(0x1E), (b.extract( 2, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0F), (b.extract( 3, 6))); + CHECK_EQUAL_HEX(uint8_t(0x27), (b.extract( 4, 6))); + CHECK_EQUAL_HEX(uint8_t(0x33), (b.extract( 5, 6))); + CHECK_EQUAL_HEX(uint8_t(0x19), (b.extract( 6, 6))); + CHECK_EQUAL_HEX(uint8_t(0x2C), (b.extract( 7, 6))); + CHECK_EQUAL_HEX(uint8_t(0x16), (b.extract( 8, 6))); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract( 9, 6))); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract(10, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0A), (b.extract(11, 6))); + CHECK_EQUAL_HEX(uint8_t(0x05), (b.extract(12, 6))); + CHECK_EQUAL_HEX(uint8_t(0x22), (b.extract(13, 6))); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract(14, 6))); + CHECK_EQUAL_HEX(uint8_t(0x28), (b.extract(15, 6))); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract(16, 6))); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract(17, 6))); + CHECK_EQUAL_HEX(uint8_t(0x0D), (b.extract(18, 6))); + CHECK_EQUAL_HEX(uint8_t(0x06), (b.extract(19, 6))); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract(20, 6))); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract(21, 6))); + CHECK_EQUAL_HEX(uint8_t(0x08), (b.extract(22, 6))); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract(23, 6))); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract(24, 6))); + CHECK_EQUAL_HEX(uint8_t(0x09), (b.extract(25, 6))); + CHECK_EQUAL_HEX(uint8_t(0x04), (b.extract(26, 6))); + + CHECK_THROW(b.extract(26, 7), etl::bitset_overflow); + CHECK_THROW(b.extract(27, 6), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_6_bit_uint8_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint8_t(0x38), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1E), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0F), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x27), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x33), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x19), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2C), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x16), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x05), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x22), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x28), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x0D), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x06), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x08), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x09), (b.extract())); + CHECK_EQUAL_HEX(uint8_t(0x04), (b.extract())); + + // The lines below should static assert. + //uint8_t v1 = b.extract(); + //uint8_t v1 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_6_bit_int8_t_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract( 0, 6))); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract( 1, 6))); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract( 2, 6))); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract( 3, 6))); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract( 4, 6))); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract( 5, 6))); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract( 6, 6))); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract( 7, 6))); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract( 8, 6))); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract( 9, 6))); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract(10, 6))); + CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract(11, 6))); + CHECK_EQUAL_HEX(int8_t(0x05), (b.extract(12, 6))); + CHECK_EQUAL_HEX(int8_t(0xE2), (b.extract(13, 6))); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract(14, 6))); + CHECK_EQUAL_HEX(int8_t(0xE8), (b.extract(15, 6))); + CHECK_EQUAL_HEX(int8_t(0xF4), (b.extract(16, 6))); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract(17, 6))); + CHECK_EQUAL_HEX(int8_t(0x0D), (b.extract(18, 6))); + CHECK_EQUAL_HEX(int8_t(0x06), (b.extract(19, 6))); + CHECK_EQUAL_HEX(int8_t(0xE3), (b.extract(20, 6))); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract(21, 6))); + CHECK_EQUAL_HEX(int8_t(0x08), (b.extract(22, 6))); + CHECK_EQUAL_HEX(int8_t(0xE4), (b.extract(23, 6))); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract(24, 6))); + CHECK_EQUAL_HEX(int8_t(0x09), (b.extract(25, 6))); + CHECK_EQUAL_HEX(int8_t(0x04), (b.extract(26, 6))); + + CHECK_THROW(b.extract(26, 7), etl::bitset_overflow); + CHECK_THROW(b.extract(27, 6), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_6_bit_int8_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int8_t(0xF8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xFC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1E), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0F), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE7), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x19), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x16), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xEB), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x05), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE2), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE8), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xF4), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x0D), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x06), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x11), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x08), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xE4), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x09), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x04), (b.extract())); + + // The lines below should static assert. + //int8_t v1 = b.extract(); + //int8_t v1 = b.extract(); + } + //************************************************************************* TEST(test_extract_uint8_t_with_run_time_parameters) { - using bs32 = etl::bitset_ext<32, int32_t>; + using bs32 = etl::bitset_ext<32, uint32_t>; bs32::buffer_type buffer; bs32 b(0x12345678UL, buffer); @@ -1343,12 +1505,15 @@ namespace CHECK_EQUAL_HEX(uint8_t(0x48), b.extract(22, 8)); CHECK_EQUAL_HEX(uint8_t(0x24), b.extract(23, 8)); CHECK_EQUAL_HEX(uint8_t(0x12), b.extract(24, 8)); + + CHECK_THROW(b.extract(24, 9), etl::bitset_overflow); + CHECK_THROW(b.extract(25, 8), etl::bitset_overflow); } //************************************************************************* TEST(test_extract_uint8_t_with_template_parameters) { - using bs32 = etl::bitset_ext<32, int32_t>; + using bs32 = etl::bitset_ext<32, uint32_t>; bs32::buffer_type buffer; bs32 b(0x12345678UL, buffer); @@ -1379,9 +1544,275 @@ namespace CHECK_EQUAL_HEX(uint8_t(0x24), (b.extract())); CHECK_EQUAL_HEX(uint8_t(0x12), (b.extract())); - // The line below should static assert. - //uint8_t v = b.extract(); - //uint8_t v = b.extract(); + // The lines below should static assert. + //uint8_t v1 = b.extract(); + //uint8_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_int8_t_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int8_t(0x78), b.extract( 0, 8)); + CHECK_EQUAL_HEX(int8_t(0x3C), b.extract( 1, 8)); + CHECK_EQUAL_HEX(int8_t(0x9E), b.extract( 2, 8)); + CHECK_EQUAL_HEX(int8_t(0xCF), b.extract( 3, 8)); + CHECK_EQUAL_HEX(int8_t(0x67), b.extract( 4, 8)); + CHECK_EQUAL_HEX(int8_t(0xB3), b.extract( 5, 8)); + CHECK_EQUAL_HEX(int8_t(0x59), b.extract( 6, 8)); + CHECK_EQUAL_HEX(int8_t(0xAC), b.extract( 7, 8)); + CHECK_EQUAL_HEX(int8_t(0x56), b.extract( 8, 8)); + CHECK_EQUAL_HEX(int8_t(0x2B), b.extract( 9, 8)); + CHECK_EQUAL_HEX(int8_t(0x15), b.extract(10, 8)); + CHECK_EQUAL_HEX(int8_t(0x8A), b.extract(11, 8)); + CHECK_EQUAL_HEX(int8_t(0x45), b.extract(12, 8)); + CHECK_EQUAL_HEX(int8_t(0xA2), b.extract(13, 8)); + CHECK_EQUAL_HEX(int8_t(0xD1), b.extract(14, 8)); + CHECK_EQUAL_HEX(int8_t(0x68), b.extract(15, 8)); + CHECK_EQUAL_HEX(int8_t(0x34), b.extract(16, 8)); + CHECK_EQUAL_HEX(int8_t(0x1A), b.extract(17, 8)); + CHECK_EQUAL_HEX(int8_t(0x8D), b.extract(18, 8)); + CHECK_EQUAL_HEX(int8_t(0x46), b.extract(19, 8)); + CHECK_EQUAL_HEX(int8_t(0x23), b.extract(20, 8)); + CHECK_EQUAL_HEX(int8_t(0x91), b.extract(21, 8)); + CHECK_EQUAL_HEX(int8_t(0x48), b.extract(22, 8)); + CHECK_EQUAL_HEX(int8_t(0x24), b.extract(23, 8)); + CHECK_EQUAL_HEX(int8_t(0x12), b.extract(24, 8)); + + CHECK_THROW(b.extract(24, 9), etl::bitset_overflow); + CHECK_THROW(b.extract(25, 8), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_int8_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int8_t(0x78), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x3C), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x9E), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xCF), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x67), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xB3), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x59), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xAC), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x56), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x2B), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x15), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x8A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x45), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xA2), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0xD1), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x68), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x34), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x1A), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x8D), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x46), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x23), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x91), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x48), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x24), (b.extract())); + CHECK_EQUAL_HEX(int8_t(0x12), (b.extract())); + + // The lines below should static assert. + //int8_t v1 = b.extract(); + //int8_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_13_bits_uint16_t_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint16_t(0x1678), b.extract( 0, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0B3C), b.extract( 1, 13)); + CHECK_EQUAL_HEX(uint16_t(0x159E), b.extract( 2, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0ACF), b.extract( 3, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0567), b.extract( 4, 13)); + CHECK_EQUAL_HEX(uint16_t(0x02B3), b.extract( 5, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1159), b.extract( 6, 13)); + CHECK_EQUAL_HEX(uint16_t(0x08AC), b.extract( 7, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1456), b.extract( 8, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), b.extract( 9, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0D15), b.extract(10, 13)); + CHECK_EQUAL_HEX(uint16_t(0x068A), b.extract(11, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0345), b.extract(12, 13)); + CHECK_EQUAL_HEX(uint16_t(0x11A2), b.extract(13, 13)); + CHECK_EQUAL_HEX(uint16_t(0x08D1), b.extract(14, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0468), b.extract(15, 13)); + CHECK_EQUAL_HEX(uint16_t(0x1234), b.extract(16, 13)); + CHECK_EQUAL_HEX(uint16_t(0x091A), b.extract(17, 13)); + CHECK_EQUAL_HEX(uint16_t(0x048D), b.extract(18, 13)); + CHECK_EQUAL_HEX(uint16_t(0x0246), b.extract(19, 13)); + + CHECK_THROW(b.extract(19, 14), etl::bitset_overflow); + CHECK_THROW(b.extract(20, 13), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_13_bits_uint16_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint16_t(0x1678), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0B3C), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0ACF), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0567), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x02B3), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1159), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x08AC), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1456), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0D15), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x068A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0345), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x11A2), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x08D1), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0468), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1234), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x091A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x048D), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x0246), (b.extract())); + + // The lines below should static assert. + //uint16_t v1 = b.extract; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint16_t(0x5678), b.extract( 0, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2B3C), b.extract( 1, 16)); + CHECK_EQUAL_HEX(uint16_t(0x159E), b.extract( 2, 16)); + CHECK_EQUAL_HEX(uint16_t(0x8ACF), b.extract( 3, 16)); + CHECK_EQUAL_HEX(uint16_t(0x4567), b.extract( 4, 16)); + CHECK_EQUAL_HEX(uint16_t(0xA2B3), b.extract( 5, 16)); + CHECK_EQUAL_HEX(uint16_t(0xD159), b.extract( 6, 16)); + CHECK_EQUAL_HEX(uint16_t(0x68AC), b.extract( 7, 16)); + CHECK_EQUAL_HEX(uint16_t(0x3456), b.extract( 8, 16)); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), b.extract( 9, 16)); + CHECK_EQUAL_HEX(uint16_t(0x8D15), b.extract(10, 16)); + CHECK_EQUAL_HEX(uint16_t(0x468A), b.extract(11, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2345), b.extract(12, 16)); + CHECK_EQUAL_HEX(uint16_t(0x91A2), b.extract(13, 16)); + CHECK_EQUAL_HEX(uint16_t(0x48D1), b.extract(14, 16)); + CHECK_EQUAL_HEX(uint16_t(0x2468), b.extract(15, 16)); + CHECK_EQUAL_HEX(uint16_t(0x1234), b.extract(16, 16)); + + CHECK_THROW(b.extract(16, 17), etl::bitset_overflow); + CHECK_THROW(b.extract(17, 16), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_uint16_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(uint16_t(0x5678), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2B3C), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x8ACF), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x4567), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0xA2B3), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0xD159), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x68AC), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x3456), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x8D15), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x468A), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2345), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x91A2), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x48D1), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x2468), (b.extract())); + CHECK_EQUAL_HEX(uint16_t(0x1234), (b.extract())); + + // The lines below should static assert. + //uint16_t v1 = b.extract(); + //uint16_t v2 = b.extract(); + } + + //************************************************************************* + TEST(test_extract_int16_t_with_run_time_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int16_t(0x5678), b.extract( 0, 16)); + CHECK_EQUAL_HEX(int16_t(0x2B3C), b.extract( 1, 16)); + CHECK_EQUAL_HEX(int16_t(0x159E), b.extract( 2, 16)); + CHECK_EQUAL_HEX(int16_t(0x8ACF), b.extract( 3, 16)); + CHECK_EQUAL_HEX(int16_t(0x4567), b.extract( 4, 16)); + CHECK_EQUAL_HEX(int16_t(0xA2B3), b.extract( 5, 16)); + CHECK_EQUAL_HEX(int16_t(0xD159), b.extract( 6, 16)); + CHECK_EQUAL_HEX(int16_t(0x68AC), b.extract( 7, 16)); + CHECK_EQUAL_HEX(int16_t(0x3456), b.extract( 8, 16)); + CHECK_EQUAL_HEX(int16_t(0x1A2B), b.extract( 9, 16)); + CHECK_EQUAL_HEX(int16_t(0x8D15), b.extract(10, 16)); + CHECK_EQUAL_HEX(int16_t(0x468A), b.extract(11, 16)); + CHECK_EQUAL_HEX(int16_t(0x2345), b.extract(12, 16)); + CHECK_EQUAL_HEX(int16_t(0x91A2), b.extract(13, 16)); + CHECK_EQUAL_HEX(int16_t(0x48D1), b.extract(14, 16)); + CHECK_EQUAL_HEX(int16_t(0x2468), b.extract(15, 16)); + CHECK_EQUAL_HEX(int16_t(0x1234), b.extract(16, 16)); + + CHECK_THROW(b.extract(16, 17), etl::bitset_overflow); + CHECK_THROW(b.extract(17, 16), etl::bitset_overflow); + } + + //************************************************************************* + TEST(test_extract_int16_t_with_template_parameters) + { + using bs32 = etl::bitset_ext<32, uint32_t>; + + bs32::buffer_type buffer; + bs32 b(0x12345678UL, buffer); + + CHECK_EQUAL_HEX(int16_t(0x5678), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2B3C), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x159E), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x8ACF), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x4567), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0xA2B3), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0xD159), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x68AC), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x3456), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x1A2B), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x8D15), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x468A), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2345), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x91A2), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x48D1), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x2468), (b.extract())); + CHECK_EQUAL_HEX(int16_t(0x1234), (b.extract())); + + // The lines below should static assert. + //int16_t v1 = b.extract()); + //int16_t v2 = b.extract()); } }; }