44 return encode_value(value);
54 status = owner_.encode_value(value);
68 std::size_t count_ = 0;
74 auto status = owner_.encode_value(value);
88 std::size_t count_ = 0;
94 "container size exceeds configured limit");
96 depth_guard
depth(*
this);
99 "maximum serialization depth exceeded");
113 "custom object field count does not match declared size");
121 "container size exceeds configured limit");
123 depth_guard
depth(*
this);
126 "maximum serialization depth exceeded");
140 "custom array element count does not match declared size");
146 return writer_.write_null();
150 return writer_.write_bool(
v);
154 return writer_.write_signed(
v);
158 return writer_.write_unsigned(
v);
162 return writer_.write_floating(
v);
166 return writer_.write_string(
v);
170 return writer_.begin_array(
n);
174 return writer_.end_array();
178 return writer_.begin_object(
n);
182 return writer_.write_key(
v);
186 return writer_.end_object();
209 basic_serializer &s_;
213 class structure_guard {
215 structure_guard(basic_serializer &
owner,
bool object) : owner_(
owner), object_(
object) {}
220 (
void)owner_.end_object();
222 (
void)owner_.end_array();
227 serialization_result<void> finish() {
229 return object_ ? owner_.end_object() : owner_.end_array();
233 basic_serializer &owner_;
238 template <
typename T> serialization_result<void> encode_value(
const T &value) {
239 using U = detail::unqualified_t<T>;
242 serialization_traits<U>::serialize(
a,
v)
243 } -> std::same_as<serialization_result<void>>;
245 return serialization_traits<U>::serialize(*
this, value);
246 }
else if constexpr (std::same_as<U, std::nullptr_t>) {
248 }
else if constexpr (std::same_as<U, bool>) {
250 }
else if constexpr (std::is_integral_v<U> && std::is_signed_v<U>) {
252 }
else if constexpr (std::is_integral_v<U> && std::is_unsigned_v<U>) {
254 }
else if constexpr (std::is_floating_point_v<U>) {
255 if (!std::isfinite(
static_cast<double>(value))) {
257 "non-finite floating point value");
260 }
else if constexpr (std::same_as<U, std::string>) {
262 }
else if constexpr (std::same_as<U, std::string_view>) {
264 }
else if constexpr (detail::is_char_array_v<T>) {
265 constexpr auto extent = std::extent_v<std::remove_reference_t<T>>;
268 }
else if constexpr (std::same_as<U, const char *> || std::same_as<U, char *>) {
269 if (value ==
nullptr) {
273 }
else if constexpr (std::is_enum_v<U>) {
280 "enum value is not reflected");
283 }
else if constexpr (detail::is_optional_v<U>) {
284 return value ? encode_value(*value) :
write_null();
285 }
else if constexpr (detail::is_sequence_v<U> || detail::is_set_v<U>) {
288 "container size exceeds configured limit");
290 depth_guard
guard(*
this);
293 "maximum serialization depth exceeded");
300 for (
const auto &
e : value) {
301 serialization_result<void>
q;
302 if constexpr (detail::is_sequence_v<U>) {
303 using element_type =
typename detail::sequence_traits<U>::value_type;
304 if constexpr (std::same_as<element_type, bool>) {
305 q = encode_value(
static_cast<bool>(
e));
318 }
else if constexpr (detail::is_array_v<U> || detail::is_pair_v<U> ||
319 detail::is_tuple_like_v<U>) {
320 constexpr auto N = std::tuple_size_v<U>;
323 "container size exceeds configured limit");
325 depth_guard
guard(*
this);
328 "maximum serialization depth exceeded");
334 auto each = [&]<std::size_t...
I>(std::index_sequence<
I...>) {
335 serialization_result<void>
status;
340 status = encode_value(std::get<J>(value));
348 r =
each(std::make_index_sequence<N>{});
353 }
else if constexpr (detail::is_map_v<U>) {
356 "container size exceeds configured limit");
358 depth_guard
guard(*
this);
361 "maximum serialization depth exceeded");
363 using K =
typename detail::map_traits<U>::key_type;
364 if constexpr (detail::is_string_key_v<K>) {
369 for (
const auto &[
k,
v] : value) {
373 if (!(
r = encode_value(
v))) {
383 std::size_t index = 0;
384 for (
const auto &[
k,
v] : value) {
388 "maximum serialization depth exceeded",
389 std::to_string(index));
395 if (!(
q = encode_value(
k))) {
398 if (!(
q = encode_value(
v))) {
408 }
else if constexpr (detail::is_variant_v<U>) {
409 if (value.valueless_by_exception()) {
411 "valueless variant cannot be serialized");
415 "container size exceeds configured limit");
417 depth_guard
guard(*
this);
420 "maximum serialization depth exceeded");
435 r = std::visit([&](
const auto &
x) {
return encode_value(
x); }, value);
441 static_assert(detail::valid_schema<U>(),
442 "serialization_schema contains an unknown/duplicate member "
443 "or an overlapping wire/alias name");
448 "container size exceeds configured limit");
450 depth_guard
guard(*
this);
453 "maximum serialization depth exceeded");
459 auto each = [&]<std::size_t...
I>(std::index_sequence<
I...>) {
460 serialization_result<void>
status;
461 auto one = [&](
auto ic) {
462 constexpr std::size_t
J =
decltype(
ic)::value;
463 using descriptor = detail::field_descriptor_t<U, J>;
464 if constexpr (!descriptor::is_transient) {
465 constexpr auto name = detail::descriptor_wire<descriptor>();
477 (
one(std::integral_constant<std::size_t, I>{}), ...);
480 r =
each(std::make_index_sequence<N>{});
486 static_assert(detail::always_false_v<U>,
487 "type is not serializable; specialize serialization_traits<T>");
492 serialization_options options_;
493 std::size_t depth_ = 0;