81 lines
2.4 KiB
C++
81 lines
2.4 KiB
C++
#pragma once
|
|
#include "../utility/assert.h"
|
|
#include "../utility/meta.h"
|
|
#include "../utility/parameter.h"
|
|
|
|
#include "../stream/serialize_traits.h"
|
|
|
|
#include "../traits/integral_traits.h"
|
|
|
|
namespace bitstream
|
|
{
|
|
/**
|
|
* @brief Wrapper type for compiletime known integer bounds
|
|
* @tparam T
|
|
*/
|
|
template<typename T, std::underlying_type_t<T> = (std::numeric_limits<T>::min)(), std::underlying_type_t<T> = (std::numeric_limits<T>::max)()>
|
|
struct bounded_enum;
|
|
|
|
/**
|
|
* @brief A trait used to serialize an enum type with runtime bounds
|
|
*/
|
|
template<typename T>
|
|
struct serialize_traits<T, typename std::enable_if_t<std::is_enum_v<T>>>
|
|
{
|
|
using value_type = std::underlying_type_t<T>;
|
|
|
|
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.template serialize<value_type>(unsigned_value, min, max);
|
|
}
|
|
|
|
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.template serialize<value_type>(unsigned_value, min, max));
|
|
|
|
value = static_cast<T>(unsigned_value);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief A trait used to serialize an enum type with compiletime bounds
|
|
*/
|
|
template<typename T, std::underlying_type_t<T> Min, std::underlying_type_t<T> Max>
|
|
struct serialize_traits<bounded_enum<T, Min, Max>, typename std::enable_if_t<std::is_enum_v<T>>>
|
|
{
|
|
using value_type = std::underlying_type_t<T>;
|
|
using bound_type = bounded_int<value_type, Min, Max>;
|
|
|
|
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.template serialize<bound_type>(unsigned_value);
|
|
}
|
|
|
|
template<typename Stream>
|
|
typename utility::is_reading_t<Stream>
|
|
static serialize(Stream& reader, T& value) noexcept
|
|
{
|
|
value_type unsigned_value;
|
|
|
|
BS_ASSERT(reader.template serialize<bound_type>(unsigned_value));
|
|
|
|
value = static_cast<T>(unsigned_value);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
} |