Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More generic traits #12

Merged
merged 6 commits into from
Aug 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/bitstream/bitstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "traits/array_traits.h"
#include "traits/bool_trait.h"
#include "traits/enum_trait.h"
#include "traits/float_trait.h"
#include "traits/integral_traits.h"
#include "traits/quantization_traits.h"
#include "traits/string_traits.h"
14 changes: 12 additions & 2 deletions include/bitstream/stream/bit_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,16 @@ namespace bitstream
return true;
}

/**
* @brief Pads the buffer up with the given number of bytes
* @param num_bytes The amount of bytes to pad
* @return Returns false if the current size of the buffer is bigger than @p num_bytes or if the padded bits are not zeros.
*/
[[nodiscard]] bool pad(uint32_t num_bytes) noexcept
{
return pad_to_size(get_num_bytes_serialized() + num_bytes);
}

/**
* @brief Pads the buffer with up to 8 zeros, so that the next read is byte-aligned
* @notes Return false if the padded bits are not zeros
Expand Down Expand Up @@ -235,7 +245,7 @@ namespace bitstream
{
const uint32_t* ptr = m_Buffer + m_WordIndex;

uint64_t ptr_value = static_cast<uint64_t>(utility::endian_swap_32(*ptr)) << (32U - m_ScratchBits);
uint64_t ptr_value = static_cast<uint64_t>(utility::to_big_endian32(*ptr)) << (32U - m_ScratchBits);
m_Scratch |= ptr_value;
m_ScratchBits += 32U;
m_WordIndex++;
Expand Down Expand Up @@ -285,7 +295,7 @@ namespace bitstream

// Casting a byte-array to an int is wrong on little-endian systems
// We have to swap the bytes around
word_buffer[i] = utility::endian_swap_32(value);
word_buffer[i] = utility::to_big_endian32(value);
}
}

Expand Down
16 changes: 13 additions & 3 deletions include/bitstream/stream/bit_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ namespace bitstream
{
uint32_t* ptr = m_Buffer + m_WordIndex;
uint32_t ptr_value = static_cast<uint32_t>(m_Scratch >> 32U);
*ptr = utility::endian_swap_32(ptr_value);
*ptr = utility::to_big_endian32(ptr_value);

m_Scratch = 0U;
m_ScratchBits = 0U;
Expand Down Expand Up @@ -241,6 +241,16 @@ namespace bitstream
return true;
}

/**
* @brief Pads the buffer up with the given number of bytes
* @param num_bytes The amount of bytes to pad
* @return Returns false if the current size of the buffer is bigger than @p num_bytes or if the padded bits are not zeros.
*/
[[nodiscard]] bool pad(uint32_t num_bytes) noexcept
{
return pad_to_size(get_num_bytes_serialized() + num_bytes);
}

/**
* @brief Pads the buffer with up to 8 zeros, so that the next write is byte-aligned
* @return Success
Expand Down Expand Up @@ -281,7 +291,7 @@ namespace bitstream
{
uint32_t* ptr = m_Buffer + m_WordIndex;
uint32_t ptr_value = static_cast<uint32_t>(m_Scratch >> 32U);
*ptr = utility::endian_swap_32(ptr_value);
*ptr = utility::to_big_endian32(ptr_value);
m_Scratch <<= 32ULL;
m_ScratchBits -= 32U;
m_WordIndex++;
Expand Down Expand Up @@ -321,7 +331,7 @@ namespace bitstream
{
// Casting a byte-array to an int is wrong on little-endian systems
// We have to swap the bytes around
uint32_t value = utility::endian_swap_32(word_buffer[i]);
uint32_t value = utility::to_big_endian32(word_buffer[i]);
BS_ASSERT(serialize_bits(value, 32U));
}
}
Expand Down
20 changes: 14 additions & 6 deletions include/bitstream/traits/bool_trait.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#pragma once
#include "../utility/assert.h"
#include "../utility/meta.h"
#include "../utility/parameter.h"

#include "../stream/serialize_traits.h"
#include "../stream/bit_reader.h"
#include "../stream/bit_writer.h"

namespace bitstream
{
Expand All @@ -13,14 +13,18 @@ namespace bitstream
template<>
struct serialize_traits<bool>
{
static bool serialize(bit_writer& writer, bool value) noexcept
template<typename Stream>
typename utility::is_writing_t<Stream>
static serialize(Stream& writer, in<bool> value) noexcept
{
uint32_t unsigned_value = value;

return writer.serialize_bits(unsigned_value, 1U);
}

static bool serialize(bit_reader& reader, bool& value) noexcept
template<typename Stream>
typename utility::is_reading_t<Stream>
static serialize(Stream& reader, out<bool> value) noexcept
{
uint32_t unsigned_value;

Expand All @@ -38,7 +42,9 @@ namespace bitstream
template<size_t Size>
struct serialize_traits<bool[Size]>
{
static bool serialize(bit_writer& writer, const bool* values) noexcept
template<typename Stream>
typename utility::is_writing_t<Stream>
static serialize(Stream& writer, const bool* values) noexcept
{
uint32_t unsigned_value;
for (size_t i = 0; i < Size; i++)
Expand All @@ -50,7 +56,9 @@ namespace bitstream
return writer.serialize_bits(unsigned_value, 1U);
}

static bool serialize(bit_reader& reader, bool* values) noexcept
template<typename Stream>
typename utility::is_reading_t<Stream>
static serialize(Stream& reader, bool* values) noexcept
{
uint32_t unsigned_value;
for (size_t i = 0; i < Size; i++)
Expand Down
30 changes: 19 additions & 11 deletions include/bitstream/traits/enum_trait.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#pragma once
#include "../utility/assert.h"
#include "../utility/meta.h"
#include "../utility/parameter.h"

#include "../stream/serialize_traits.h"
#include "../stream/bit_reader.h"
#include "../stream/bit_writer.h"

#include "../traits/integral_traits.h"

Expand All @@ -23,19 +23,23 @@ namespace bitstream
struct serialize_traits<T, typename std::enable_if_t<std::is_enum_v<T>>>
{
using value_type = std::underlying_type_t<T>;

static bool serialize(bit_writer& writer, T value, value_type min = 0, value_type max = (std::numeric_limits<value_type>::max)()) noexcept

template<typename Stream>
typename utility::is_writing_t<Stream>
static serialize(Stream& writer, T value, value_type min = 0, value_type max = (std::numeric_limits<value_type>::max)()) noexcept
{
value_type unsigned_value = static_cast<value_type>(value);

return writer.serialize<value_type>(unsigned_value, min, max);
return writer.template serialize<value_type>(unsigned_value, min, max);
}

static bool serialize(bit_reader& reader, T& value, value_type min = 0, value_type max = (std::numeric_limits<value_type>::max)()) noexcept
template<typename Stream>
typename utility::is_reading_t<Stream>
static serialize(Stream& reader, T& value, value_type min = 0, value_type max = (std::numeric_limits<value_type>::max)()) noexcept
{
value_type unsigned_value;

BS_ASSERT(reader.serialize<value_type>(unsigned_value, min, max));
BS_ASSERT(reader.template serialize<value_type>(unsigned_value, min, max));

value = static_cast<T>(unsigned_value);

Expand All @@ -52,18 +56,22 @@ namespace bitstream
using value_type = std::underlying_type_t<T>;
using bound_type = bounded_int<value_type, Min, Max>;

static bool serialize(bit_writer& writer, T value) noexcept
template<typename Stream>
typename utility::is_writing_t<Stream>
static serialize(Stream& writer, T value) noexcept
{
value_type unsigned_value = static_cast<value_type>(value);

return writer.serialize<bound_type>(unsigned_value);
return writer.template serialize<bound_type>(unsigned_value);
}

static bool serialize(bit_reader& reader, T& value) noexcept
template<typename Stream>
typename utility::is_reading_t<Stream>
static serialize(Stream& reader, T& value) noexcept
{
value_type unsigned_value;

BS_ASSERT(reader.serialize<bound_type>(unsigned_value));
BS_ASSERT(reader.template serialize<bound_type>(unsigned_value));

value = static_cast<T>(unsigned_value);

Expand Down
20 changes: 14 additions & 6 deletions include/bitstream/traits/float_trait.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#pragma once
#include "../utility/assert.h"
#include "../utility/meta.h"
#include "../utility/parameter.h"

#include "../stream/serialize_traits.h"
#include "../stream/bit_reader.h"
#include "../stream/bit_writer.h"

#include <cstdint>
#include <cstring>
Expand All @@ -22,7 +22,9 @@ namespace bitstream
* @param value The float to serialize
* @return Success
*/
static bool serialize(bit_writer& writer, float value) noexcept
template<typename Stream>
typename utility::is_writing_t<Stream>
static serialize(Stream& writer, in<float> value) noexcept
{
uint32_t tmp;
std::memcpy(&tmp, &value, sizeof(float));
Expand All @@ -38,7 +40,9 @@ namespace bitstream
* @param value The float to serialize to
* @return Success
*/
static bool serialize(bit_reader& reader, float& value) noexcept
template<typename Stream>
typename utility::is_reading_t<Stream>
static serialize(Stream& reader, float& value) noexcept
{
uint32_t tmp;

Expand All @@ -62,7 +66,9 @@ namespace bitstream
* @param value The double to serialize
* @return Success
*/
static bool serialize(bit_writer& writer, double value) noexcept
template<typename Stream>
typename utility::is_writing_t<Stream>
static serialize(Stream& writer, in<double> value) noexcept
{
uint32_t tmp[2];
std::memcpy(tmp, &value, sizeof(double));
Expand All @@ -79,7 +85,9 @@ namespace bitstream
* @param value The double to serialize to
* @return Success
*/
static bool serialize(bit_reader& reader, double& value) noexcept
template<typename Stream>
typename utility::is_reading_t<Stream>
static serialize(Stream& reader, double& value) noexcept
{
uint32_t tmp[2];

Expand Down
20 changes: 14 additions & 6 deletions include/bitstream/traits/integral_traits.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#pragma once
#include "../utility/assert.h"
#include "../utility/bits.h"
#include "../utility/meta.h"
#include "../utility/parameter.h"

#include "../stream/serialize_traits.h"
#include "../stream/bit_reader.h"
#include "../stream/bit_writer.h"

#include <cstdint>
#include <limits>
Expand Down Expand Up @@ -37,7 +37,9 @@ namespace bitstream
* @param max The maximum bound that @p value can be. Inclusive
* @return Success
*/
static bool serialize(bit_writer& writer, T value, T min = (std::numeric_limits<T>::min)(), T max = (std::numeric_limits<T>::max)()) noexcept
template<typename Stream>
typename utility::is_writing_t<Stream>
static serialize(Stream& writer, in<T> value, T min = (std::numeric_limits<T>::min)(), T max = (std::numeric_limits<T>::max)()) noexcept
{
BS_ASSERT(min < max);

Expand Down Expand Up @@ -77,7 +79,9 @@ namespace bitstream
* @param max The maximum bound that @p value can be. Inclusive
* @return Success
*/
static bool serialize(bit_reader& reader, T& value, T min = (std::numeric_limits<T>::min)(), T max = (std::numeric_limits<T>::max)()) noexcept
template<typename Stream>
typename utility::is_reading_t<Stream>
static serialize(Stream& reader, T& value, T min = (std::numeric_limits<T>::min)(), T max = (std::numeric_limits<T>::max)()) noexcept
{
BS_ASSERT(min < max);

Expand Down Expand Up @@ -138,7 +142,9 @@ namespace bitstream
* @param value The value to serialize
* @return Success
*/
static bool serialize(bit_writer& writer, T value) noexcept
template<typename Stream>
typename utility::is_writing_t<Stream>
static serialize(Stream& writer, in<T> value) noexcept
{
static_assert(Min < Max);

Expand Down Expand Up @@ -173,7 +179,9 @@ namespace bitstream
* @param value The value to serialize
* @return Success
*/
static bool serialize(bit_reader& reader, T& value) noexcept
template<typename Stream>
typename utility::is_reading_t<Stream>
static serialize(Stream& reader, T& value) noexcept
{
static_assert(Min < Max);

Expand Down
Loading