1 #ifndef REFLECTIVE_RAPIDJSON_BINARY_REFLECTOR_H 2 #define REFLECTIVE_RAPIDJSON_BINARY_REFLECTOR_H 10 #include "../traits.h" 12 #include <c++utilities/conversion/conversionexception.h> 13 #include <c++utilities/conversion/types.h> 14 #include <c++utilities/io/binaryreader.h> 15 #include <c++utilities/io/binarywriter.h> 29 static constexpr
const char *
name =
"AdaptedBinarySerializable";
30 static constexpr
const char *
qualifiedName =
"ReflectiveRapidJSON::AdaptedBinarySerializable";
38 namespace BinaryReflector {
41 template <
typename Type>
42 using IsBuiltInType = Traits::Any<Traits::IsAnyOf<Type, char, byte, bool, std::string, int16, uint16, int32, uint32, int64, uint64, float32, float64>,
43 Traits::IsIteratable<Type>, Traits::IsSpecializingAnyOf<Type, std::pair, std::unique_ptr, std::shared_ptr>, std::is_enum<Type>>;
44 template <
typename Type>
using IsCustomType = Traits::Not<IsBuiltInType<Type>>;
56 using IoUtilities::BinaryReader::read;
57 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::pair>> * =
nullptr>
void read(Type &pair);
58 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::unique_ptr>> * =
nullptr>
void read(Type &pair);
59 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::shared_ptr>> * =
nullptr>
void read(Type &pair);
60 template <
typename Type, Traits::EnableIf<IsArray<Type>, Traits::IsResizable<Type>> * =
nullptr>
void read(Type &iteratable);
61 template <
typename Type, Traits::EnableIfAny<IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * =
nullptr>
void read(Type &iteratable);
62 template <
typename Type,
63 Traits::EnableIf<IsIteratableExceptString<Type>,
64 Traits::None<IsMapOrHash<Type>,
IsMultiMapOrHash<Type>, Traits::All<IsArray<Type>, Traits::IsResizable<Type>>>> * =
nullptr>
65 void read(Type &iteratable);
66 template <
typename Type, Traits::EnableIf<std::is_enum<Type>> * =
nullptr>
void read(Type &customType);
67 template <
typename Type, Traits::EnableIf<IsCustomType<Type>> * =
nullptr>
void read(Type &customType);
76 using IoUtilities::BinaryWriter::write;
77 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::pair>> * =
nullptr>
void write(
const Type &pair);
78 template <
typename Type, Traits::EnableIf<Traits::IsSpecializingAnyOf<Type, std::unique_ptr>> * =
nullptr>
void write(
const Type &pointer);
79 template <
typename Type, Traits::EnableIf<Traits::IsSpecializingAnyOf<Type, std::shared_ptr>> * =
nullptr>
void write(
const Type &pointer);
80 template <
typename Type, Traits::EnableIf<IsIteratableExceptString<Type>, Traits::HasSize<Type>> * =
nullptr>
void write(
const Type &iteratable);
81 template <
typename Type, Traits::EnableIf<std::is_enum<Type>> * =
nullptr>
void write(
const Type &customType);
82 template <
typename Type, Traits::EnableIf<IsCustomType<Type>> * =
nullptr>
void write(
const Type &customType);
88 : IoUtilities::BinaryReader(stream)
92 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::pair>> *>
void BinaryDeserializer::read(Type &pair)
98 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::unique_ptr>> *>
void BinaryDeserializer::read(Type &pointer)
104 pointer = std::make_unique<typename Type::element_type>();
108 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::shared_ptr>> *>
void BinaryDeserializer::read(Type &pointer)
110 auto mode = readByte();
117 const auto id = (mode & 0x4) ? readUInt64BE() : readVariableLengthUIntBE();
118 if ((mode & 0x3) == 1) {
120 m_pointer[id] = pointer = std::make_shared<typename Type::element_type>();
126 pointer = std::any_cast<Type>(
m_pointer[
id]);
127 }
catch (
const std::bad_any_cast) {
128 throw ConversionUtilities::ConversionException(
"Referenced pointer type does not match");
132 template <
typename Type, Traits::EnableIf<IsArray<Type>, Traits::IsResizable<Type>> *>
void BinaryDeserializer::read(Type &iteratable)
134 const auto size = readVariableLengthUIntBE();
135 iteratable.resize(size);
136 for (
auto &element : iteratable) {
141 template <
typename Type, Traits::EnableIfAny<IsMapOrHash<Type>, IsMultiMapOrHash<Type>> *>
void BinaryDeserializer::read(Type &iteratable)
143 const auto size = readVariableLengthUIntBE();
144 for (
size_t i = 0; i != size; ++i) {
145 std::pair<typename std::remove_const<typename Type::value_type::first_type>::type,
typename Type::value_type::second_type> value;
147 iteratable.emplace(std::move(value));
151 template <
typename Type,
152 Traits::EnableIf<IsIteratableExceptString<Type>,
153 Traits::None<IsMapOrHash<Type>, IsMultiMapOrHash<Type>, Traits::All<IsArray<Type>, Traits::IsResizable<Type>>>> *>
156 const auto size = readVariableLengthUIntBE();
157 for (
size_t i = 0; i != size; ++i) {
158 typename Type::value_type value;
160 iteratable.emplace(std::move(value));
166 typename std::underlying_type<Type>::type value;
168 enumValue = static_cast<Type>(value);
177 : IoUtilities::BinaryWriter(stream)
181 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::pair>> *>
void BinarySerializer::write(
const Type &pair)
187 template <
typename Type, Traits::EnableIf<Traits::IsSpecializingAnyOf<Type, std::unique_ptr>> *>
void BinarySerializer::write(
const Type &pointer)
189 const bool hasValue = pointer !=
nullptr;
196 template <
typename Type, Traits::EnableIf<Traits::IsSpecializingAnyOf<Type, std::shared_ptr>> *>
void BinarySerializer::write(
const Type &pointer)
198 if (pointer ==
nullptr) {
202 const auto id = reinterpret_cast<std::uintptr_t>(pointer.get());
203 const auto bigId =
id >= 0x80000000000000;
205 byte mode = alreadyWritten ? 2 : 1;
213 writeVariableLengthUIntBE(
id);
215 if (!alreadyWritten) {
216 alreadyWritten =
true;
221 template <
typename Type, Traits::EnableIf<IsIteratableExceptString<Type>, Traits::HasSize<Type>> *>
224 writeVariableLengthUIntBE(iteratable.size());
225 for (
const auto &element : iteratable) {
230 template <
typename Type, Traits::EnableIf<std::is_enum<Type>> *>
void BinarySerializer::write(
const Type &enumValue)
232 write(
static_cast<typename std::underlying_type<Type>::type
>(enumValue));
235 template <
typename Type, Traits::EnableIf<IsCustomType<Type>> *>
void BinarySerializer::write(
const Type &customType)
243 #endif // REFLECTIVE_RAPIDJSON_BINARY_REFLECTOR_H
void writeCustomType(BinarySerializer &serializer, const Type &customType)
Traits::Not< IsBuiltInType< Type > > IsCustomType
void write(const Type &pair)
void readCustomType(BinaryDeserializer &deserializer, Type &customType)
BinaryDeserializer(std::istream *stream)
Traits::Any< Traits::IsSpecializationOf< Type, std::multimap >, Traits::IsSpecializationOf< Type, std::unordered_multimap >, TreatAsMultiMapOrHash< Type > > IsMultiMapOrHash
std::unordered_map< uint64, bool > m_pointer
static constexpr const char * qualifiedName
BinarySerializer(std::ostream *stream)
static constexpr const char * name
Traits::Any< Traits::IsAnyOf< Type, char, byte, bool, std::string, int16, uint16, int32, uint32, int64, uint64, float32, float64 >, Traits::IsIteratable< Type >, Traits::IsSpecializingAnyOf< Type, std::pair, std::unique_ptr, std::shared_ptr >, std::is_enum< Type > > IsBuiltInType
The AdaptedBinarySerializable class allows considering 3rd party classes as serializable.
std::unordered_map< uint64, std::any > m_pointer
The BinarySerializable class provides the CRTP-base for (de)serializable objects.