From ad2f95ac79fc46389ad3cd7d9ea1233fc382df8c Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 20 Jun 2022 09:25:39 +0100 Subject: [PATCH] Optimisations --- include/etl/bit_stream.h | 144 +++++++++------------------------------ 1 file changed, 32 insertions(+), 112 deletions(-) diff --git a/include/etl/bit_stream.h b/include/etl/bit_stream.h index d3169e59..23b82dbf 100644 --- a/include/etl/bit_stream.h +++ b/include/etl/bit_stream.h @@ -653,7 +653,7 @@ namespace etl void write_unchecked(bool value) { unsigned char chunk = value ? 1 : 0; - write_integral(uint32_t(chunk), 1); + write_data(static_cast(chunk), 1); } //*************************************************************************** @@ -682,13 +682,9 @@ namespace etl typename etl::enable_if::value, void>::type write_unchecked(T value, uint_least8_t nbits = CHAR_BIT * sizeof(T)) { - if (stream_endianness == etl::endian::little) - { - value = etl::reverse_bits(value); - value = value >> ((CHAR_BIT * sizeof(T)) - nbits); - } + typedef typename unsigned_type::type unsigned_t; - write_integral(static_cast(value), nbits); + write_data(static_cast(value), nbits); } //*************************************************************************** @@ -712,74 +708,6 @@ namespace etl return success; } - #if ETL_USING_64BIT_TYPES - //*************************************************************************** - /// For signed 64bit integral types - //*************************************************************************** - void write_unchecked(int64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(int64_t)) - { - if (stream_endianness == etl::endian::little) - { - value = etl::reverse_bits(value); - value = value >> ((CHAR_BIT * sizeof(int64_t)) - nbits); - } - - write_integral(uint64_t(value), nbits); - } - - //*************************************************************************** - /// For signed 64bit integral types - //*************************************************************************** - bool write(int64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(uint64_t)) - { - bool success = (available(nbits) > 0U); - - if (success) - { - write_unchecked(value, nbits); - } - else - { - ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow)); - } - - return success; - } - - //*************************************************************************** - /// For unsigned 64bit integral types - //*************************************************************************** - void write_unchecked(uint64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(int64_t)) - { - if (stream_endianness == etl::endian::little) - { - value = etl::reverse_bits(value); - value = value >> ((CHAR_BIT * sizeof(int64_t)) - nbits); - } - - write_integral(uint64_t(value), nbits); - } - - //*************************************************************************** - /// For unsigned 64bit integral types - //*************************************************************************** - bool write(uint64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(uint64_t)) - { - bool success = (available(nbits) > 0U); - - if (success) - { - write_unchecked(value, nbits); - } - else - { - ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow)); - } - - return success; - } - #endif - //*************************************************************************** /// Skip n bits, up to the maximum space available. /// Returns true if the skip was possible. @@ -987,20 +915,41 @@ namespace etl private: //*************************************************************************** - /// For unsigned integral types + /// Defines one of five unsigned types that has the same size as T. //*************************************************************************** - void write_integral(uint32_t value, uint_least8_t nbits) + template + struct unsigned_type { + typedef typename etl::conditional::type>::type>::type>::type type; + }; + + //*************************************************************************** + /// Write a value to the stream. + /// It will be passed one of five unsigned types. + //*************************************************************************** + template + void write_data(T value, uint_least8_t nbits) + { + if (stream_endianness == etl::endian::little) + { + value = etl::reverse_bits(value); + value = value >> ((CHAR_BIT * sizeof(T)) - nbits); + } + // Send the bits to the stream. while (nbits != 0) { unsigned char mask_width = static_cast(etl::min(nbits, bits_available_in_char)); nbits -= mask_width; - uint32_t mask = ((uint32_t(1U) << mask_width) - 1U) << nbits; + T mask = ((T(1U) << mask_width) - 1U) << nbits; // Move chunk to lowest char bits. // Chunks are never larger than one char. - uint32_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width); + T chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width); write_chunk(static_cast(chunk), mask_width); } @@ -1011,35 +960,6 @@ namespace etl } } - #if ETL_USING_64BIT_TYPES - //*************************************************************************** - /// For unsigned integral types. 64bit - //*************************************************************************** - void write_integral(uint64_t value, uint_least8_t nbits) - { - // Send the bits to the stream. - while (nbits != 0) - { - unsigned char mask_width = static_cast(etl::min(nbits, bits_available_in_char)); - nbits -= mask_width; - uint64_t mask = ((uint64_t(1U) << mask_width) - 1U) << nbits; - - // Move chunk to lowest char bits. - // Chunks are never larger than one char. - uint64_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width); - - write_chunk(static_cast(chunk), mask_width); - } - - size_t end_index = char_index; - - if (callback.is_valid()) - { - flush_full_bytes(); - } - } - #endif - //*************************************************************************** /// Write a data chunk to the stream //*************************************************************************** @@ -1334,10 +1254,10 @@ namespace etl struct unsigned_type { typedef typename etl::conditional::type>::type>::type>::type type; + typename etl::conditional::type>::type>::type>::type type; }; //***************************************************************************