#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 = (std::numeric_limits::min)(), std::underlying_type_t = (std::numeric_limits::max)()> struct bounded_enum; /** * @brief A trait used to serialize an enum type with runtime bounds */ template struct serialize_traits>> { using value_type = std::underlying_type_t; template typename utility::is_writing_t static serialize(Stream& writer, T value, value_type min = 0, value_type max = (std::numeric_limits::max)()) noexcept { value_type unsigned_value = static_cast(value); return writer.template serialize(unsigned_value, min, max); } template typename utility::is_reading_t static serialize(Stream& reader, T& value, value_type min = 0, value_type max = (std::numeric_limits::max)()) noexcept { value_type unsigned_value; BS_ASSERT(reader.template serialize(unsigned_value, min, max)); value = static_cast(unsigned_value); return true; } }; /** * @brief A trait used to serialize an enum type with compiletime bounds */ template Min, std::underlying_type_t Max> struct serialize_traits, typename std::enable_if_t>> { using value_type = std::underlying_type_t; using bound_type = bounded_int; template typename utility::is_writing_t static serialize(Stream& writer, T value) noexcept { value_type unsigned_value = static_cast(value); return writer.template serialize(unsigned_value); } template typename utility::is_reading_t static serialize(Stream& reader, T& value) noexcept { value_type unsigned_value; BS_ASSERT(reader.template serialize(unsigned_value)); value = static_cast(unsigned_value); return true; } }; }