Skip to content

Commit 20c6d58

Browse files
committed
Add serialize_traits for enum types
Update integral trait to not allow const types Update extension example in README
1 parent 3b4be20 commit 20c6d58

File tree

6 files changed

+87
-5
lines changed

6 files changed

+87
-5
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,12 +386,14 @@ struct serialize_traits<TRAIT_TYPE> // The type to use when serializing
386386
The specialization can also be templated to work with a number of types.
387387
It also works with `enable_if`:
388388
```cpp
389-
// This trait will be used by any integral pointer type (char*, uint16_t* etc.)
389+
// This trait will be used by any non-const integral pointer type (char*, uint16_t* etc.)
390390
template<typename T>
391-
struct serialize_traits<T*, typename std::enable_if_t<std::is_integral_v<T>>>
391+
struct serialize_traits<T*, typename std::enable_if_t<std::is_integral_v<T> && !std::is_const_v<T>>>
392392
{ ... };
393-
// An example which would use the above trait
393+
// An example which will use the above trait
394394
bool status = writer.serialize<int16_t*>(...);
395+
// An example which won't use it (and won't compile)
396+
bool status = writer.serialize<const int16_t*>(...);
395397
```
396398

397399
More concrete examples of traits can be found in the [`traits/`](https://github.com/KredeGC/BitStream/tree/master/include/bitstream/traits/) directory.

include/bitstream/bitstream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// Traits
1515
#include "traits/array_traits.h"
1616
#include "traits/bool_trait.h"
17+
#include "traits/enum_trait.h"
1718
#include "traits/integral_traits.h"
1819
#include "traits/quantization_traits.h"
1920
#include "traits/string_traits.h"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
#include "../utility/assert.h"
3+
4+
#include "../stream/serialize_traits.h"
5+
#include "../stream/bit_reader.h"
6+
#include "../stream/bit_writer.h"
7+
8+
#include "../traits/integral_traits.h"
9+
10+
namespace bitstream
11+
{
12+
/**
13+
* @brief A trait used to serialize an enum type
14+
*/
15+
template<typename T>
16+
struct serialize_traits<T, typename std::enable_if_t<std::is_enum_v<T>>>
17+
{
18+
using value_type = std::underlying_type_t<T>;
19+
20+
static bool serialize(bit_writer& writer, T value, value_type min = 0, value_type max = (std::numeric_limits<value_type>::max)()) noexcept
21+
{
22+
value_type unsigned_value = static_cast<value_type>(value);
23+
24+
return writer.serialize<value_type>(unsigned_value, min, max);
25+
}
26+
27+
static bool serialize(bit_reader& reader, T& value, value_type min = 0, value_type max = (std::numeric_limits<value_type>::max)()) noexcept
28+
{
29+
value_type unsigned_value;
30+
31+
BS_ASSERT(reader.serialize<value_type>(unsigned_value, min, max));
32+
33+
value = static_cast<T>(unsigned_value);
34+
35+
return true;
36+
}
37+
};
38+
}

include/bitstream/traits/integral_traits.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace bitstream
2525
* @tparam T A type matching an integer value
2626
*/
2727
template<typename T>
28-
struct serialize_traits<T, typename std::enable_if_t<std::is_integral_v<T>>>
28+
struct serialize_traits<T, typename std::enable_if_t<std::is_integral_v<T> && !std::is_const_v<T>>>
2929
{
3030
/**
3131
* @brief Writes an integer into the @p writer
@@ -126,7 +126,7 @@ namespace bitstream
126126
* @tparam Max The upper bound. Inclusive
127127
*/
128128
template<typename T, T Min, T Max>
129-
struct serialize_traits<bounded_int<T, Min, Max>, typename std::enable_if_t<std::is_integral_v<T>>>
129+
struct serialize_traits<bounded_int<T, Min, Max>, typename std::enable_if_t<std::is_integral_v<T> && !std::is_const_v<T>>>
130130
{
131131
/**
132132
* @brief Writes an integer into the @p writer

src/shared/test_types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,11 @@ namespace bitstream::test
1919
return values[index];
2020
}
2121
};
22+
23+
enum class test_enum
24+
{
25+
FirstValue = 3,
26+
SecondValue = 1,
27+
ThirdValue
28+
};
2229
}

src/test/serialize_enum_test.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include "../shared/assert.h"
2+
#include "../shared/test.h"
3+
#include "../shared/test_types.h"
4+
5+
#include <bitstream/stream/bit_reader.h>
6+
#include <bitstream/stream/bit_writer.h>
7+
8+
#include <bitstream/traits/enum_trait.h>
9+
10+
namespace bitstream::test::traits
11+
{
12+
BS_ADD_TEST(test_serialize_enum_aligned)
13+
{
14+
// Test enums
15+
test_enum value = test_enum::SecondValue;
16+
17+
// Write a char array, but make sure the word count isn't whole
18+
byte_buffer<4> buffer;
19+
bit_writer writer(buffer);
20+
21+
BS_TEST_ASSERT(writer.serialize<test_enum>(value, 1, 3));
22+
uint32_t num_bytes = writer.flush();
23+
24+
BS_TEST_ASSERT_OPERATION(num_bytes, == , 1);
25+
26+
// Read the enum back and validate
27+
test_enum out_value;
28+
bit_reader reader(buffer, num_bytes);
29+
30+
BS_TEST_ASSERT(reader.serialize<test_enum>(out_value, 1, 3));
31+
32+
BS_TEST_ASSERT_OPERATION(out_value, == , value);
33+
}
34+
}

0 commit comments

Comments
 (0)