Skip to content

Commit

Permalink
Merge pull request #8 from KredeGC/dev
Browse files Browse the repository at this point in the history
Add double trait
  • Loading branch information
KredeGC authored Apr 10, 2023
2 parents f68353a + 3b43179 commit ed26f51
Show file tree
Hide file tree
Showing 22 changed files with 405 additions and 264 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,10 @@ uint32_t value = 27; // We can choose any value below 2^5. Otherwise we need mor
writer.serialize_bits(value, 5);
// Flush the writer's remaining state into the buffer
uint32_t num_bytes = writer.flush();
uint32_t num_bits = writer.flush();
// Create a reader, referencing the buffer and bytes written
bit_reader reader(buffer, num_bytes);
bit_reader reader(buffer, num_bits);
// Read the value back
uint32_t out_value; // We don't have to initialize it yet
Expand All @@ -275,10 +275,10 @@ int32_t value = -45; // We can choose any value within the range below
writer.serialize<int32_t>(value, -90, 40); // A lower and upper bound which the value will be quantized between

// Flush the writer's remaining state into the buffer
uint32_t num_bytes = writer.flush();
uint32_t num_bits = writer.flush();

// Create a reader by moving and invalidating the writer
bit_reader reader(buffer, num_bytes);
bit_reader reader(buffer, num_bits);

// Read the value back
int32_t out_value; // We don't have to initialize it yet
Expand All @@ -296,10 +296,10 @@ const char* value = "Hello world!";
writer.serialize<const char*>(value, 32U); // The second argument is the maximum size we expect the string to be
// Flush the writer's remaining state into the buffer
uint32_t num_bytes = writer.flush();
uint32_t num_bits = writer.flush();
// Create a reader by moving and invalidating the writer
bit_reader reader(buffer, num_bytes);
bit_reader reader(buffer, num_bits);
// Read the value back
char out_value[32]; // Set the size to the max size
Expand All @@ -317,10 +317,10 @@ std::string value = "Hello world!";
writer.serialize<std::string>(value, 32U); // The second argument is the maximum size we expect the string to be

// Flush the writer's remaining state into the buffer
uint32_t num_bytes = writer.flush();
uint32_t num_bits = writer.flush();

// Create a reader by moving and invalidating the writer
bit_reader reader(buffer, num_bytes);
bit_reader reader(buffer, num_bits);

// Read the value back
std::string out_value; // The string will be resized if the output doesn't fit
Expand All @@ -339,10 +339,10 @@ float value = 1.2345678f;
writer.serialize<bounded_range>(range, value);
// Flush the writer's remaining state into the buffer
uint32_t num_bytes = writer.flush();
uint32_t num_bits = writer.flush();
// Create a reader by moving and invalidating the writer
bit_reader reader(buffer, num_bytes);
bit_reader reader(buffer, num_bits);
// Read the value back
float out_value;
Expand All @@ -354,7 +354,7 @@ These examples can also be seen in [`src/test/examples_test.cpp`](https://github
# Extensibility
The library is made with extensibility in mind.
The `bit_writer` and `bit_reader` use a template trait specialization of the given type to deduce how to serialize and deserialize the object.
The only requirements of the trait is that it has (or can deduce) 2 static functions which take a bit_writer& and a bit_reader& respectively as their first argument.
The only requirements of the trait is that it has (or can deduce) 2 static functions which take a `bit_writer&` and a `bit_reader&` respectively as their first argument.
The 2 functions must also return a bool indicating whether the serialization was a success or not, but can otherwise take any number of additional arguments.

## Adding new serializables types
Expand Down
4 changes: 2 additions & 2 deletions include/bitstream/quantization/bounded_range.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#pragma once

#include <cstdint>

/*
* Copyright (c) 2018 Stanislav Denisov
*
Expand All @@ -24,6 +22,8 @@
* SOFTWARE.
*/

#include <cstdint>

namespace bitstream
{
/**
Expand Down
43 changes: 15 additions & 28 deletions include/bitstream/quantization/half_precision.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#pragma once

#include <cstdint>

/*
* Copyright (c) 2018 Stanislav Denisov
*
Expand All @@ -24,36 +22,25 @@
* SOFTWARE.
*/

#include <cstdint>
#include <cstring>

namespace bitstream
{
/**
* @brief Class for quantizing single-precision floats into half-precision
*/
class half_precision
{
private:
union Values
{
float f;
int32_t i;
};

public:
inline static uint16_t quantize(float value)
{
Values values
{
value
};
int32_t tmp;
std::memcpy(&tmp, &value, sizeof(float));

return quantize(values.i);
}

inline static uint16_t quantize(int32_t value)
{
int32_t s = (value >> 16) & 0x00008000;
int32_t e = ((value >> 23) & 0X000000FF) - (127 - 15);
int32_t m = value & 0X007FFFFF;
int32_t s = (tmp >> 16) & 0x00008000;
int32_t e = ((tmp >> 23) & 0X000000FF) - (127 - 15);
int32_t m = tmp & 0X007FFFFF;

if (e <= 0) {
if (e < -10)
Expand Down Expand Up @@ -94,7 +81,7 @@ namespace bitstream

inline static float dequantize(uint16_t value)
{
uint32_t result;
uint32_t tmp;
uint32_t mantissa = (uint32_t)(value & 1023);
uint32_t exponent = 0XFFFFFFF2;

Expand All @@ -106,22 +93,22 @@ namespace bitstream
}

mantissa &= 0XFFFFFBFF;
result = (((uint32_t)value & 0x8000) << 16) | ((exponent + 127) << 23) | (mantissa << 13);
tmp = (((uint32_t)value & 0x8000) << 16) | ((exponent + 127) << 23) | (mantissa << 13);
}
else
{
result = (uint32_t)((value & 0x8000) << 16);
tmp = (uint32_t)((value & 0x8000) << 16);
}
}
else
{
result = ((((uint32_t)value & 0x8000) << 16) | ((((((uint32_t)value >> 10) & 0X1F) - 15) + 127) << 23)) | (mantissa << 13);
tmp = ((((uint32_t)value & 0x8000) << 16) | ((((((uint32_t)value >> 10) & 0X1F) - 15) + 127) << 23)) | (mantissa << 13);
}

Values values;
values.i = result;
float result;
std::memcpy(&result, &tmp, sizeof(float));

return values.f;
return result;
}
};
}
6 changes: 3 additions & 3 deletions include/bitstream/quantization/smallest_three.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#pragma once

#include <cstdint>
#include <cmath>

/*
* Copyright (c) 2020 Stanislav Denisov, Maxim Munning, Davin Carten
*
Expand All @@ -25,6 +22,9 @@
* SOFTWARE.
*/

#include <cstdint>
#include <cmath>

namespace bitstream
{
/**
Expand Down
44 changes: 25 additions & 19 deletions include/bitstream/stream/bit_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,28 @@ namespace bitstream
m_WordIndex(0) {}

/**
* @brief Construct a reader pointing to the given byte array with @p num_bytes size
* @brief Construct a reader pointing to the given byte array with @p num_bits
* @param bytes The byte array to read from. Should be 4-byte aligned if possible. The size of the array must be a multiple of 4
* @param num_bytes The maximum number of bytes that we can read
* @param num_bits The maximum number of bits that we can read
*/
explicit bit_reader(const void* bytes, uint32_t num_bytes) noexcept :
explicit bit_reader(const void* bytes, uint32_t num_bits) noexcept :
m_Buffer(static_cast<const uint32_t*>(bytes)),
m_NumBitsRead(0),
m_TotalBits(num_bytes * 8),
m_TotalBits(num_bits),
m_Scratch(0),
m_ScratchBits(0),
m_WordIndex(0) {}

/**
* @brief Construct a reader pointing to the given @p buffer
* @param buffer The buffer to read from
* @param num_bytes The maximum number of bytes that we can read
* @param num_bits The maximum number of bits that we can read
*/
template<size_t Size>
explicit bit_reader(byte_buffer<Size>& buffer, uint32_t num_bytes) noexcept :
explicit bit_reader(byte_buffer<Size>& buffer, uint32_t num_bits) noexcept :
m_Buffer(reinterpret_cast<uint32_t*>(buffer.Bytes)),
m_NumBitsRead(0),
m_TotalBits(num_bytes * 8),
m_TotalBits(num_bits),
m_Scratch(0),
m_ScratchBits(0),
m_WordIndex(0) {}
Expand Down Expand Up @@ -113,6 +113,12 @@ namespace bitstream
*/
uint32_t get_num_bits_serialized() const noexcept { return m_NumBitsRead; }

/**
* @brief Returns the number of bytes which have been read from the buffer
* @return The number of bytes which have been read
*/
uint32_t get_num_bytes_serialized() const noexcept { return m_NumBitsRead > 0U ? ((m_NumBitsRead - 1U) / 8U + 1U) : 0U; }

/**
* @brief Returns whether the @p num_bits be read from the buffer
* @param num_bits The number of bits to test
Expand Down Expand Up @@ -178,24 +184,23 @@ namespace bitstream

BS_ASSERT(num_bytes * 8U >= m_NumBitsRead);

uint32_t offset = m_NumBitsRead / 32;
uint32_t remainder = (num_bytes * 8U - m_NumBitsRead) % 32U;
uint32_t zero;

// Test for zeros in padding
for (uint32_t i = offset; i < num_bytes / 4; i++)
// Test the last word more carefully, as it may have data
if (remainder != 0U)
{
bool status = serialize_bits(zero, 32);

bool status = serialize_bits(zero, remainder);
BS_ASSERT(status && zero == 0);
}

uint32_t remainder = num_bytes * 8U - m_NumBitsRead;
uint32_t offset = m_NumBitsRead / 32;
uint32_t max = num_bytes / 4;

// Test the last word more carefully, as it may have data
if (remainder % 32U != 0U)
// Test for zeros in padding
for (uint32_t i = offset; i < max; i++)
{
bool status = serialize_bits(zero, remainder);

bool status = serialize_bits(zero, 32);
BS_ASSERT(status && zero == 0);
}

Expand Down Expand Up @@ -329,9 +334,10 @@ namespace bitstream
* @brief Reads from the buffer, by trying to deduce the trait.
* @note The Trait type in this function is always implicit and will be deduced from the first argument if possible.
* If the trait cannot be deduced it will not compile.
* @tparam Trait A template specialization of serialize_trait<>
* @tparam Trait The type of the first argument, which will be used to deduce the trait specialization
* @tparam ...Args The types of the arguments to pass to the serialize function
* @param ...args The arguments to pass to the serialize function
* @param arg The first argument to pass to the serialize function
* @param ...args The rest of the arguments to pass to the serialize function
* @return Whether successful or not
*/
template<typename Trait, typename... Args>
Expand Down
Loading

0 comments on commit ed26f51

Please sign in to comment.