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 + + + + + + + +