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 DAW_CONSTEVAL T const *data( ) const {
68 return nullptr;
69 }
70
71 DAW_CONSTEVAL T *data( ) {
72 return nullptr;
73 }
74
75 DAW_CONSTEVAL std::size_t size( ) const {
76 return 0;
77 }
78 };
79
80 /***
81 * Serialize items to an output iterator as members of a class
82 * @tparam JsonMembers member items in json_class
83 * @tparam OutputIterator An Output Iterator that allows writing
84 * character data
85 * @tparam Is index_sequence index into JsonMembers
86 * @tparam Tuple tuple type holding class members
87 * @tparam Value mapped class type to serialize
88 * @param it an Output Iterator to write char data to
89 * @param args A tuple of the member values
90 * @param value class to serialize
91 * @return The OutputIterator it at theposition
92 */
93 template<typename... JsonMembers, typename OutputIterator,
94 json_options_t SerializationOptions, std::size_t... Is,
95 typename Tuple, typename Value>
96 [[nodiscard]] DAW_ATTRIB_INLINE static constexpr serialization_policy<
97 OutputIterator, SerializationOptions>
98 serialize_json_class(
100 Tuple const &args, Value const &value, std::index_sequence<Is...> ) {
101
102 it.put( '{' );
103 it.add_indent( );
104
105 using visit_size =
106 daw::constant<sizeof...( JsonMembers ) +
107 ( static_cast<std::size_t>(
108 has_dependent_member_v<JsonMembers> ) +
109 ... + 0 )>;
110 auto visited_members =
111 basic_array_t<daw::string_view, visit_size::value>{ };
112
113 // Tag Members, if any. Putting them ahead means we can parse this
114 // faster in the future
115
116 // Using list init to ensure serialization happens in order
117 bool is_first = true;
118
119 // gcc complains when JsonMembers is empty
120 (void)visited_members;
121 (void)is_first;
122 {
123 using Names = daw::fwd_pack<JsonMembers...>;
124 daw::empty_t const expander[]{
125 ( dependent_member_to_json_str<
126 Is,
127 daw::traits::nth_element<Is, JsonMembers...>,
128 Names>( is_first, it, args, value, visited_members ),
129 daw::empty_t{ } )...,
130 daw::empty_t{ } };
131 (void)expander;
132 }
133
134 // Regular Members
135 {
136 daw::empty_t const expander[]{
137 ( to_json_str<Is, daw::traits::nth_element<Is, JsonMembers...>>(
138 is_first, it, args, value, visited_members ),
139 daw::empty_t{ } )...,
140 daw::empty_t{ } };
141 (void)expander;
142 }
143 it.del_indent( );
144 if constexpr( sizeof...( Is ) > 0 ) {
145 if constexpr( it.output_trailing_comma ==
146 options::OutputTrailingComma::Yes ) {
147 it.put( ',' );
148 }
149 it.next_member( );
150 }
151 it.put( '}' );
152 return it;
153 }
154
155 template<typename... JsonMembers, typename OutputIterator,
156 json_options_t SerializerOptions, typename Tuple, typename Value,
157 std::size_t... Is>
158 [[nodiscard]] DAW_ATTRIB_INLINE static constexpr serialization_policy<
159 OutputIterator, SerializerOptions>
160 serialize_ordered_json_class(
162 Tuple const &args, Value const &value, std::index_sequence<Is...> ) {
163
164 it.put( '[' );
165 it.add_indent( );
166 it.next_member( );
167 std::size_t array_idx = 0;
168 (void)array_idx; // gcc was complaining on empty pack
169 Unused( value );
170 {
171 daw::empty_t const expander[]{
172 ( to_json_ordered_str<Is,
173 daw::traits::nth_element<Is, JsonMembers...>>(
174 array_idx, sizeof...( Is ), it, args ),
175 daw::empty_t{ } )...,
176 daw::empty_t{ } };
177 (void)expander;
178 }
179 it.del_indent( );
180 if constexpr( sizeof...( Is ) != 0 ) {
181 if constexpr( it.output_trailing_comma ==
182 options::OutputTrailingComma::Yes ) {
183 it.put( ',' );
184 }
185 it.next_member( );
186 }
187 it.put( ']' );
188 return it;
189 }
190 } // namespace json_details
191 } // namespace DAW_JSON_VER
192} // 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