Skip to content

Commit 7d3a08a

Browse files
committed
Serde WIP
Signed-off-by: Alexis Jeandet <[email protected]>
1 parent 4c08d35 commit 7d3a08a

File tree

12 files changed

+574
-141
lines changed

12 files changed

+574
-141
lines changed

include/cpp_utils/endianness/endianness.hpp

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,22 @@ namespace details
8787
using uint_t = typename uint<s>::type;
8888

8989

90-
inline uint8_t bswap(uint8_t v) { return v; }
91-
inline uint16_t bswap(uint16_t v) { return bswap16(v); }
92-
inline uint32_t bswap(uint32_t v) { return bswap32(v); }
93-
inline uint64_t bswap(uint64_t v) { return bswap64(v); }
90+
inline uint8_t bswap(uint8_t v)
91+
{
92+
return v;
93+
}
94+
inline uint16_t bswap(uint16_t v)
95+
{
96+
return bswap16(v);
97+
}
98+
inline uint32_t bswap(uint32_t v)
99+
{
100+
return bswap32(v);
101+
}
102+
inline uint64_t bswap(uint64_t v)
103+
{
104+
return bswap64(v);
105+
}
94106

95107
template <typename T, std::size_t s = sizeof(T)>
96108
T byte_swap(T value)
@@ -117,6 +129,7 @@ enum class Endianness
117129
struct big_endian_t
118130
{
119131
};
132+
120133
struct little_endian_t
121134
{
122135
};
@@ -132,16 +145,15 @@ inline constexpr bool is_big_endian_v = std::is_same_v<big_endian_t, endianness_
132145
inline Endianness host_endianness_v()
133146
{
134147
if constexpr (is_little_endian_v<host_endianness_t>)
135-
return Endianness::little;
148+
return Endianness::little;
136149
if constexpr (is_big_endian_v<host_endianness_t>)
137-
return Endianness::big;
150+
return Endianness::big;
138151
return Endianness::unknown;
139152
}
140153

141154

142155
template <typename src_endianess_t, typename T, typename U>
143-
[[nodiscard]] HEDLEY_NON_NULL(1)
144-
T decode(const U* input)
156+
[[nodiscard]] HEDLEY_NON_NULL(1) T decode(const U* input)
145157
{
146158
if constexpr (sizeof(T) > 1)
147159
{
@@ -173,14 +185,22 @@ inline void _impl_decode_v(const value_t* data, std::size_t size, value_t* outpu
173185
}
174186
}
175187
}
188+
else
189+
{
190+
if (size > 0 && data != output)
191+
{
192+
std::memcpy(output, data, size * sizeof(value_t));
193+
}
194+
}
176195
}
177196

178197

179198
template <typename src_endianess_t, typename value_t>
180199
HEDLEY_NON_NULL(1)
181200
inline void decode_v(value_t* data, std::size_t size)
182201
{
183-
_impl_decode_v<src_endianess_t>(reinterpret_cast<details::uint_t<sizeof(value_t)>*>(data), size, reinterpret_cast<details::uint_t<sizeof(value_t)>*>(data));
202+
_impl_decode_v<src_endianess_t>(reinterpret_cast<details::uint_t<sizeof(value_t)>*>(data), size,
203+
reinterpret_cast<details::uint_t<sizeof(value_t)>*>(data));
184204
}
185205

186206
template <typename src_endianess_t, typename value_t>
@@ -189,7 +209,8 @@ inline void decode_v(const auto* data, std::size_t size, value_t* output)
189209
{
190210
using _value_t = details::uint_t<sizeof(value_t)>;
191211
auto count = size * sizeof(decltype(*data)) / sizeof(value_t);
192-
_impl_decode_v<src_endianess_t>(reinterpret_cast<const _value_t*>(data), count , reinterpret_cast<_value_t*>(output));
212+
_impl_decode_v<src_endianess_t>(
213+
reinterpret_cast<const _value_t*>(data), count, reinterpret_cast<_value_t*>(output));
193214
}
194215

195216
}

include/cpp_utils/io/memory_mapped_file.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
namespace cpp_utils::io
4747
{
4848

49-
struct mmap_adapter
49+
struct memory_mapped_file
5050
{
5151
#ifdef USE_MMAP
5252
int fd = -1;
@@ -59,7 +59,7 @@ struct mmap_adapter
5959
HANDLE hFile = NULL;
6060
#endif
6161

62-
mmap_adapter(const std::string& path)
62+
memory_mapped_file(const std::string& path)
6363
{
6464

6565
if (std::filesystem::exists(path))
@@ -92,7 +92,7 @@ struct mmap_adapter
9292
}
9393
}
9494
}
95-
~mmap_adapter()
95+
~memory_mapped_file()
9696
{
9797
if (mapped_file)
9898
{

include/cpp_utils/reflexion/reflection.hpp

Lines changed: 36 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -36,70 +36,36 @@ namespace details
3636
{
3737
struct anything
3838
{
39-
template <class T>
39+
template <class T> requires (!std::is_bounded_array_v<std::decay_t<T>>)
4040
operator T() const;
4141
};
4242

43-
44-
template <class T, class Is, class = void>
45-
struct _can_construct_with_N : std::false_type
46-
{
47-
};
48-
49-
template <class T, std::size_t... Is>
50-
struct _can_construct_with_N<T, std::index_sequence<Is...>,
51-
std::void_t<decltype(T { (void(Is), anything {})... })>> : std::true_type
52-
{
53-
};
54-
55-
template <class T, std::size_t N>
56-
using can_construct_with_N = _can_construct_with_N<T, std::make_index_sequence<N>>;
57-
58-
59-
template <std::size_t Min, std::size_t Range, template <std::size_t N> class target>
60-
struct maximize
61-
: std::conditional_t<maximize<Min, Range / 2, target> {} == (Min + Range / 2) - 1,
62-
maximize<Min + Range / 2, (Range + 1) / 2, target>, maximize<Min, Range / 2, target>>
63-
{
64-
};
65-
template <std::size_t Min, template <std::size_t N> class target>
66-
struct maximize<Min, 1, target>
67-
: std::conditional_t<target<Min> {}, std::integral_constant<std::size_t, Min>,
68-
std::integral_constant<std::size_t, Min - 1>>
69-
{
70-
};
71-
template <std::size_t Min, template <std::size_t N> class target>
72-
struct maximize<Min, 0, target> : std::integral_constant<std::size_t, Min - 1>
73-
{
74-
};
75-
76-
template <class T>
77-
struct construct_searcher
78-
{
79-
template <std::size_t N>
80-
using result = can_construct_with_N<T, N>;
81-
};
82-
83-
template <class T, std::size_t Cap = 32>
84-
using construct_airity = details::maximize<0, Cap, details::construct_searcher<T>::template result>;
43+
template<typename T, typename... A0>
44+
consteval auto MemberCounter(auto ...c0) {
45+
if constexpr (requires { T{ {A0{}}..., {anything{}}, c0... }; } == false
46+
&& requires { T{ {A0{}}..., c0..., anything{}}; } == false )
47+
return sizeof...(A0) + sizeof...(c0);
48+
else
49+
if constexpr (requires { T{ {A0{}}..., {anything{}}, c0... }; })
50+
return MemberCounter<T,A0...,anything>(c0...);
51+
else
52+
return MemberCounter<T,A0...>(c0...,anything{});
53+
}
8554

8655
}
8756

88-
template <typename T>
89-
inline constexpr std::size_t count_members
90-
= details::construct_airity<std::remove_cv_t<std::remove_reference_t<T>>>::value;
9157

9258
#define SPLIT_FIELDS_FW_DECL(return_type, name, const_struct) \
9359
template <typename T, typename... Args> \
94-
constexpr return_type name(const_struct T& structure, Args&&... args);
60+
return_type name(const_struct T& structure, Args&&... args);
9561

9662

9763
#define SPLIT_FIELDS(return_type, name, function, const_struct) \
9864
/* this looks quite ugly bit it is worth it!*/ \
9965
template <typename T, typename... Args> \
100-
constexpr return_type name(const_struct T& structure, Args&&... args) \
66+
return_type name(const_struct T& structure, Args&&... args) \
10167
{ \
102-
constexpr std::size_t count = count_members<T>; \
68+
constexpr std::size_t count = cpp_utils::reflexion::count_members<T>; \
10369
static_assert(count <= 31); \
10470
\
10571
if constexpr (count == 1) \
@@ -343,61 +309,42 @@ inline constexpr std::size_t count_members
343309

344310
namespace cpp_utils::reflexion
345311
{
312+
template <typename T>
313+
inline constexpr std::size_t count_members = details::MemberCounter<T>();
346314

347-
SPLIT_FIELDS_FW_DECL(std::size_t, load_record, );
348-
315+
SPLIT_FIELDS_FW_DECL([[nodiscard]] constexpr std::size_t, composite_size, const);
316+
template <typename composite_t>
317+
consteval std::size_t composite_size();
349318

350319
template <typename field_t>
351-
struct is_field : std::false_type
352-
{
353-
};
354-
355-
template <typename field_t>
356-
inline constexpr bool is_field_v = is_field<field_t>::value;
357-
358-
359-
constexpr inline std::size_t _load_field(const auto& , auto& parsing_context, std::size_t offset, types::concepts::fundamental_type auto&& field)
360-
{
361-
using value_t = std::decay_t<decltype(field)>;
362-
load_value(parsing_context, offset, std::addressof(field), sizeof(value_t));
363-
return offset + sizeof(value_t);
364-
}
365-
366-
367-
template <typename record_t, typename parsing_context_t, typename T>
368-
constexpr inline std::size_t _load_field(const record_t& r, parsing_context_t& parsing_context, std::size_t offset, T&& field)
320+
[[nodiscard]] consteval std::size_t field_size()
369321
{
370-
return load_field(r, parsing_context, offset, field);
322+
if constexpr (std::is_bounded_array_v<field_t>)
323+
return sizeof(field_t)*std::extent_v<field_t>;
324+
return sizeof(field_t);
371325
}
372326

373-
template <typename record_t, typename parsing_context_t, typename T>
374-
constexpr inline std::size_t load_fields(const record_t& r, parsing_context_t& parsing_context,
375-
[[maybe_unused]] std::size_t offset, T&& field)
327+
[[nodiscard]] constexpr inline std::size_t fields_size(const auto& , auto& field)
376328
{
377-
using Field_t = std::remove_cv_t<std::remove_reference_t<T>>;
378-
constexpr std::size_t count = count_members<Field_t>;
379-
if constexpr (std::is_compound_v<Field_t> && (count > 1) && (not is_field_v<Field_t>))
380-
return load_record(field, parsing_context, offset);
329+
using Field_t = std::decay_t<decltype(field)>;
330+
if constexpr (std::is_compound_v<Field_t> && ! std::is_bounded_array_v<Field_t>)
331+
return composite_size<Field_t>();
381332
else
382-
return _load_field(r, parsing_context, offset, std::forward<T>(field));
333+
return field_size<Field_t>();
383334
}
384335

385-
template <typename record_t, typename parsing_context_t, typename T, typename... Ts>
386-
constexpr inline std::size_t load_fields(const record_t& r, parsing_context_t& parsing_context,
387-
[[maybe_unused]] std::size_t offset, T&& field, Ts&&... fields)
336+
template <typename record_t, typename T, typename... Ts>
337+
[[nodiscard]] constexpr inline std::size_t fields_size(const record_t& s, T&& field, Ts&&... fields)
388338
{
389-
offset = load_fields(r, parsing_context, offset, std::forward<T>(field));
390-
return load_fields(r, parsing_context, offset, std::forward<Ts>(fields)...);
339+
return fields_size(s, std::forward<T>(field)) + fields_size(s, std::forward<Ts>(fields)...);
391340
}
392341

393-
SPLIT_FIELDS(std::size_t, load_record, load_fields, );
342+
SPLIT_FIELDS([[nodiscard]] constexpr std::size_t, composite_size, fields_size, const);
394343

395-
template <typename record_t>
396-
constexpr record_t load_record(auto&& parsing_context, [[maybe_unused]] std::size_t offset)
344+
template <typename composite_t>
345+
consteval std::size_t composite_size()
397346
{
398-
record_t r;
399-
load_record(r, std::forward<decltype(parsing_context)>(parsing_context), offset);
400-
return r;
347+
return composite_size(composite_t{});
401348
}
402349

403350
} // namespace cpp_utils::reflexion

0 commit comments

Comments
 (0)