UdonLibrary 1.0.0
機械システム研究部 C++ ライブラリ
読み取り中…
検索中…
一致する文字列を見つけられません
Serializer.hpp
[詳解]
1//
2// シリアライザ実装部
3//
4// Copyright (c) 2022-2024 udonrobo
5//
6
7#pragma once
8
10#include <algorithm>
11#include <vector>
12#include <limits.h>
13
16#include <Udon/Types/Float.hpp>
21
22namespace Udon
23{
24
25 namespace Impl
26 {
27 using namespace Udon::Traits;
28
30 {
31
32 size_t pushIndex = 0; // 次に挿入するインデックス(バッファの先端からのオフセット)
33 uint8_t boolCount = 0; // bool の挿入回数
34 size_t boolInsertIndex = 0; // bool を挿入中であるインデックス(バッファの先端からのオフセット)
35
36 ArrayView<uint8_t> buffer; // シリアライズしたデータを格納するバッファへの参照
37
38 public:
39 using ResultType = void;
40
42 : buffer(buffer)
43 {
44 }
45
49 template <typename... Args>
50 void operator()(Args&&... args) const
51 {
52 argsUnpack(std::forward<Args>(args)...);
53 }
54
55 private:
57 template <typename Head, typename... Tails>
58 void argsUnpack(Head&& head, Tails&&... tails) const
59 {
60 const_cast<Serializer&>(*this).serialize(std::forward<Head>(head));
61 // enumerate 関数は引数に一時オブジェクトを受けられる、かつconstexprである必要があるため "const Serializer& enumerator" になっている
62 // その関係で、operator()、本関数はconstな関数となり、thisポインタはconstなポインタになる。そのため const を外す。
63
64 argsUnpack(std::forward<Tails>(tails)...);
65 }
66
68 void argsUnpack() const {}
69
71 template <typename Bool, EnableIfNullptrT<IsBool<RemoveCVRefT<Bool>>::value> = nullptr>
72 void serialize(Bool rhs)
73 {
74 pushBool(rhs);
75 }
76
78 template <typename IntegralNotBool, EnableIfNullptrT<IsIntegralNotBool<RemoveCVRefT<IntegralNotBool>>::value> = nullptr>
79 void serialize(IntegralNotBool rhs)
80 {
81 pushArithmetic(rhs);
82 }
83
85 template <typename FloatingPoint, EnableIfNullptrT<IsFloatingPoint<RemoveCVRefT<FloatingPoint>>::value> = nullptr>
86 void serialize(FloatingPoint rhs)
87 {
88 pushArithmetic(static_cast<Udon::Float32>(rhs));
89 }
90
92 template <typename Enum, EnableIfNullptrT<IsEnum<RemoveCVRefT<Enum>>::value> = nullptr>
93 void serialize(Enum rhs)
94 {
95 pushArithmetic(static_cast<typename std::underlying_type<Enum>::type>(rhs));
96 }
97
99 template <typename Array, EnableIfNullptrT<IsArray<RemoveCVRefT<Array>>::value> = nullptr>
100 void serialize(Array&& rhs)
101 {
102 for (auto&& element : rhs)
103 {
104 serialize(element);
105 }
106 }
107
109 template <typename Enumerable, EnableIfNullptrT<HasMemberFunctionEnumerate<RemoveCVRefT<Enumerable>>::value> = nullptr>
110 void serialize(Enumerable&& rhs)
111 {
112 // static_assert(AlwaysFalse<Enumerable>::value, "Enumerable type must have a member function named 'enumerate'" __FUNCSIG__ );
113 rhs.enumerate(*this);
114 }
115
117 template <typename Arithmetic>
118 void pushArithmetic(Arithmetic arithmetic)
119 {
120 constexpr auto size = sizeof(Arithmetic);
121
122 // バッファの後方に挿入
123 // リトルエンディアン環境でのバイト列の並びを順とする
124#if UDON_PLATFORM_ENDIANNESS == UDON_PLATFORM_LITTLE_ENDIAN
125
126 // オブジェクトをバイト列として解釈
127 memcpy(
128 buffer.data() + pushIndex,
129 std::addressof(arithmetic),
130 size);
131
132#elif UDON_PLATFORM_ENDIANNESS == UDON_PLATFORM_BIG_ENDIAN
133
134 // オブジェクトをバイト列として解釈
135 uint8_t reversedBuffer[size];
136 memcpy(
137 reversedBuffer,
138 std::addressof(arithmetic),
139 size);
140
141 // リトルエンディアンが基準なので、逆順にしてバッファに挿入
142 std::reverse_copy(
143 reversedBuffer,
144 reversedBuffer + size,
145 buffer.begin() + pushIndex);
146
147#endif
148
149 // 次に挿入するインデックスを更新
150 pushIndex += size;
151 }
152
154 void pushBool(bool rhs)
155 {
156 if (boolCount == 0)
157 {
158 boolInsertIndex = pushIndex++;
159 }
160
161 Udon::BitWrite(buffer.at(boolInsertIndex), boolCount, rhs);
162
163 if (++boolCount >= CHAR_BIT)
164 {
165 boolCount = 0;
166 }
167 }
168 };
169 } // namespace Impl
170
171} // namespace Udon
配列参照クラス
Definition ArrayView.hpp:27
iterator begin()
Definition ArrayView.hpp:244
pointer data()
Definition ArrayView.hpp:95
reference at(const size_type index)
Definition ArrayView.hpp:113
Definition Serializer.hpp:30
Serializer(ArrayView< uint8_t > buffer)
Definition Serializer.hpp:41
void operator()(Args &&... args) const
シリアライズ
Definition Serializer.hpp:50
void ResultType
Definition Serializer.hpp:39
Definition SerializerTraits.hpp:92
Definition Bit.hpp:12
void BitWrite(Ty &rhs, uint8_t bit, bool value)
特定のビットに値を書き込む
Definition Bit.hpp:61