3#include "ll/api/base/FixedString.h"
4#include "ll/api/reflection/Reflection.h"
5#include "ll/api/reflection/ReflectionError.h"
6#include "ll/api/reflection/Serializer.h"
7#include "mc/deps/nbt/CompoundTagVariant.h"
26namespace ll::reflection {
30template <
class T,
class J, IsKeyFormatter F>
31inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<11>)
32 requires(std::is_arithmetic_v<std::remove_cvref_t<T>>);
33template <
class T,
class J, IsKeyFormatter F>
34inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<10>)
36 detail::has_value_deserializer_v<std::remove_cvref_t<T>, J, F>
37 || detail::is_string_serializable_v<std::remove_cvref_t<T>>
39template <
class T,
class J, IsKeyFormatter F>
40inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<9>)
41 requires(concepts::IsOptional<std::remove_cvref_t<T>>);
42template <
class T,
class J, IsKeyFormatter F>
43inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<9>)
44 requires(concepts::IsDispatcher<std::remove_cvref_t<T>>);
45template <
class T,
class J, IsKeyFormatter F>
46inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<8>)
47 requires(concepts::IsVectorBase<std::remove_cvref_t<T>>);
48template <
class T,
class J, IsKeyFormatter F>
49inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<7>)
50 requires(std::is_enum_v<std::remove_cvref_t<T>>);
51template <
class T,
class J, IsKeyFormatter F>
52inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<6>)
53 requires(concepts::IsVariant<std::remove_cvref_t<T>>);
54template <
class T,
class J, IsKeyFormatter F>
55inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<5>)
57 concepts::IsString<std::remove_cvref_t<T>> && std::is_assignable_v<std::remove_cvref_t<T>&, std::string>
58 && !std::same_as<std::remove_cvref_t<T>, std::string_view>
60template <
class T,
class J, IsKeyFormatter F>
61inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<5>)
62 requires(std::same_as<std::remove_cvref_t<T>, std::string_view>);
63template <
class T,
class J, IsKeyFormatter F>
64inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<4>)
65 requires(concepts::TupleLike<std::remove_cvref_t<T>>);
66template <
class T,
class J, IsKeyFormatter F>
67inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<3>)
68 requires(concepts::ArrayLike<std::remove_cvref_t<T>>);
69template <
class T,
class J, IsKeyFormatter F>
70inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<2>)
71 requires(concepts::Associative<std::remove_cvref_t<T>>);
72template <
class T,
class J, IsKeyFormatter F>
73inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<1>)
75template <
class T,
class J, IsKeyFormatter F>
76inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<0>);
78template <
class T,
class J, IsKeyFormatter F>
79inline Expected<> deserialize_inplace_impl(T& t, J&& j, F
const& keyFormatter)
80 requires(detail::has_inplace_deserializer_v<std::remove_cvref_t<T>, J, F>);
82template <
class T,
class V>
83inline void replace_deserialized_value(T& target, V&& value);
85template <
class T,
class J, IsKeyFormatter F>
86inline Expected<std::remove_cvref_t<T>> deserialize_construct(J&& j, F
const& keyFormatter);
90template <
class T,
class J, IsKeyFormatter F>
91inline Expected<> deserialize(T& t, J&& j, F
const& keyFormatter)
noexcept try {
92 using RT = std::remove_cvref_t<T>;
93 if constexpr (detail::has_inplace_deserializer_v<RT, J, F>) {
94 return deserialize_inplace_impl(t, std::forward<J>(j), keyFormatter);
96 auto value = deserialize_impl<RT>(std::forward<J>(j), keyFormatter, meta::PriorityTag<11>{});
97 if (!value)
return forwardError(value.error());
98 replace_deserialized_value(t, std::move(*value));
102 return makeExceptionError();
105template <
class T,
class J>
106inline Expected<> deserialize(T& t, J&& j)
noexcept {
107 return deserialize<T>(t, std::forward<J>(j), detail::default_key_formatter);
110template <
class T,
class J, IsKeyFormatter F>
111inline Expected<T> deserialize_to(J&& j, F
const& keyFormatter)
noexcept try {
112 return deserialize_construct<T>(std::forward<J>(j), keyFormatter);
114 return makeExceptionError();
117template <
class T,
class J>
118inline Expected<T> deserialize_to(J&& j)
noexcept {
119 return deserialize_to<T>(std::forward<J>(j), detail::default_key_formatter);
124template <
class T,
class J, IsKeyFormatter F>
125constexpr bool can_deserialize_construct_from_inplace_v =
126 std::is_default_constructible_v<std::remove_cvref_t<T>>
127 && detail::has_inplace_deserializer_v<std::remove_cvref_t<T>, J, F>;
129template <
class T,
class J, IsKeyFormatter F>
130inline Expected<> deserialize_inplace_impl(T& t, J&& j, F
const& keyFormatter)
131 requires(detail::has_inplace_deserializer_v<std::remove_cvref_t<T>, J, F>)
133 using RT = std::remove_cvref_t<T>;
134 using JT = std::remove_cvref_t<J>;
150template <
class T,
class V>
151inline void replace_deserialized_value(T& target, V&& value) {
152 using target_type = std::remove_cvref_t<T>;
153 using value_type = std::remove_cvref_t<V>;
156 std::same_as<target_type, value_type>,
157 "replace_deserialized_value requires the constructed value to match the target type"
160 if constexpr (std::is_assignable_v<T&, V&&>) {
161 target = std::forward<V>(value);
163 static_assert(!std::is_const_v<target_type>,
"deserialize target must not be const");
164 static_assert(!std::is_reference_v<T>,
"deserialize target must not be a reference");
166 std::is_constructible_v<target_type, V&&>,
167 "deserialize target must be assignable or constructible from the deserialized value"
169 std::destroy_at(std::addressof(target));
170 std::construct_at(std::addressof(target), std::forward<V>(value));
174template <
class T,
class J, IsKeyFormatter F>
175inline Expected<std::remove_cvref_t<T>> deserialize_construct(J&& j, F
const& keyFormatter) {
176 using RT = std::remove_cvref_t<T>;
177 if constexpr (can_deserialize_construct_from_inplace_v<RT, J, F>) {
179 auto res = deserialize(value, std::forward<J>(j), keyFormatter);
180 if (!res)
return forwardError(res.error());
183 return deserialize_impl<T>(std::forward<J>(j), keyFormatter, meta::PriorityTag<11>{});
187template <
class T,
class V>
188inline void array_append_value(T& t, V&& value) {
189 if constexpr (
requires(T& a, std::remove_cvref_t<V> v) { a.emplace_back(std::move(v)); }) {
190 t.emplace_back(std::forward<V>(value));
191 }
else if constexpr (
requires(T& a, std::remove_cvref_t<V> v) { a.push_back(std::move(v)); }) {
192 t.push_back(std::forward<V>(value));
193 }
else if constexpr (
requires(T& a, std::remove_cvref_t<V> v) { a.insert(a.end(), std::move(v)); }) {
194 t.insert(t.end(), std::forward<V>(value));
195 }
else if constexpr (
requires(T& a, std::remove_cvref_t<V> v) { a.insert(std::move(v)); }) {
196 t.insert(std::forward<V>(value));
199 ll::traits::always_false<std::remove_cvref_t<T>>,
200 "array-like type must support appending a constructed value for deserialization"
205template <
class T,
class K,
class V>
206inline void associative_insert_value(T& t, K&& key, V&& value) {
207 if constexpr (
requires(T& a, std::remove_cvref_t<K> k, std::remove_cvref_t<V> v) {
208 a.try_emplace(std::move(k), std::move(v));
210 t.try_emplace(std::forward<K>(key), std::forward<V>(value));
211 }
else if constexpr (
requires(T& a, std::remove_cvref_t<K> k, std::remove_cvref_t<V> v) {
212 a.emplace(std::move(k), std::move(v));
214 t.emplace(std::forward<K>(key), std::forward<V>(value));
215 }
else if constexpr (
requires(T& a, std::remove_cvref_t<K> k, std::remove_cvref_t<V> v) {
216 a.insert_or_assign(std::move(k), std::move(v));
218 t.insert_or_assign(std::forward<K>(key), std::forward<V>(value));
221 ll::traits::always_false<std::remove_cvref_t<T>>,
222 "associative type must support inserting a constructed mapped value for deserialization"
227template <
typename Child,
typename J>
228[[nodiscard]]
inline decltype(
auto) array_child_at(J&& j,
size_t index) {
229 if constexpr (std::same_as<std::remove_cvref_t<J>, CompoundTagVariant>) {
230 return CompoundTagVariant{j[index]};
231 }
else if constexpr (std::same_as<std::remove_cvref_t<J>, UniqueTagPtr>) {
232 return CompoundTagVariant{j[index]};
233 }
else if constexpr (std::is_lvalue_reference_v<J&&>) {
234 return static_cast<J&&
>(j[index]);
236 return std::remove_cvref_t<J>(j[index]);
240template <
typename J,
typename K>
241[[nodiscard]]
inline decltype(
auto) object_child_at(J&& j, K&& key) {
242 if constexpr (std::same_as<std::remove_cvref_t<J>, CompoundTagVariant>) {
243 return CompoundTagVariant{j[std::forward<K>(key)]};
244 }
else if constexpr (std::same_as<std::remove_cvref_t<J>, UniqueTagPtr>) {
245 return CompoundTagVariant{j[std::forward<K>(key)]};
246 }
else if constexpr (std::is_lvalue_reference_v<J&&>) {
247 return static_cast<J&&
>(j[std::forward<K>(key)]);
249 return std::remove_cvref_t<J>(j[std::forward<K>(key)]);
253template <auto MemberPtr,
bool AllowOptionalMissing,
class T,
class J, IsKeyFormatter F>
254inline Expected<> member_deserialize_impl(T& t, J&& j, F
const& keyFormatter) {
255 static_assert(!typeNameStem(getRawName<MemberPtr>()).empty(),
"member name is empty");
256 if (!j.is_object())
return makeDeserObjectTypeError();
257 auto key = keyFormatter(typeNameStem(getRawName<MemberPtr>()));
258 if (!j.contains(key)) {
259 using MemberT =
decltype(t.*MemberPtr);
260 if constexpr (AllowOptionalMissing && concepts::IsOptional<std::remove_cvref_t<MemberT>>) {
261 t.*MemberPtr = std::nullopt;
264 return makeDeserMissingRequiredFieldError(std::string{key});
267 decltype(
auto) child = object_child_at(std::forward<J>(j), key);
268 return deserialize(t.*MemberPtr, std::forward<
decltype(child)>(child), keyFormatter);
271template <auto MemberPtr,
class T,
class D,
class J, IsKeyFormatter F>
272inline Expected<> member_deserialize_or_impl(T& t, J&& j, D&& defaultValue, F
const& keyFormatter) {
273 static_assert(!typeNameStem(getRawName<MemberPtr>()).empty(),
"member name is empty");
274 if (!j.is_object())
return makeDeserObjectTypeError();
276 auto key = keyFormatter(typeNameStem(getRawName<MemberPtr>()));
277 if (!j.contains(key)) {
278 t.*MemberPtr = std::forward<D>(defaultValue);
282 decltype(
auto) child = object_child_at(std::forward<J>(j), key);
283 return deserialize(t.*MemberPtr, std::forward<
decltype(child)>(child), keyFormatter);
286template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
287inline Expected<> member_deserialize_default_impl(T& t, J&& j, F
const& keyFormatter) {
288 static_assert(!typeNameStem(getRawName<MemberPtr>()).empty(),
"member name is empty");
289 if (!j.is_object())
return makeDeserObjectTypeError();
291 auto key = keyFormatter(typeNameStem(getRawName<MemberPtr>()));
292 if (!j.contains(key)) {
296 decltype(
auto) child = object_child_at(std::forward<J>(j), key);
297 return deserialize(t.*MemberPtr, std::forward<
decltype(child)>(child), keyFormatter);
300template <ll::FixedString Key,
bool AllowOptionalMissing,
class T,
class J, IsKeyFormatter F>
301inline Expected<> field_deserialize_impl(T& t, J&& j, F
const& keyFormatter) {
302 static_assert(Key.size() != 0,
"field name is empty");
303 if (!j.is_object())
return makeDeserObjectTypeError();
305 auto key = keyFormatter(Key.sv());
306 if (!j.contains(key)) {
307 if constexpr (AllowOptionalMissing && concepts::IsOptional<std::remove_cvref_t<T>>) {
311 return makeDeserMissingRequiredFieldError(std::string{key});
315 decltype(
auto) child = object_child_at(std::forward<J>(j), key);
316 return deserialize(t, std::forward<
decltype(child)>(child), keyFormatter);
319template <ll::FixedString Key,
class T,
class D,
class J, IsKeyFormatter F>
320inline Expected<> field_deserialize_or_impl(T& t, J&& j, D&& defaultValue, F
const& keyFormatter) {
321 static_assert(Key.size() != 0,
"field name is empty");
322 if (!j.is_object())
return makeDeserObjectTypeError();
324 auto key = keyFormatter(Key.sv());
325 if (!j.contains(key)) {
326 t = std::forward<D>(defaultValue);
330 decltype(
auto) child = object_child_at(std::forward<J>(j), key);
331 return deserialize(t, std::forward<
decltype(child)>(child), keyFormatter);
334template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
335inline Expected<> field_deserialize_default_impl(T& t, J&& j, F
const& keyFormatter) {
336 static_assert(Key.size() != 0,
"field name is empty");
337 if (!j.is_object())
return makeDeserObjectTypeError();
339 auto key = keyFormatter(Key.sv());
340 if (!j.contains(key)) {
344 decltype(
auto) child = object_child_at(std::forward<J>(j), key);
345 return deserialize(t, std::forward<
decltype(child)>(child), keyFormatter);
350template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
351inline Expected<> member_deserialize(T& t, J&& j, F
const& keyFormatter)
noexcept
352 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
354 return member_deserialize_impl<MemberPtr, true>(t, std::forward<J>(j), keyFormatter);
357template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
358inline Expected<> member_deserialize_required(T& t, J&& j, F
const& keyFormatter)
noexcept
359 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
361 return member_deserialize_impl<MemberPtr, false>(t, std::forward<J>(j), keyFormatter);
364template <auto MemberPtr,
class T,
class D,
class J, IsKeyFormatter F>
365inline Expected<> member_deserialize_or(T& t, J&& j, D&& defaultValue, F
const& keyFormatter)
noexcept
368 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
371 return member_deserialize_or_impl<MemberPtr>(t, std::forward<J>(j), std::forward<D>(defaultValue), keyFormatter);
374template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
375inline Expected<> field_deserialize(T& t, J&& j, F
const& keyFormatter)
noexcept
376 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
378 return field_deserialize_impl<Key, true>(t, std::forward<J>(j), keyFormatter);
381template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
382inline Expected<> field_deserialize_required(T& t, J&& j, F
const& keyFormatter)
noexcept
383 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
385 return field_deserialize_impl<Key, false>(t, std::forward<J>(j), keyFormatter);
388template <ll::FixedString Key,
class T,
class D,
class J, IsKeyFormatter F>
389inline Expected<> field_deserialize_or(T& t, J&& j, D&& defaultValue, F
const& keyFormatter)
noexcept
392 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
395 return field_deserialize_or_impl<Key>(t, std::forward<J>(j), std::forward<D>(defaultValue), keyFormatter);
398template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
399inline Expected<> member_deserialize(T& t, J
const& j, F
const& keyFormatter)
noexcept {
400 return member_deserialize_impl<MemberPtr, true>(t, j, keyFormatter);
403template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
404inline Expected<> member_deserialize_required(T& t, J
const& j, F
const& keyFormatter)
noexcept {
405 return member_deserialize_impl<MemberPtr, false>(t, j, keyFormatter);
408template <auto MemberPtr,
class T,
class D,
class J, IsKeyFormatter F>
409inline Expected<> member_deserialize_or(T& t, J
const& j, D&& defaultValue, F
const& keyFormatter)
noexcept
412 return member_deserialize_or_impl<MemberPtr>(t, j, std::forward<D>(defaultValue), keyFormatter);
415template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
416inline Expected<> field_deserialize(T& t, J
const& j, F
const& keyFormatter)
noexcept {
417 return field_deserialize_impl<Key, true>(t, j, keyFormatter);
420template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
421inline Expected<> field_deserialize_required(T& t, J
const& j, F
const& keyFormatter)
noexcept {
422 return field_deserialize_impl<Key, false>(t, j, keyFormatter);
425template <ll::FixedString Key,
class T,
class D,
class J, IsKeyFormatter F>
426inline Expected<> field_deserialize_or(T& t, J
const& j, D&& defaultValue, F
const& keyFormatter)
noexcept
429 return field_deserialize_or_impl<Key>(t, j, std::forward<D>(defaultValue), keyFormatter);
432template <auto MemberPtr,
class T,
class J>
433inline Expected<> member_deserialize(T& t, J&& j)
noexcept
434 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
436 return member_deserialize<MemberPtr>(t, std::forward<J>(j), detail::default_key_formatter);
439template <auto MemberPtr,
class T,
class J>
440inline Expected<> member_deserialize_required(T& t, J&& j)
noexcept
441 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
443 return member_deserialize_required<MemberPtr>(t, std::forward<J>(j), detail::default_key_formatter);
446template <auto MemberPtr,
class T,
class D,
class J>
447inline Expected<> member_deserialize_or(T& t, J&& j, D&& defaultValue)
noexcept
450 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
453 return member_deserialize_or<MemberPtr>(
456 std::forward<D>(defaultValue),
457 detail::default_key_formatter
461template <ll::FixedString Key,
class T,
class J>
462inline Expected<> field_deserialize(T& t, J&& j)
noexcept
463 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
465 return field_deserialize<Key>(t, std::forward<J>(j), detail::default_key_formatter);
468template <ll::FixedString Key,
class T,
class J>
469inline Expected<> field_deserialize_required(T& t, J&& j)
noexcept
470 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
472 return field_deserialize_required<Key>(t, std::forward<J>(j), detail::default_key_formatter);
475template <ll::FixedString Key,
class T,
class D,
class J>
476inline Expected<> field_deserialize_or(T& t, J&& j, D&& defaultValue)
noexcept
479 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
482 return field_deserialize_or<Key>(
485 std::forward<D>(defaultValue),
486 detail::default_key_formatter
490template <auto MemberPtr,
class T,
class J>
491inline Expected<> member_deserialize(T& t, J
const& j)
noexcept {
492 return member_deserialize_impl<MemberPtr, true>(t, j, detail::default_key_formatter);
495template <auto MemberPtr,
class T,
class J>
496inline Expected<> member_deserialize_required(T& t, J
const& j)
noexcept {
497 return member_deserialize_impl<MemberPtr, false>(t, j, detail::default_key_formatter);
500template <auto MemberPtr,
class T,
class D,
class J>
501inline Expected<> member_deserialize_or(T& t, J
const& j, D&& defaultValue)
noexcept
504 return member_deserialize_or_impl<MemberPtr>(t, j, std::forward<D>(defaultValue), detail::default_key_formatter);
507template <ll::FixedString Key,
class T,
class J>
508inline Expected<> field_deserialize(T& t, J
const& j)
noexcept {
509 return field_deserialize_impl<Key, true>(t, j, detail::default_key_formatter);
512template <ll::FixedString Key,
class T,
class J>
513inline Expected<> field_deserialize_required(T& t, J
const& j)
noexcept {
514 return field_deserialize_impl<Key, false>(t, j, detail::default_key_formatter);
517template <ll::FixedString Key,
class T,
class D,
class J>
518inline Expected<> field_deserialize_or(T& t, J
const& j, D&& defaultValue)
noexcept
521 return field_deserialize_or_impl<Key>(t, j, std::forward<D>(defaultValue), detail::default_key_formatter);
524template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
525inline Expected<> member(T& t, J&& j, F
const& keyFormatter)
noexcept
526 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
528 return member_deserialize<MemberPtr>(t, std::forward<J>(j), keyFormatter);
531template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
532inline Expected<> required_member(T& t, J&& j, F
const& keyFormatter)
noexcept
533 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
535 return member_deserialize_required<MemberPtr>(t, std::forward<J>(j), keyFormatter);
538template <auto MemberPtr,
class T,
class D,
class J, IsKeyFormatter F>
539inline Expected<> default_member(T& t, J&& j, D&& defaultValue, F
const& keyFormatter)
noexcept
542 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
545 return member_deserialize_or<MemberPtr>(t, std::forward<J>(j), std::forward<D>(defaultValue), keyFormatter);
548template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
549inline Expected<> default_member(T& t, J&& j, F
const& keyFormatter)
noexcept
550 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
552 return member_deserialize_default_impl<MemberPtr>(t, std::forward<J>(j), keyFormatter);
555template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
556inline Expected<> field(T& t, J&& j, F
const& keyFormatter)
noexcept
557 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
559 return field_deserialize<Key>(t, std::forward<J>(j), keyFormatter);
562template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
563inline Expected<> required_field(T& t, J&& j, F
const& keyFormatter)
noexcept
564 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
566 return field_deserialize_required<Key>(t, std::forward<J>(j), keyFormatter);
569template <ll::FixedString Key,
class T,
class D,
class J, IsKeyFormatter F>
570inline Expected<> default_field(T& t, J&& j, D&& defaultValue, F
const& keyFormatter)
noexcept
573 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
576 return field_deserialize_or<Key>(t, std::forward<J>(j), std::forward<D>(defaultValue), keyFormatter);
579template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
580inline Expected<> default_field(T& t, J&& j, F
const& keyFormatter)
noexcept
581 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
583 return field_deserialize_default_impl<Key>(t, std::forward<J>(j), keyFormatter);
586template <auto MemberPtr,
class T,
class J>
587inline Expected<> member(T& t, J&& j)
noexcept
588 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
590 return member<MemberPtr>(t, std::forward<J>(j), detail::default_key_formatter);
593template <auto MemberPtr,
class T,
class J>
594inline Expected<> required_member(T& t, J&& j)
noexcept
595 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
597 return required_member<MemberPtr>(t, std::forward<J>(j), detail::default_key_formatter);
600template <auto MemberPtr,
class T,
class D,
class J>
601inline Expected<> default_member(T& t, J&& j, D&& defaultValue)
noexcept
604 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
607 return default_member<MemberPtr>(
610 std::forward<D>(defaultValue),
611 detail::default_key_formatter
615template <auto MemberPtr,
class T,
class J>
616inline Expected<> default_member(T& t, J&& j)
noexcept
617 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
619 return member_deserialize_default_impl<MemberPtr>(t, std::forward<J>(j), detail::default_key_formatter);
622template <ll::FixedString Key,
class T,
class J>
623inline Expected<> field(T& t, J&& j)
noexcept
624 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
626 return field<Key>(t, std::forward<J>(j), detail::default_key_formatter);
629template <ll::FixedString Key,
class T,
class J>
630inline Expected<> required_field(T& t, J&& j)
noexcept
631 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
633 return required_field<Key>(t, std::forward<J>(j), detail::default_key_formatter);
636template <ll::FixedString Key,
class T,
class D,
class J>
637inline Expected<> default_field(T& t, J&& j, D&& defaultValue)
noexcept
640 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
643 return default_field<Key>(t, std::forward<J>(j), std::forward<D>(defaultValue), detail::default_key_formatter);
646template <ll::FixedString Key,
class T,
class J>
647inline Expected<> default_field(T& t, J&& j)
noexcept
648 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
650 return field_deserialize_default_impl<Key>(t, std::forward<J>(j), detail::default_key_formatter);
653template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
654inline Expected<> member(T& t, J
const& j, F
const& keyFormatter)
noexcept {
655 return member_deserialize<MemberPtr>(t, j, keyFormatter);
658template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
659inline Expected<> required_member(T& t, J
const& j, F
const& keyFormatter)
noexcept {
660 return member_deserialize_required<MemberPtr>(t, j, keyFormatter);
663template <auto MemberPtr,
class T,
class D,
class J, IsKeyFormatter F>
664inline Expected<> default_member(T& t, J
const& j, D&& defaultValue, F
const& keyFormatter)
noexcept
667 return member_deserialize_or<MemberPtr>(t, j, std::forward<D>(defaultValue), keyFormatter);
670template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
671inline Expected<> default_member(T& t, J
const& j, F
const& keyFormatter)
noexcept {
672 return member_deserialize_default_impl<MemberPtr>(t, j, keyFormatter);
675template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
676inline Expected<> field(T& t, J
const& j, F
const& keyFormatter)
noexcept {
677 return field_deserialize<Key>(t, j, keyFormatter);
680template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
681inline Expected<> required_field(T& t, J
const& j, F
const& keyFormatter)
noexcept {
682 return field_deserialize_required<Key>(t, j, keyFormatter);
685template <ll::FixedString Key,
class T,
class D,
class J, IsKeyFormatter F>
686inline Expected<> default_field(T& t, J
const& j, D&& defaultValue, F
const& keyFormatter)
noexcept
689 return field_deserialize_or<Key>(t, j, std::forward<D>(defaultValue), keyFormatter);
692template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
693inline Expected<> default_field(T& t, J
const& j, F
const& keyFormatter)
noexcept {
694 return field_deserialize_default_impl<Key>(t, j, keyFormatter);
697template <auto MemberPtr,
class T,
class J>
698inline Expected<> member(T& t, J
const& j)
noexcept {
699 return member<MemberPtr>(t, j, detail::default_key_formatter);
702template <auto MemberPtr,
class T,
class J>
703inline Expected<> required_member(T& t, J
const& j)
noexcept {
704 return required_member<MemberPtr>(t, j, detail::default_key_formatter);
707template <auto MemberPtr,
class T,
class D,
class J>
708inline Expected<> default_member(T& t, J
const& j, D&& defaultValue)
noexcept
711 return default_member<MemberPtr>(t, j, std::forward<D>(defaultValue), detail::default_key_formatter);
714template <auto MemberPtr,
class T,
class J>
715inline Expected<> default_member(T& t, J
const& j)
noexcept {
716 return member_deserialize_default_impl<MemberPtr>(t, j, detail::default_key_formatter);
719template <ll::FixedString Key,
class T,
class J>
720inline Expected<> field(T& t, J
const& j)
noexcept {
721 return field<Key>(t, j, detail::default_key_formatter);
724template <ll::FixedString Key,
class T,
class J>
725inline Expected<> required_field(T& t, J
const& j)
noexcept {
726 return required_field<Key>(t, j, detail::default_key_formatter);
729template <ll::FixedString Key,
class T,
class D,
class J>
730inline Expected<> default_field(T& t, J
const& j, D&& defaultValue)
noexcept
733 return default_field<Key>(t, j, std::forward<D>(defaultValue), detail::default_key_formatter);
736template <ll::FixedString Key,
class T,
class J>
737inline Expected<> default_field(T& t, J
const& j)
noexcept {
738 return field_deserialize_default_impl<Key>(t, j, detail::default_key_formatter);
743template <
class T,
class J,
IsKeyFormatter F,
size_t I = 0,
class... Args>
744inline Expected<std::remove_cvref_t<T>> tuple_deserialize_value(J&& j, F
const& keyFormatter, Args&&... args) {
745 using RT = std::remove_cvref_t<T>;
746 if constexpr (I == std::tuple_size_v<RT>) {
747 return RT{std::forward<Args>(args)...};
749 using element_type = std::remove_cvref_t<std::tuple_element_t<I, RT>>;
750 auto child = array_child_at<element_type>(std::forward<J>(j), I);
751 auto value = deserialize_construct<element_type>(std::forward<
decltype(child)>(child), keyFormatter);
753 return makeDeserIndexError(I, value.error());
755 return tuple_deserialize_value<RT, J, F, I + 1>(
758 std::forward<Args>(args)...,
764template <
class T,
class J,
IsKeyFormatter F,
size_t I = 0,
class... Args>
765inline Expected<std::remove_cvref_t<T>> reflectable_deserialize_value(J&& j, F
const& keyFormatter, Args&&... args) {
766 using RT = std::remove_cvref_t<T>;
767 if constexpr (I == member_count_v<RT>) {
768 return RT{std::forward<Args>(args)...};
770 using member_type = std::remove_cvref_t<member_t<I, RT>>;
771 auto key = keyFormatter(member_name_array_v<RT>[I]);
772 std::string sname{key};
773 if (!j.contains(sname)) {
774 if constexpr (concepts::IsOptional<member_type>) {
775 return reflectable_deserialize_value<RT, J, F, I + 1>(
778 std::forward<Args>(args)...,
779 member_type{std::nullopt}
782 return makeDeserMissingRequiredFieldError(sname);
786 decltype(
auto) child = object_child_at(std::forward<J>(j), sname);
787 auto value = deserialize_construct<member_type>(std::forward<
decltype(child)>(child), keyFormatter);
789 return makeDeserMemberError(sname, value.error());
791 return reflectable_deserialize_value<RT, J, F, I + 1>(
794 std::forward<Args>(args)...,
802 requires(std::integral<RT>)
803constexpr bool isRepresentable(int64 value)
noexcept {
804 if constexpr (std::is_signed_v<RT>) {
805 return value >=
static_cast<int64
>((std::numeric_limits<RT>::lowest)())
806 && value <=
static_cast<int64
>((std::numeric_limits<RT>::max)());
808 return value >= 0 &&
static_cast<uint64
>(value) <=
static_cast<uint64
>((std::numeric_limits<RT>::max)());
813 requires(std::integral<RT>)
814constexpr bool isRepresentable(uint64 value)
noexcept {
815 return value <= static_cast<uint64>((std::numeric_limits<RT>::max)());
819 requires(std::integral<RT> && !std::same_as<RT, bool>)
820inline Expected<RT> narrowIntegral(int64 value) {
821 if (!isRepresentable<RT>(value)) {
822 return makeDeserNumberRangeError(fmt::to_string(value), type_name_v<RT>);
824 return static_cast<RT
>(value);
828 requires(std::integral<RT> && !std::same_as<RT, bool>)
829inline Expected<RT> narrowIntegral(uint64 value) {
830 if (!isRepresentable<RT>(value)) {
831 return makeDeserNumberRangeError(fmt::to_string(value), type_name_v<RT>);
833 return static_cast<RT
>(value);
836template <
class T,
class J, IsKeyFormatter F>
837inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const&, meta::PriorityTag<11>)
838 requires(std::is_arithmetic_v<std::remove_cvref_t<T>>)
840 using RT = std::remove_cvref_t<T>;
841 if (!j.is_number() && !j.is_boolean())
return makeDeserArithmeticTypeError();
843 if constexpr (std::same_as<RT, bool>) {
844 return static_cast<RT
>(j);
845 }
else if constexpr (std::integral<RT> && !std::same_as<RT, bool>) {
846 if (!j.is_number())
return static_cast<RT
>(
static_cast<bool>(j));
847 if (j.is_number_float()) {
848 auto value =
static_cast<double>(j);
849 if (std::trunc(value) != value)
return makeDeserNumberFractionError(fmt::to_string(value));
852 if constexpr (std::unsigned_integral<RT>) {
853 if (value < 0.0 || value >= std::ldexp(1.0, 64)) {
854 return makeDeserNumberRangeError(fmt::to_string(value), type_name_v<RT>);
856 return narrowIntegral<RT>(
static_cast<uint64
>(value));
858 if (value < -std::ldexp(1.0, 63) || value >= std::ldexp(1.0, 63)) {
859 return makeDeserNumberRangeError(fmt::to_string(value), type_name_v<RT>);
861 return narrowIntegral<RT>(
static_cast<int64
>(value));
864 if (j.is_number_unsigned())
return narrowIntegral<RT>(
static_cast<uint64
>(j));
865 return narrowIntegral<RT>(
static_cast<int64
>(j));
868 if (j.is_number_float()) {
869 auto value =
static_cast<double>(j);
870 if (std::abs(value) >
static_cast<double>((std::numeric_limits<RT>::max)())) {
871 return makeDeserNumberRangeError(fmt::to_string(value), type_name_v<RT>);
874 return static_cast<RT
>(j);
878template <
class T,
class J, IsKeyFormatter F>
879inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<10>)
881 detail::has_value_deserializer_v<std::remove_cvref_t<T>, J, F>
882 || detail::is_string_serializable_v<std::remove_cvref_t<T>>
885 using RT = std::remove_cvref_t<T>;
886 if constexpr (detail::has_value_deserializer_v<RT, J, F>) {
887 using JT = std::remove_cvref_t<J>;
888 decltype(
auto) result = [&]() ->
decltype(
auto) {
897 }
else if constexpr (
requires {
905 using Result = std::remove_cvref_t<
decltype(result)>;
906 if constexpr (concepts::IsLeviExpected<Result>) {
907 if (!result)
return forwardError(result.error());
908 return std::move(*result);
910 return std::forward<decltype(result)>(result);
913 if (!j.is_string())
return makeDeserStringTypeError();
914 if constexpr (std::is_lvalue_reference_v<J&&> && concepts::BorrowableStringSource<J>) {
915 auto const& text = std::as_const(j).template get_ref<typename std::remove_cvref_t<J>::string_t
const&>();
917 return *std::move(res);
919 return forwardError(res.error());
922 std::string text = std::string{std::forward<J>(j)};
924 return *std::move(res);
926 return forwardError(res.error());
932template <
class T,
class J, IsKeyFormatter F>
933inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<9>)
934 requires(concepts::IsOptional<std::remove_cvref_t<T>>)
936 using RT = std::remove_cvref_t<T>;
937 using value_type =
typename RT::value_type;
939 return RT{std::nullopt};
941 auto value = deserialize_construct<value_type>(std::forward<J>(j), keyFormatter);
942 if (!value)
return forwardError(value.error());
943 return RT{std::move(*value)};
946template <
class T,
class J, IsKeyFormatter F>
947inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<9>)
948 requires(concepts::IsDispatcher<std::remove_cvref_t<T>>)
950 using RT = std::remove_cvref_t<T>;
951 using storage_type =
typename RT::storage_type;
952 auto storage = deserialize_construct<storage_type>(std::forward<J>(j), keyFormatter);
953 if (!storage)
return forwardError(storage.error());
954 RT result{std::move(*storage)};
959template <
class T,
class J, IsKeyFormatter F>
960inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<8>)
961 requires(concepts::IsVectorBase<std::remove_cvref_t<T>>)
963 using RT = std::remove_cvref_t<T>;
964 if (!j.is_array())
return makeDeserArrayTypeError();
967 RT::forEachComponent([&]<
typename axis_type,
size_t iter> {
969 auto child = array_child_at<axis_type>(std::forward<J>(j), iter);
970 auto value = deserialize_construct<axis_type>(std::forward<
decltype(child)>(child), keyFormatter);
972 res = makeDeserIndexError(iter, value.error());
974 result.template get<axis_type, iter>() = std::move(*value);
978 if (!res)
return forwardError(res.error());
982template <
class T,
class J, IsKeyFormatter F>
983inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<7>)
984 requires(std::is_enum_v<std::remove_cvref_t<T>>)
986 using enum_type = std::remove_cvref_t<T>;
988 std::string s = std::string{std::forward<J>(j)};
989 if (
auto res = detail::string_to_enum<enum_type>(s, keyFormatter)) {
991 }
else if constexpr (magic_enum::detail::subtype_v<enum_type> == magic_enum::detail::enum_subtype::flags) {
992 return makeDeserEnumFlagsValueError(s);
994 return makeDeserEnumValueError(s);
996 }
else if (j.is_number()) {
997 return static_cast<enum_type
>(
static_cast<std::underlying_type_t<enum_type>
>(j));
999 return makeDeserEnumTypeError();
1003template <
class T,
class J, IsKeyFormatter F>
1004inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<6>)
1005 requires(concepts::IsVariant<std::remove_cvref_t<T>>)
1007 using RT = std::remove_cvref_t<T>;
1008 std::optional<RT> matched;
1010 [&]<
typename... Ts>(std::type_identity<std::variant<Ts...>>) {
1013 if (matched.has_value())
return;
1014 if constexpr (std::is_arithmetic_v<Ts>) {
1015 Expected<Ts> value = [&]() -> Expected<Ts> {
1016 if constexpr (std::same_as<Ts, bool>) {
1017 if (j.is_boolean())
return j.template get<bool>();
1018 }
else if constexpr (std::is_floating_point_v<Ts>) {
1019 if (j.is_number_float()) {
1020 auto number = j.template get<double>();
1021 if (std::abs(number) <=
static_cast<double>((std::numeric_limits<Ts>::max)())) {
1022 return static_cast<Ts
>(number);
1025 }
else if constexpr (std::is_signed_v<Ts>) {
1026 if (j.is_number_integer() && !j.is_number_unsigned()) {
1027 auto number = j.template get<int64>();
1028 if (isRepresentable<Ts>(number))
return static_cast<Ts
>(number);
1030 }
else if constexpr (std::is_unsigned_v<Ts>) {
1031 if (j.is_number_unsigned()) {
1032 auto number = j.template get<uint64>();
1033 if (isRepresentable<Ts>(number))
return static_cast<Ts
>(number);
1036 return makeDeserNumberTypeError(j.type_name());
1039 matched.emplace(std::in_place_type<Ts>, std::move(*value));
1044 }(std::type_identity<RT>{});
1046 [&]<
typename... Ts>(std::type_identity<std::variant<Ts...>>) {
1049 if (matched.has_value())
return;
1050 if (
auto value = deserialize_construct<Ts>(std::forward<J>(j), keyFormatter); value) {
1051 matched.emplace(std::in_place_type<Ts>, std::move(*value));
1055 }(std::type_identity<RT>{});
1057 if (!matched)
return makeDeserVariantCastError(j.type_name(), j.dump());
1058 return std::move(*matched);
1061template <
class T,
class J, IsKeyFormatter F>
1062inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const&, meta::PriorityTag<5>)
1064 concepts::IsString<std::remove_cvref_t<T>> && std::is_assignable_v<std::remove_cvref_t<T>&, std::string>
1065 && !std::same_as<std::remove_cvref_t<T>, std::string_view>
1068 using RT = std::remove_cvref_t<T>;
1069 if (!j.is_string())
return makeDeserStringTypeError();
1070 return RT{std::string{std::forward<J>(j)}};
1073template <
class T,
class J, IsKeyFormatter F>
1074inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const&, meta::PriorityTag<5>)
1075 requires(std::same_as<std::remove_cvref_t<T>, std::string_view>)
1077 if (!j.is_string())
return makeDeserStringTypeError();
1078 if constexpr (std::is_lvalue_reference_v<J&&> && concepts::BorrowableStringSource<J>) {
1079 auto const& text = std::as_const(j).template get_ref<typename std::remove_cvref_t<J>::string_t
const&>();
1080 return std::string_view{text};
1082 return makeDeserStringViewLifetimeError();
1086template <
class T,
class J, IsKeyFormatter F>
1087inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<4>)
1088 requires(concepts::TupleLike<std::remove_cvref_t<T>>)
1090 using RT = std::remove_cvref_t<T>;
1091 if (!j.is_array())
return makeDeserArrayTypeError();
1092 if (j.size() != std::tuple_size_v<RT>)
return makeDeserArraySizeError(std::tuple_size_v<RT>);
1093 return tuple_deserialize_value<RT>(std::forward<J>(j), keyFormatter);
1096template <
class T,
class J, IsKeyFormatter F>
1097inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<3>)
1098 requires(concepts::ArrayLike<std::remove_cvref_t<T>>)
1100 using RT = std::remove_cvref_t<T>;
1101 using value_type =
typename RT::value_type;
1102 if (!j.is_array())
return makeDeserArrayTypeError();
1104 if constexpr (
requires(RT& a) { a.clear(); }) {
1107 for (
size_t i = 0; i < j.size(); ++i) {
1108 auto child = array_child_at<value_type>(std::forward<J>(j), i);
1109 auto value = deserialize_construct<value_type>(std::forward<
decltype(child)>(child), keyFormatter);
1110 if (!value)
return makeDeserIndexError(i, value.error());
1111 array_append_value(result, std::move(*value));
1116template <
class T,
class J, IsKeyFormatter F>
1117inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<2>)
1118 requires(concepts::Associative<std::remove_cvref_t<T>>)
1120 using RT = std::remove_cvref_t<T>;
1122 detail::is_key_stringifiable_v<typename RT::key_type>,
1123 "an associative container key has to be a string, an enum, or a type with a "
1124 "ll::reflection::Serializer<T>::to_string / from_string specialization"
1126 J
const& jConst = j;
1127 if (!jConst.is_object())
return makeDeserObjectTypeError();
1129 if constexpr (
requires(RT& a) { a.clear(); }) {
1132 for (
auto&& [k, v] : jConst.items()) {
1133 std::string keyString{k};
1134 auto keyOpt = string_to_type<typename RT::key_type>(keyString, keyFormatter);
1135 if (!keyOpt.has_value()) {
1136 auto error = makeDeserInvalidKeyError(keyString);
1137 return makeDeserKeyError(keyString, error.error());
1139 using mapped_type =
typename RT::mapped_type;
1140 auto value = deserialize_construct<mapped_type>(std::forward<
decltype(v)>(v), keyFormatter);
1141 if (!value)
return makeDeserKeyError(keyString, value.error());
1142 associative_insert_value(result, std::move(*keyOpt), std::move(*value));
1147template <
class T,
class J, IsKeyFormatter F>
1148inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const& keyFormatter, meta::PriorityTag<1>)
1151 using RT = std::remove_cvref_t<T>;
1152 J
const& jConst = j;
1153 if (!jConst.is_object())
return makeDeserObjectTypeError();
1154 return reflectable_deserialize_value<RT>(std::forward<J>(j), keyFormatter);
1157template <
class T,
class J,
class F>
1158constexpr bool use_convertible_deserialize_fallback_v =
1159 !std::is_arithmetic_v<std::remove_cvref_t<T>> && !detail::has_value_deserializer_v<std::remove_cvref_t<T>, J, F>
1160 && !concepts::IsOptional<std::remove_cvref_t<T>> && !concepts::IsDispatcher<std::remove_cvref_t<T>>
1161 && !concepts::IsVectorBase<std::remove_cvref_t<T>> && !std::is_enum_v<std::remove_cvref_t<T>>
1162 && !concepts::IsVariant<std::remove_cvref_t<T>>
1163 && !(concepts::IsString<std::remove_cvref_t<T>> && std::is_assignable_v<std::remove_cvref_t<T>&, std::string>)
1164 && !std::same_as<std::remove_cvref_t<T>, std::string_view> && !concepts::TupleLike<std::remove_cvref_t<T>>
1165 && !concepts::ArrayLike<std::remove_cvref_t<T>> && !concepts::Associative<std::remove_cvref_t<T>>
1166 && !
Reflectable<std::remove_cvref_t<T>> && std::convertible_to<J, std::remove_cvref_t<T>>;
1168template <
class T,
class J, IsKeyFormatter F>
1169inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F
const&, meta::PriorityTag<0>) {
1170 using RT = std::remove_cvref_t<T>;
1171 if constexpr (use_convertible_deserialize_fallback_v<T, J, F>) {
1172 return static_cast<RT
>(j);
1175 traits::always_false<RT>,
1176 "cannot deserialize this type: provide a ll::reflection::Serializer<T> specialization, or use an "
1177 "arithmetic type, a string, an optional, a dispatcher, an enum, a variant, a tuple-like, an array-like "
1178 "or associative container, or a reflectable aggregate"
Definition Reflection.h:33
Definition Serializer.h:9