Latest updates to bit_stream_reader

This commit is contained in:
John Wellbelove 2022-06-09 15:05:08 +01:00
parent 11b97359fb
commit f88999bb12
6 changed files with 1254 additions and 80 deletions

View File

@ -40,12 +40,41 @@ SOFTWARE.
#include "memory.h"
#include "delegate.h"
#include "span.h"
#include "endianness.h"
#include "optional.h"
#include "exception.h"
#include "error_handler.h"
#include "private/minmax_push.h"
namespace etl
{
//***************************************************************************
/// Exception base for bit streams
//***************************************************************************
class bit_stream_exception : public etl::exception
{
public:
bit_stream_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
///\ingroup string
/// String empty exception.
//***************************************************************************
class bit_stream_overflow : public etl::bit_stream_exception
{
public:
bit_stream_overflow(string_type file_name_, numeric_type line_number_)
: bit_stream_exception(ETL_ERROR_TEXT("bit_stream:overflow", ETL_BIT_STREAM_FILE_ID"A"), file_name_, line_number_)
{
}
};
//***************************************************************************
/// Encodes and decodes bitstreams.
/// Data must be stored in the stream in network order.
@ -109,9 +138,9 @@ namespace etl
//***************************************************************************
void restart()
{
bits_available_in_char = 8;
bits_available_in_char = CHAR_BIT;
char_index = 0U;
bits_remaining = CHAR_BIT * length_chars;
bits_available = CHAR_BIT * length_chars;
}
//***************************************************************************
@ -119,7 +148,7 @@ namespace etl
//***************************************************************************
bool at_end() const
{
return (bits_remaining == 0U);
return (bits_available == 0U);
}
//***************************************************************************
@ -131,7 +160,7 @@ namespace etl
if (pdata != ETL_NULLPTR)
{
if (bits_remaining > 0)
if (bits_available > 0)
{
unsigned char chunk = value ? 1 : 0;
put_integral(uint32_t(chunk), 1);
@ -203,7 +232,7 @@ namespace etl
if (pdata != ETL_NULLPTR)
{
// Do we have enough bits?
if (bits_remaining > 0)
if (bits_available > 0U)
{
value = get_bit();
success = true;
@ -226,7 +255,7 @@ namespace etl
if (pdata != ETL_NULLPTR)
{
// Do we have enough bits?
if (bits_remaining >= nbits)
if (bits_available >= nbits)
{
value = 0;
@ -270,7 +299,7 @@ namespace etl
uint_least8_t nbits = CHAR_BIT * sizeof(T);
// Do we have enough bits?
if (bits_remaining >= nbits)
if (bits_available >= nbits)
{
// Temporary storage.
etl::uninitialized_buffer_of<T, 1U> data;
@ -310,7 +339,7 @@ namespace etl
//***************************************************************************
size_t bits() const
{
return (length_chars * CHAR_BIT) - bits_remaining;
return (length_chars * CHAR_BIT) - bits_available;
}
//***************************************************************************
@ -341,7 +370,7 @@ namespace etl
if (pdata != ETL_NULLPTR)
{
// Do we have enough bits?
if (bits_remaining >= nbits)
if (bits_available >= nbits)
{
// Send the bits to the stream.
while (nbits != 0)
@ -375,7 +404,7 @@ namespace etl
if (pdata != ETL_NULLPTR)
{
// Do we have enough bits?
if (bits_remaining >= nbits)
if (bits_available >= nbits)
{
// Send the bits to the stream.
while (nbits != 0)
@ -507,14 +536,14 @@ namespace etl
bits_available_in_char = 8;
}
bits_remaining -= nbits;
bits_available -= nbits;
}
unsigned char *pdata; ///< The start of the bitstream buffer.
size_t length_chars; ///< The length, in char, of the bitstream buffer.
unsigned char bits_available_in_char; ///< The number of available bits in the current char.
size_t char_index; ///< The index of the char in the bitstream buffer.
size_t bits_remaining; ///< The number of bits still available in the bitstream buffer.
size_t bits_available; ///< The number of bits still available in the bitstream buffer.
};
//***************************************************************************
@ -524,16 +553,16 @@ namespace etl
{
public:
typedef const unsigned char* const_iterator;
typedef etl::span<char> callback_parameter_type;
typedef char value_type;
typedef const value_type* const_iterator;
typedef etl::span<value_type> callback_parameter_type;
typedef etl::delegate<void(callback_parameter_type)> callback_type;
//***************************************************************************
/// Construct from span.
//***************************************************************************
bit_stream_writer(etl::span<char> span_, callback_type callback_ = callback_type())
: pdata(reinterpret_cast<unsigned char*>(span_.begin()))
: pdata(span_.begin())
, length_chars(span_.size_bytes())
, callback(callback_)
{
@ -544,7 +573,7 @@ namespace etl
/// Construct from span.
//***************************************************************************
bit_stream_writer(etl::span<unsigned char> span_, callback_type callback_ = callback_type())
: pdata(span_.begin())
: pdata(reinterpret_cast<char*>(span_.begin()))
, length_chars(span_.size_bytes())
, callback(callback_)
{
@ -555,7 +584,7 @@ namespace etl
/// Construct from range.
//***************************************************************************
bit_stream_writer(void* begin_, void* end_, callback_type callback_ = callback_type())
: pdata(reinterpret_cast<unsigned char*>(begin_))
: pdata(reinterpret_cast<char*>(begin_))
, length_chars(etl::distance(reinterpret_cast<unsigned char*>(begin_), reinterpret_cast<unsigned char*>(end_)))
, callback(callback_)
{
@ -566,7 +595,7 @@ namespace etl
/// Construct from begin and length.
//***************************************************************************
bit_stream_writer(void* begin_, size_t length_chars_, callback_type callback_ = callback_type())
: pdata(reinterpret_cast<unsigned char*>(begin_))
: pdata(reinterpret_cast<char*>(begin_))
, length_chars(length_chars_)
, callback(callback_)
{
@ -578,9 +607,9 @@ namespace etl
//***************************************************************************
void restart()
{
bits_available_in_char = 8;
bits_available_in_char = CHAR_BIT;
char_index = 0U;
bits_remaining = CHAR_BIT * length_chars;
bits_available = CHAR_BIT * length_chars;
}
//***************************************************************************
@ -602,7 +631,7 @@ namespace etl
//***************************************************************************
bool empty() const
{
return (bits_remaining == length_chars);
return (bits_available == length_chars);
}
//***************************************************************************
@ -610,7 +639,7 @@ namespace etl
//***************************************************************************
bool full() const
{
return (bits_remaining == 0U);
return (bits_available == 0U);
}
//***************************************************************************
@ -627,12 +656,15 @@ namespace etl
//***************************************************************************
bool write(bool value)
{
bool success = false;
bool success = (available<1U>() > 0U);
if (available<1U>() > 0U)
if (success)
{
write_unchecked(value);
success = true;
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow));
}
return success;
@ -655,12 +687,15 @@ namespace etl
typename etl::enable_if<etl::is_integral<T>::value, bool>::type
write(T value, uint_least8_t nbits = CHAR_BIT * sizeof(T))
{
bool success = false;
bool success = (available(nbits) > 0U);
if (available(nbits) > 0U)
if (success)
{
write_unchecked(value, nbits);
success = true;
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow));
}
return success;
@ -680,12 +715,15 @@ namespace etl
//***************************************************************************
bool write(int64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(uint64_t))
{
bool success = false;
bool success = (available(nbits) > 0U);
if (available(nbits) > 0U)
if (success)
{
write_unchecked(value, nbits);
success = true;
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow));
}
return success;
@ -704,12 +742,15 @@ namespace etl
//***************************************************************************
bool write(uint64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(uint64_t))
{
bool success = false;
bool success = (available(nbits) > 0U);
if (available(nbits) > 0U)
if (success)
{
write_unchecked(value, nbits);
success = true;
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow));
}
return success;
@ -739,12 +780,15 @@ namespace etl
typename etl::enable_if<etl::is_floating_point<T>::value, bool>::type
write(T value)
{
bool success = false;
if (available<T>())
bool success = available<T>();
if (success)
{
write_unchecked(value);
success = true;
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow));
}
return success;
@ -757,23 +801,24 @@ namespace etl
//***************************************************************************
bool skip(size_t nbits)
{
bool success = true;
bool success = (nbits <= available_bits());
if (nbits > available_bits())
if (success)
{
nbits = available_bits();
success = false;
while (nbits > bits_available_in_char)
{
step(bits_available_in_char);
nbits -= bits_available_in_char;
}
if (nbits != 0U)
{
step(static_cast<unsigned char>(nbits));
}
}
while (nbits > bits_available_in_char)
else
{
step(bits_available_in_char);
nbits -= bits_available_in_char;
}
if (nbits != 0U)
{
step(static_cast<unsigned char>(nbits));
ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow));
}
return success;
@ -804,13 +849,13 @@ namespace etl
}
//***************************************************************************
/// The number of 'bit nbits' available in the stream.
/// The number of multiples of 'Nbits' available in the stream.
/// Compile time.
//***************************************************************************
template <size_t Nbits>
size_t available() const
{
return bits_remaining / Nbits;
return bits_available / Nbits;
}
//***************************************************************************
@ -829,7 +874,7 @@ namespace etl
//***************************************************************************
size_t available(size_t nbits) const
{
return bits_remaining / nbits;
return bits_available / nbits;
}
//***************************************************************************
@ -837,7 +882,7 @@ namespace etl
//***************************************************************************
size_t available_bits() const
{
return bits_remaining;
return bits_available;
}
//***************************************************************************
@ -877,7 +922,7 @@ namespace etl
//***************************************************************************
etl::span<char> used_data() const
{
return etl::span<char>(reinterpret_cast<char*>(pdata), reinterpret_cast<char*>(pdata) + size_bytes());
return etl::span<char>(pdata, pdata + size_bytes());
}
//***************************************************************************
@ -885,7 +930,7 @@ namespace etl
//***************************************************************************
etl::span<char> data() const
{
return etl::span<char>(reinterpret_cast<char*>(pdata), reinterpret_cast<char*>(pdata) + length_chars);
return etl::span<char>(pdata, pdata + length_chars);
}
//***************************************************************************
@ -897,11 +942,11 @@ namespace etl
{
if (bits_available_in_char != 0U)
{
char_index = 1U;
char_index = 1U; // Indicate that the first char is actually 'full'.
flush_full_bytes();
char_index = 0U;
bits_available_in_char = CHAR_BIT;
}
restart();
}
}
@ -939,7 +984,7 @@ namespace etl
// Chunks are never larger than one char.
uint32_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
write_chunk(static_cast<unsigned char>(chunk), mask_width);
write_chunk(static_cast<char>(chunk), mask_width);
}
if (callback.is_valid())
@ -965,7 +1010,7 @@ namespace etl
// Chunks are never larger than one char.
uint64_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
write_chunk(static_cast<unsigned char>(chunk), mask_width);
write_chunk(static_cast<char>(chunk), mask_width);
}
size_t end_index = char_index;
@ -980,7 +1025,7 @@ namespace etl
//***************************************************************************
/// Write a data chunk to the stream
//***************************************************************************
void write_chunk(unsigned char chunk, unsigned char nbits)
void write_chunk(char chunk, unsigned char nbits)
{
// Clear if new byte.
if (bits_available_in_char == CHAR_BIT)
@ -994,19 +1039,22 @@ namespace etl
//***************************************************************************
/// Flush full bytes to the callback, if valid.
/// Resets the
/// Resets the stream to empty or the last unfilled byte.
//***************************************************************************
void flush_full_bytes()
{
// Is the first byte fully filled?
if (char_index > 0U)
{
callback(callback_parameter_type((char*)pdata, (char*)pdata + char_index));
callback(callback_parameter_type(pdata, pdata + char_index));
bits_available = CHAR_BIT * length_chars;
if (bits_available_in_char != 0U)
{
// Move a partially filled last byte to the start of the buffer.
pdata[0] = pdata[char_index];
bits_available -= (CHAR_BIT - bits_available_in_char);
}
char_index = 0U;
@ -1046,15 +1094,15 @@ namespace etl
bits_available_in_char = CHAR_BIT;
}
bits_remaining -= nbits;
bits_available -= nbits;
}
unsigned char* const pdata; ///< The start of the bitstream buffer.
const size_t length_chars; ///< The length, in unsigned char, of the bitstream buffer.
unsigned char bits_available_in_char; ///< The number of available bits in the current char.
size_t char_index; ///< The index of the char in the bitstream buffer.
size_t bits_remaining; ///< The number of bits still available in the bitstream buffer.
callback_type callback; ///< An optional callback on every filled byte on the write buffer.
char* const pdata; ///< The start of the bitstream buffer.
const size_t length_chars; ///< The length of the bitstream buffer.
unsigned char bits_available_in_char; ///< The number of available bits in the current char.
size_t char_index; ///< The index of the current char in the bitstream buffer.
size_t bits_available; ///< The number of bits still available in the bitstream buffer.
callback_type callback; ///< An optional callback on every filled byte in buffer.
};
//***************************************************************************
@ -1069,13 +1117,331 @@ namespace etl
}
//***************************************************************************
/// Implementation of the write function.
/// Default implementation of the write function.
/// For integral and floating point types only.
/// Overload this to support custom types.
//***************************************************************************
template <typename T>
bool write(etl::bit_stream_writer& stream, const T& value, uint_least8_t nbits = CHAR_BIT * sizeof(T))
{
return stream.write(value, nbits);
}
//***************************************************************************
/// Reads bit streams
//***************************************************************************
class bit_stream_reader
{
public:
typedef const char* const_iterator;
//***************************************************************************
/// Construct from span.
//***************************************************************************
bit_stream_reader(etl::span<char> span_)
: pdata(span_.begin())
, length_chars(span_.size_bytes())
{
restart();
}
//***************************************************************************
/// Construct from span.
//***************************************************************************
bit_stream_reader(etl::span<unsigned char> span_)
: pdata(reinterpret_cast<char*>(span_.begin()))
, length_chars(span_.size_bytes())
{
restart();
}
//***************************************************************************
/// Construct from range.
//***************************************************************************
bit_stream_reader(void* begin_, void* end_)
: pdata(reinterpret_cast<char*>(begin_))
, length_chars(etl::distance(reinterpret_cast<char*>(begin_), reinterpret_cast<char*>(end_)))
{
restart();
}
//***************************************************************************
/// Construct from begin and length.
//***************************************************************************
bit_stream_reader(void* begin_, size_t length_)
: pdata(reinterpret_cast<char*>(begin_))
, length_chars(length_)
{
restart();
}
//***************************************************************************
/// Sets the indexes back to the beginning of the stream.
//***************************************************************************
void restart()
{
bits_available_in_char = CHAR_BIT;
char_index = 0U;
bits_available = CHAR_BIT * length_chars;
}
//***************************************************************************
/// For bool types
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<bool, T>::value, bool>::type
read_unchecked()
{
return get_bit();
}
//***************************************************************************
/// For bool types
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<bool, T>::value, etl::optional<bool>>::type
read()
{
etl::optional<bool> result;
if (bits_available > 0U)
{
result = read_unchecked<bool>();
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow));
}
return result;
}
//***************************************************************************
/// For integral types
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_integral<T>::value && !etl::is_same<bool, T>::value, T>::type
read_unchecked(uint_least8_t nbits = CHAR_BIT * sizeof(T))
{
T value = 0;
uint_least8_t bits = nbits;
// Get the bits from the stream.
while (nbits != 0)
{
unsigned char mask_width = static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
typedef typename etl::make_unsigned<T>::type chunk_t;
chunk_t chunk = get_chunk(mask_width);
nbits -= mask_width;
value |= static_cast<T>(chunk << nbits);
}
// Sign extend if signed type and not already full bit width.
if (etl::is_signed<T>::value && (bits != (CHAR_BIT * sizeof(T))))
{
typedef typename etl::make_signed<T>::type ST;
value = etl::sign_extend<ST, ST>(value, bits);
}
return value;
}
//***************************************************************************
/// For integral types
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_integral<T>::value && !etl::is_same<bool, T>::value, etl::optional<T>>::type
read(uint_least8_t nbits = CHAR_BIT * sizeof(T))
{
etl::optional<T> result;
// Do we have enough bits?
if (bits_available >= nbits)
{
result = read_unchecked<T>(nbits);
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow));
}
return result;
}
//***************************************************************************
/// For floating point types
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_floating_point<T>::value, T>::type
read_unchecked()
{
T value = 0;
// Temporary storage.
etl::uninitialized_buffer_of<T, 1U> data;
for (size_t i = 0UL; i < sizeof(T); ++i)
{
get(data.raw[i], CHAR_BIT);
}
from_bytes(reinterpret_cast<const unsigned char*>(data.raw), value);
return success;
}
//***************************************************************************
/// For floating point types
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_floating_point<T>::value, etl::optional<T>>::type
read()
{
uint_least8_t nbits = CHAR_BIT * sizeof(T);
etl::optional<T> result;
// Do we have enough bits?
if (bits_available >= nbits)
{
result = read_unchecked<T>();
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::bit_stream_overflow));
}
return result;
}
//***************************************************************************
/// Returns the number of bytes used in the stream.
//***************************************************************************
size_t size_bytes() const
{
//size_t s = char_index;
//// Current byte is used?
//if (bits_available_in_char != CHAR_BIT)
//{
// ++s;
//}
//return s;
}
//***************************************************************************
/// Returns the number of bits used in the stream.
//***************************************************************************
size_t size_bits() const
{
return (length_chars * CHAR_BIT) - bits_available;
}
//***************************************************************************
/// Returns start of the stream.
//***************************************************************************
const_iterator begin() const
{
return pdata;
}
//***************************************************************************
/// Returns end of the stream.
//***************************************************************************
const_iterator end() const
{
return pdata + size_bytes();
}
private:
//***************************************************************************
/// Get a data chunk from the stream
//***************************************************************************
unsigned char get_chunk(unsigned char nbits)
{
unsigned char value = pdata[char_index];
value >>= (bits_available_in_char - nbits);
unsigned char mask;
if (nbits == CHAR_BIT)
{
mask = etl::integral_limits<unsigned char>::max;
}
else
{
mask = (1U << nbits) - 1;
}
value &= mask;
step(nbits);
return value;
}
//***************************************************************************
/// Get a bool from the stream
//***************************************************************************
bool get_bit()
{
bool result = (pdata[char_index] & (1U << (bits_available_in_char - 1U))) != 0U;
step(1U);
return result;
}
//***************************************************************************
/// Helper function for floating point types
//***************************************************************************
template <typename T>
void from_bytes(const unsigned char* data, T& value)
{
etl::uninitialized_buffer_of<T, 1U> temp;
// Network to host.
if (etl::endianness::value() == etl::endian::little)
{
etl::reverse_copy(data, data + sizeof(T), temp.raw);
}
else
{
etl::copy(data, data + sizeof(T), temp.raw);
}
value = *reinterpret_cast<T*>(temp.raw);
}
//***************************************************************************
/// Step the specified number of bits along the stream.
/// The nbits will never be larger than 'bits_available_in_char'.
//***************************************************************************
void step(unsigned char nbits)
{
bits_available_in_char -= nbits;
if (bits_available_in_char == 0)
{
++char_index;
bits_available_in_char = 8;
}
bits_available -= nbits;
}
char* pdata; ///< The start of the bitstream buffer.
size_t length_chars; ///< The length, in char, of the bitstream buffer.
unsigned char bits_available_in_char; ///< The number of available bits in the current char.
size_t char_index; ///< The index of the char in the bitstream buffer.
size_t bits_available; ///< The number of bits still available in the bitstream buffer.
};
}
#include "private/minmax_pop.h"

View File

@ -95,5 +95,7 @@ SOFTWARE.
#define ETL_MEM_CAST_FILE_ID "62"
#define ETL_SINGLETON_FILE_ID "63"
#define ETL_SUCCESSOR_FILE_ID "64"
#define ETL_BIT_STREAM_FILE_ID "65"
#define ETL_BYTE_STREAM_FILE_ID "66"
#endif

View File

@ -116,10 +116,8 @@ namespace
//*************************************************************************
TEST(test_atomic_bool_load)
{
bool i;
std::atomic<bool> compare(&i);
etl::atomic<bool> test(&i);
std::atomic<bool> compare(true);
etl::atomic<bool> test(true);
CHECK_EQUAL((bool)compare.load(), (bool)test.load());
}

View File

@ -0,0 +1,804 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2018 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "unit_test_framework.h"
#include "etl/bit_stream.h"
#include <array>
#include <numeric>
namespace
{
//***********************************
struct Object
{
int16_t i;
double d;
uint8_t c;
};
bool operator ==(const Object& lhs, const Object& rhs)
{
return (lhs.i == rhs.i) &&
(lhs.d == rhs.d) &&
(lhs.c == rhs.c);
}
std::ostream& operator << (std::ostream& os, const Object& object)
{
os << object.i << "," << object.d << "," << (int)object.c;
return os;
}
}
namespace etl
{
//***********************************
bool read(etl::bit_stream_reader& stream, Object& object)
{
bool success = true;
//if (!stream.object.i, 14))
//{
// success = false;
//}
//if (!stream.get(object.d))
//{
// success = false;
//}
//if (!stream.get(object.c))
//{
// success = false;
//}
return success;
}
}
namespace
{
SUITE(test_bit_stream_reader)
{
//*************************************************************************
TEST(test_read_bool)
{
char storage = 0x5AU;
etl::bit_stream_reader bit_stream(&storage, 1);
etl::optional<bool> result;
result.reset();
result = bit_stream.read<bool>();
CHECK(result.has_value());
CHECK_EQUAL(false, result.value());
result.reset();
result = bit_stream.read<bool>();
CHECK(result.has_value());
CHECK_EQUAL(true, result.value());
result.reset();
result = bit_stream.read<bool>();
CHECK(result.has_value());
CHECK_EQUAL(false, result.value());
result.reset();
result = bit_stream.read<bool>();
CHECK(result.has_value());
CHECK_EQUAL(true, result.value());
result.reset();
result = bit_stream.read<bool>();
CHECK(result.has_value());
CHECK_EQUAL(true, result.value());
result.reset();
result = bit_stream.read<bool>();
CHECK(result.has_value());
CHECK_EQUAL(false, result.value());
result.reset();
result = bit_stream.read<bool>();
CHECK(result.has_value());
CHECK_EQUAL(true, result.value());
result.reset();
result = bit_stream.read<bool>();
CHECK(result.has_value());
CHECK_EQUAL(false, result.value());
// One too many.
CHECK_THROW(bit_stream.read<bool>(), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_int8_t)
{
std::array storage = { char(0x01), char(0x5A), char(0xA5), char(0xFF) };
std::array expected = { int8_t(0x01), int8_t(0x5A), int8_t(0xA5), int8_t(0xFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<int8_t> result;
result.reset();
result = bit_stream.read<int8_t>();
CHECK(result.has_value());
CHECK_EQUAL(int(expected[0]), int(result.value()));
result.reset();
result = bit_stream.read<int8_t>();
CHECK(result.has_value());
CHECK_EQUAL(int(expected[1]), int(result.value()));
result.reset();
result = bit_stream.read<int8_t>();
CHECK(result.has_value());
CHECK_EQUAL(int(expected[2]), int(result.value()));
result.reset();
result = bit_stream.read<int8_t>();
CHECK(result.has_value());
CHECK_EQUAL(int(expected[3]), int(result.value()));
// One too many.
CHECK_THROW(bit_stream.read<int8_t>(), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_int8_t_5bits)
{
std::array storage = { char(0x0E), char(0x8B), char(0xF0) };
std::array expected = { int8_t(0x01), int8_t(0xFA), int8_t(0x05), int8_t(0xFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<int8_t> result;
result.reset();
result = bit_stream.read<int8_t>(5U);
CHECK(result.has_value());
CHECK_EQUAL(int(expected[0]), int(result.value()));
result.reset();
result = bit_stream.read<int8_t>(5U);
CHECK(result.has_value());
CHECK_EQUAL(int(expected[1]), int(result.value()));
result.reset();
result = bit_stream.read<int8_t>(5U);
CHECK(result.has_value());
CHECK_EQUAL(int(expected[2]), int(result.value()));
result.reset();
result = bit_stream.read<int8_t>(5U);
CHECK(result.has_value());
CHECK_EQUAL(int(expected[3]), int(result.value()));
// One too many.
CHECK_THROW(bit_stream.read<int8_t>(5U), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_uint8_t)
{
std::array storage = { char(0x01), char(0x5A), char(0xA5), char(0xFF) };
std::array expected = { uint8_t(0x01), uint8_t(0x5A), uint8_t(0xA5), uint8_t(0xFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<uint8_t> result;
result.reset();
result = bit_stream.read<uint8_t>();
CHECK(result.has_value());
CHECK_EQUAL(int(expected[0]), int(result.value()));
result.reset();
result = bit_stream.read<uint8_t>();
CHECK(result.has_value());
CHECK_EQUAL(int(expected[1]), int(result.value()));
result.reset();
result = bit_stream.read<uint8_t>();
CHECK(result.has_value());
CHECK_EQUAL(int(expected[2]), int(result.value()));
result.reset();
result = bit_stream.read<uint8_t>();
CHECK(result.has_value());
CHECK_EQUAL(int(expected[3]), int(result.value()));
// One too many.
CHECK_THROW(bit_stream.read<uint8_t>(), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_uint8_t_5bits)
{
std::array storage = { char(0x0E), char(0x8B), char(0xF0) };
std::array expected = { uint8_t(0x01), uint8_t(0x1A), uint8_t(0x05), uint8_t(0x1F) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<uint8_t> result;
result.reset();
result = bit_stream.read<uint8_t>(5U);
CHECK(result.has_value());
CHECK_EQUAL(int(expected[0]), int(result.value()));
result.reset();
result = bit_stream.read<uint8_t>(5U);
CHECK(result.has_value());
CHECK_EQUAL(int(expected[1]), int(result.value()));
result.reset();
result = bit_stream.read<uint8_t>(5U);
CHECK(result.has_value());
CHECK_EQUAL(int(expected[2]), int(result.value()));
result.reset();
result = bit_stream.read<uint8_t>(5U);
CHECK(result.has_value());
CHECK_EQUAL(int(expected[3]), int(result.value()));
// One too many.
CHECK_THROW(bit_stream.read<uint8_t>(5U), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_int16_t)
{
std::array storage = { char(0x00), char(0x01), char(0xA5), char(0x5A), char(0x5A), char(0xA5), char(0xFF), char(0xFF) };
std::array expected = { int16_t(0x0001), int16_t(0xA55A), int16_t(0x5AA5), int16_t(0xFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<int16_t> result;
result.reset();
result = bit_stream.read<int16_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<int16_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<int16_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<int16_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<int16_t>(), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_int16_t_10bits)
{
std::array storage = { char(0x00), char(0x55), char(0xAA), char(0x97), char(0xFF) };
std::array expected = { int16_t(0x0001), int16_t(0x015A), int16_t(0xFEA5), int16_t(0xFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<int16_t> result;
result.reset();
result = bit_stream.read<int16_t>(10U);
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<int16_t>(10U);
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<int16_t>(10U);
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<int16_t>(10U);
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<int16_t>(10U), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_uint16_t)
{
std::array storage = { char(0x00), char(0x01), char(0xA5), char(0x5A), char(0x5A), char(0xA5), char(0xFF), char(0xFF) };
std::array expected = { uint16_t(0x0001), uint16_t(0xA55A), uint16_t(0x5AA5), uint16_t(0xFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<uint16_t> result;
result.reset();
result = bit_stream.read<uint16_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<uint16_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<uint16_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<uint16_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<uint16_t>(), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_uint16_t_10bits)
{
std::array storage = { char(0x00), char(0x55), char(0xAA), char(0x97), char(0xFF) };
std::array expected = { uint16_t(0x0001), uint16_t(0x015A), uint16_t(0x02A5), uint16_t(0x03FF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<uint16_t> result;
result.reset();
result = bit_stream.read<uint16_t>(10U);
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<uint16_t>(10U);
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<uint16_t>(10U);
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<uint16_t>(10U);
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<uint16_t>(10U), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_int32_t)
{
std::array storage = { char(0x00), char(0x00), char(0x00), char(0x01),
char(0xA5), char(0x5A), char(0xA5), char(0x5A),
char(0x5A), char(0xA5), char(0x5A), char(0xA5),
char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
std::array expected = { int32_t(0x00000001), int32_t(0xA55AA55A), int32_t(0x5AA55AA5), int32_t(0xFFFFFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<int32_t> result;
result.reset();
result = bit_stream.read<int32_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<int32_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<int32_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<int32_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<int32_t>(), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_int32_t_22bits)
{
std::array storage = { char(0x00), char(0x00), char(0x05), char(0xAA),
char(0x55), char(0xA9), char(0x56), char(0xA9),
char(0x7F), char(0xFF), char(0xFF) };
std::array expected = { int32_t(0x00000001), int32_t(0x001AA55A), int32_t(0xFFE55AA5), int32_t(0xFFFFFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<int32_t> result;
result.reset();
result = bit_stream.read<int32_t>(22U);
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<int32_t>(22U);
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<int32_t>(22U);
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<int32_t>(22U);
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<int32_t>(22U), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_uint32_t)
{
std::array storage = { char(0x00), char(0x00), char(0x00), char(0x01),
char(0xA5), char(0x5A), char(0xA5), char(0x5A),
char(0x5A), char(0xA5), char(0x5A), char(0xA5),
char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
std::array expected = { uint32_t(0x00000001), uint32_t(0xA55AA55A), uint32_t(0x5AA55AA5), uint32_t(0xFFFFFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<uint32_t> result;
result.reset();
result = bit_stream.read<uint32_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<uint32_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<uint32_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<uint32_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<uint32_t>(), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_uint32_t_22bits)
{
std::array storage = { char(0x00), char(0x00), char(0x05), char(0xAA),
char(0x55), char(0xA9), char(0x56), char(0xA9),
char(0x7F), char(0xFF), char(0xFF) };
std::array expected = { uint32_t(0x00000001), uint32_t(0x001AA55A), uint32_t(0x00255AA5), uint32_t(0x003FFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<uint32_t> result;
result.reset();
result = bit_stream.read<uint32_t>(22U);
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<uint32_t>(22U);
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<uint32_t>(22U);
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<uint32_t>(22U);
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<uint32_t>(22U), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_int64_t)
{
std::array storage = { char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x01),
char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0x5A),
char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0xA5),
char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
std::array expected = { int64_t(0x0000000000000001), int64_t(0xA55AA55AA55AA55A), int64_t(0x5AA55AA55AA55AA5), int64_t(0xFFFFFFFFFFFFFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<int64_t> result;
result.reset();
result = bit_stream.read<int64_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<int64_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<int64_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<int64_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<int64_t>(), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_int64_t_47bits)
{
std::array storage = { char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x02), char(0x95), char(0x6A),
char(0x95), char(0x6A), char(0x95), char(0x6A), char(0xD5), char(0x2A), char(0xD5), char(0x2A),
char(0xD5), char(0x2F), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xF0) };
std::array expected = { int64_t(0x0000000000000001), int64_t(0x0000255AA55AA55A), int64_t(0xFFFFDAA55AA55AA5), int64_t(0xFFFFFFFFFFFFFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<int64_t> result;
result.reset();
result = bit_stream.read<int64_t>(47U);
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<int64_t>(47U);
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<int64_t>(47U);
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<int64_t>(47U);
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<int64_t>(47U), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_uint64_t)
{
std::array storage = { char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x01),
char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0x5A),
char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0xA5),
char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
std::array expected = { uint64_t(0x0000000000000001), uint64_t(0xA55AA55AA55AA55A), uint64_t(0x5AA55AA55AA55AA5), uint64_t(0xFFFFFFFFFFFFFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<uint64_t> result;
result.reset();
result = bit_stream.read<uint64_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<uint64_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<uint64_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<uint64_t>();
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<uint64_t>(), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_uint64_t_47bits)
{
std::array storage = { char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x02), char(0x95), char(0x6A),
char(0x95), char(0x6A), char(0x95), char(0x6A), char(0xD5), char(0x2A), char(0xD5), char(0x2A),
char(0xD5), char(0x2F), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xF0) };
std::array expected = { uint64_t(0x0000000000000001), uint64_t(0x0000255AA55AA55A), uint64_t(0x00005AA55AA55AA5), uint64_t(0x00007FFFFFFFFFFF) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
etl::optional<uint64_t> result;
result.reset();
result = bit_stream.read<uint64_t>(47U);
CHECK(result.has_value());
CHECK_EQUAL(expected[0], result.value());
result.reset();
result = bit_stream.read<uint64_t>(47U);
CHECK(result.has_value());
CHECK_EQUAL(expected[1], result.value());
result.reset();
result = bit_stream.read<uint64_t>(47U);
CHECK(result.has_value());
CHECK_EQUAL(expected[2], result.value());
result.reset();
result = bit_stream.read<uint64_t>(47U);
CHECK(result.has_value());
CHECK_EQUAL(expected[3], result.value());
// One too many.
CHECK_THROW(bit_stream.read<uint64_t>(47U), etl::bit_stream_overflow);
}
//*************************************************************************
TEST(test_read_multiple_full_size)
{
int8_t c1 = 90; // 0x5A
uint16_t s1 = 4660; // 0x1234
int32_t i1 = 2309737967L; // 0x89ABCDEF
int32_t i2 = 4275878552L; // 0xFEDCBA98
uint16_t s2 = 22136; // 0x5678
int8_t c2 = -91; // 0xA5
std::array storage = { char(0x5A),
char(0x12), char(0x34),
char(0x89), char(0xAB), char(0xCD), char(0xEF),
char(0xFE), char(0xDC), char(0xBA), char(0x98),
char(0x56), char(0x78),
char(0xA5) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
auto result_c1 = bit_stream.read<int8_t>();
CHECK(result_c1.has_value());
CHECK_EQUAL(int8_t(0x5A), result_c1.value());
auto result_s1 = bit_stream.read<uint16_t>();
CHECK(result_s1.has_value());
CHECK_EQUAL(uint16_t(0x1234), result_s1.value());
auto result_i1 = bit_stream.read<int32_t>();
CHECK(result_i1.has_value());
CHECK_EQUAL(int32_t(0x89ABCDEF), result_i1.value());
auto result_i2 = bit_stream.read<int32_t>();
CHECK(result_i2.has_value());
CHECK_EQUAL(int32_t(0xFEDCBA98), result_i2.value());
auto result_s2 = bit_stream.read<uint16_t>();
CHECK(result_s2.has_value());
CHECK_EQUAL(uint16_t(0x5678), result_s2.value());
auto result_c2 = bit_stream.read<int8_t>();
CHECK(result_c2.has_value());
CHECK_EQUAL(int8_t(0xA5), result_c2.value());
}
//*************************************************************************
TEST(test_read_multiple_variable_size)
{
int8_t c1 = 90; // 0x5A 6 bits
uint16_t s1 = 4660; // 0x1234 13 bits
int32_t i1 = 2309737967L; // 0x89ABCDEF 23 bits
int32_t i2 = 4275878552L; // 0xFEDCBA98 25 bits
uint16_t s2 = 22136; // 0x5678 11 bits
int8_t c2 = -91; // 0xA5 7 bits
std::array storage = { char(0x6A), char(0x46), char(0x8A), char(0xF3),
char(0x7B), char(0xDB), char(0x97), char(0x53),
char(0x19), char(0xE1), char(0x28) };
etl::bit_stream_reader bit_stream(storage.data(), storage.size());
auto result_c1 = bit_stream.read<int8_t>(6U);
CHECK(result_c1.has_value());
CHECK_EQUAL(int8_t(0x1A), result_c1.value());
auto result_s1 = bit_stream.read<uint16_t>(13U);
CHECK(result_s1.has_value());
CHECK_EQUAL(uint16_t(0x1234), result_s1.value());
auto result_i1 = bit_stream.read<int32_t>(23U);
CHECK(result_i1.has_value());
CHECK_EQUAL(int32_t(0x002BCDEF), result_i1.value());
auto result_i2 = bit_stream.read<int32_t>(25U);
CHECK(result_i2.has_value());
CHECK_EQUAL(int32_t(0x00DCBA98), result_i2.value());
auto result_s2 = bit_stream.read<uint16_t>(11U);
CHECK(result_s2.has_value());
CHECK_EQUAL(uint16_t(0x0678), result_s2.value());
auto result_c2 = bit_stream.read<int8_t>(7U);
CHECK(result_c2.has_value());
CHECK_EQUAL(int8_t(0x25), result_c2.value());
}
//*************************************************************************
TEST(test_read_object)
{
}
//*************************************************************************
TEST(test_read_multiple_floating_point)
{
}
};
}

View File

@ -10911,6 +10911,7 @@
<ClCompile Include="..\test_alignment.cpp" />
<ClCompile Include="..\test_atomic.cpp" />
<ClCompile Include="..\test_bit.cpp" />
<ClCompile Include="..\test_bit_stream_reader.cpp" />
<ClCompile Include="..\test_bit_stream_writer.cpp" />
<ClCompile Include="..\test_bresenham_line.cpp" />
<ClCompile Include="..\test_buffer_descriptors.cpp" />

View File

@ -3251,6 +3251,9 @@
<ClCompile Include="..\test_atomic.cpp">
<Filter>Tests\Atomic</Filter>
</ClCompile>
<ClCompile Include="..\test_bit_stream_reader.cpp">
<Filter>Tests\Binary</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">
@ -3413,4 +3416,4 @@
<Filter>Resource Files</Filter>
</Natvis>
</ItemGroup>
</Project>
</Project>