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
11
13
14#include <daw/daw_constant.h>
15#include <daw/daw_empty.h>
16#include <daw/daw_fwd_pack_apply.h>
17#include <daw/daw_string_view.h>
18#include <daw/daw_undefined.h>
19#include <daw/traits/daw_traits_nth_element.h>
20
21#include <cassert>
22#include <cstddef>
23#include <daw/stdinc/integer_sequence.h>
24
25namespace daw::json {
26 inline namespace DAW_JSON_VER {
27 namespace json_details {
28
29 template<typename T, std::size_t Capacity>
30 struct basic_array_t {
31 static constexpr std::size_t capacity = Capacity;
32
33 private:
34 std::size_t position{ };
35 daw::string_view array[capacity]{ };
36
37 public:
38 basic_array_t( ) = default;
39
40 DAW_ATTRIB_RET_NONNULL
41 constexpr T const *data( ) const {
42 return array;
43 }
44
45 DAW_ATTRIB_RET_NONNULL
46 constexpr T *data( ) {
47 return array;
48 }
49
50 constexpr std::size_t size( ) const {
51 return position;
52 }
53
54 constexpr void push_back( T const &v ) {
55 assert( position < capacity );
56 array[position] = v;
57 ++position;
58 }
59 };
60
61 template<typename T>
62 struct basic_array_t<T, 0> {
63 static constexpr std::size_t capacity = 0;
64
65 basic_array_t( ) = default;
66
67 static DAW_CONSTEVAL T const *data( ) {
68 return nullptr;
69 }
70
71 static DAW_CONSTEVAL std::size_t size( ) {
72 return 0;
73 }
74 };
75
76 /***
77 * Serialize items to an output iterator as members of a class
78 * @tparam JsonMembers member items in json_class
79 * @tparam OutputIterator An Output Iterator that allows writing
80 * character data
81 * @tparam Is index_sequence index into JsonMembers
82 * @tparam Tuple tuple type holding class members
83 * @tparam Value mapped class type to serialize
84 * @param it an Output Iterator to write char data to
85 * @param args A tuple of the member values
86 * @param value class to serialize
87 * @return The OutputIterator it at theposition
88 */
89 template<typename... JsonMembers, typename OutputIterator,
90 json_options_t SerializationOptions, std::size_t... Is,
91 typename Tuple, typename Value>
92 [[nodiscard]] DAW_ATTRIB_INLINE static constexpr serialization_policy<
93 OutputIterator, SerializationOptions>
94 serialize_json_class(
96 Tuple const &args, Value const &value, std::index_sequence<Is...> ) {
97
98 it.put( '{' );
99 it.add_indent( );
100
101 using visit_size =
102 daw::constant<sizeof...( JsonMembers ) +
103 ( static_cast<std::size_t>(
104 has_dependent_member_v<JsonMembers> ) +
105 ... + 0 )>;
106 // The names written so far are only needed to skip a name that was
107 // already written, which can only happen with dependent members or
108 // with two members of the same name
109 constexpr bool track_visited =
110 visit_size::value != sizeof...( JsonMembers ) or
111 has_repeated_member_names<JsonMembers...>( );
112 auto visited_members = daw::conditional_t<
113 track_visited,
114 basic_array_t<daw::string_view, visit_size::value>,
115 no_visited_members_t>{ };
116
117 // Tag Members, if any. Putting them ahead means we can parse this
118 // faster in the future
119
120 // Using list init to ensure serialization happens in order
121 bool is_first = true;
122
123 // gcc complains when JsonMembers is empty
124 (void)visited_members;
125 (void)is_first;
126 {
127 using Names = daw::fwd_pack<JsonMembers...>;
128 daw::empty_t const expander[]{
129 ( dependent_member_to_json_str<
130 Is,
131 daw::traits::nth_element<Is, JsonMembers...>,
132 Names>( is_first, it, args, value, visited_members ),
133 daw::empty_t{ } )...,
134 daw::empty_t{ } };
135 (void)expander;
136 }
137
138 // Regular Members
139 {
140 daw::empty_t const expander[]{
141 ( to_json_str<Is, daw::traits::nth_element<Is, JsonMembers...>>(
142 is_first, it, args, value, visited_members ),
143 daw::empty_t{ } )...,
144 daw::empty_t{ } };
145 (void)expander;
146 }
147 it.del_indent( );
148 if constexpr( sizeof...( Is ) > 0 ) {
149 if constexpr( it.output_trailing_comma ==
150 options::OutputTrailingComma::Yes ) {
151 it.put( ',' );
152 }
153 it.next_member( );
154 }
155 it.put( '}' );
156 return it;
157 }
158
159 template<typename... JsonMembers, typename OutputIterator,
160 json_options_t SerializerOptions, typename Tuple, typename Value,
161 std::size_t... Is>
162 [[nodiscard]] DAW_ATTRIB_INLINE static constexpr serialization_policy<
163 OutputIterator, SerializerOptions>
164 serialize_ordered_json_class(
166 Tuple const &args, Value const &value, std::index_sequence<Is...> ) {
167
168 it.put( '[' );
169 it.add_indent( );
170 it.next_member( );
171 std::size_t array_idx = 0;
172 (void)array_idx; // gcc was complaining on empty pack
173 Unused( value );
174 {
175 daw::empty_t const expander[]{
176 ( to_json_ordered_str<Is,
177 daw::traits::nth_element<Is, JsonMembers...>>(
178 array_idx, sizeof...( Is ), it, args ),
179 daw::empty_t{ } )...,
180 daw::empty_t{ } };
181 (void)expander;
182 }
183 it.del_indent( );
184 if constexpr( sizeof...( Is ) != 0 ) {
185 if constexpr( it.output_trailing_comma ==
186 options::OutputTrailingComma::Yes ) {
187 it.put( ',' );
188 }
189 it.next_member( );
190 }
191 it.put( ']' );
192 return it;
193 }
194 } // namespace json_details
195 } // namespace DAW_JSON_VER
196} // namespace daw::json
string_writer grows its string with resize_and_overwrite, leaving the new bytes uninitialized,...
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20