DAW JSON Link
Loading...
Searching...
No Matches
daw_json_serialize_impl.h
Go to the documentation of this file.
1// Copyright (c) Darrell Wright
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5//
6// Official repository: https://github.com/beached/daw_json_link
7//
8#pragma once
9
10#include "version.h"
11
12#include "to_daw_json_string.h"
13
14#include <daw/daw_empty.h>
15#include <daw/daw_fwd_pack_apply.h>
16#include <daw/daw_string_view.h>
17#include <daw/daw_undefined.h>
18#include <daw/traits/daw_traits_nth_element.h>
19
20#include <cassert>
21#include <cstddef>
22#include <daw/stdinc/integer_sequence.h>
23
24namespace daw::json {
25 inline namespace DAW_JSON_VER {
26 namespace json_details {
27
28 template<typename T, std::size_t Capacity>
29 struct basic_array_t {
30 static constexpr std::size_t capacity = Capacity;
31
32 private:
33 std::size_t position{ };
34 daw::string_view array[capacity]{ };
35
36 public:
37 basic_array_t( ) = default;
38
39 DAW_ATTRIB_RET_NONNULL
40 constexpr T const *data( ) const {
41 return array;
42 }
43
44 DAW_ATTRIB_RET_NONNULL
45 constexpr T *data( ) {
46 return array;
47 }
48
49 constexpr std::size_t size( ) const {
50 return position;
51 }
52
53 constexpr void push_back( T const &v ) {
54 assert( position < capacity );
55 array[position] = v;
56 ++position;
57 }
58 };
59
60 template<typename T>
61 struct basic_array_t<T, 0> {
62 static constexpr std::size_t capacity = 0;
63
64 basic_array_t( ) = default;
65
66 DAW_CONSTEVAL T const *data( ) const {
67 return nullptr;
68 }
69
70 DAW_CONSTEVAL T *data( ) {
71 return nullptr;
72 }
73
74 DAW_CONSTEVAL std::size_t size( ) const {
75 return 0;
76 }
77 };
78
79 /***
80 * Serialize items to an output iterator as members of a class
81 * @tparam JsonMembers member items in json_class
82 * @tparam OutputIterator An Output Iterator that allows writing
83 * character data
84 * @tparam Is index_sequence index into JsonMembers
85 * @tparam Tuple tuple type holding class members
86 * @tparam Value mapped class type to serialize
87 * @param it an Output Iterator to write char data to
88 * @param args A tuple of the member values
89 * @param value class to serialize
90 * @return The OutputIterator it at theposition
91 */
92 template<typename... JsonMembers, typename OutputIterator,
93 json_options_t SerializationOptions, std::size_t... Is,
94 typename Tuple, typename Value>
95 [[nodiscard]] DAW_ATTRIB_INLINE static constexpr serialization_policy<
96 OutputIterator, SerializationOptions>
97 serialize_json_class(
99 Tuple const &args, Value const &value, std::index_sequence<Is...> ) {
100
101 it.put( '{' );
102 it.add_indent( );
103
104 constexpr auto visit_size =
105 sizeof...( JsonMembers ) +
106 ( static_cast<std::size_t>( has_dependent_member_v<JsonMembers> ) +
107 ... + 0 );
108 auto visited_members = basic_array_t<daw::string_view, visit_size>{ };
109
110 // Tag Members, if any. Putting them ahead means we can parse this
111 // faster in the future
112
113 // Using list init to ensure serialization happens in order
114 bool is_first = true;
115
116 // gcc complains when JsonMembers is empty
117 (void)visited_members;
118 (void)is_first;
119 {
120 using Names = daw::fwd_pack<JsonMembers...>;
121 daw::empty_t const expander[]{
122 ( dependent_member_to_json_str<
123 Is, daw::traits::nth_element<Is, JsonMembers...>, Names>(
124 is_first, it, args, value, visited_members ),
125 daw::empty_t{ } )...,
126 daw::empty_t{} };
127 (void)expander;
128 }
129
130 // Regular Members
131 {
132 daw::empty_t const expander[]{
133 ( to_json_str<Is, daw::traits::nth_element<Is, JsonMembers...>>(
134 is_first, it, args, value, visited_members ),
135 daw::empty_t{ } )...,
136 daw::empty_t{} };
137 (void)expander;
138 }
139 it.del_indent( );
140 if constexpr( sizeof...( Is ) > 0 ) {
141 if constexpr( it.output_trailing_comma ==
142 options::OutputTrailingComma::Yes ) {
143 it.put( ',' );
144 }
145 it.next_member( );
146 }
147 it.put( '}' );
148 return it;
149 }
150
151 template<typename... JsonMembers, typename OutputIterator,
152 json_options_t SerializerOptions, typename Tuple, typename Value,
153 std::size_t... Is>
154 [[nodiscard]] DAW_ATTRIB_INLINE static constexpr serialization_policy<
155 OutputIterator, SerializerOptions>
156 serialize_ordered_json_class(
158 Tuple const &args, Value const &value, std::index_sequence<Is...> ) {
159
160 it.put( '[' );
161 it.add_indent( );
162 it.next_member( );
163 std::size_t array_idx = 0;
164 (void)array_idx; // gcc was complaining on empty pack
165 Unused( value );
166 {
167 daw::empty_t const expander[]{
168 ( to_json_ordered_str<Is,
169 daw::traits::nth_element<Is, JsonMembers...>>(
170 array_idx, sizeof...( Is ), it, args ),
171 daw::empty_t{ } )...,
172 daw::empty_t{} };
173 (void)expander;
174 }
175 it.del_indent( );
176 if constexpr( sizeof...( Is ) != 0 ) {
177 if constexpr( it.output_trailing_comma ==
178 options::OutputTrailingComma::Yes ) {
179 it.put( ',' );
180 }
181 it.next_member( );
182 }
183 it.put( ']' );
184 return it;
185 }
186 } // namespace json_details
187 } // namespace DAW_JSON_VER
188} // namespace daw::json
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20