/src/boost/boost/json/impl/serializer.hpp
Line | Count | Source |
1 | | // |
2 | | // Copyright (c) 2024 Dmitry Arkhipov (grisumbras@yandex.ru) |
3 | | // |
4 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | | // |
7 | | // Official repository: https://github.com/boostorg/json |
8 | | // |
9 | | |
10 | | #ifndef BOOST_JSON_IMPL_SERIALIZER_HPP |
11 | | #define BOOST_JSON_IMPL_SERIALIZER_HPP |
12 | | |
13 | | #include <boost/core/detail/static_assert.hpp> |
14 | | #include <boost/describe/enum_to_string.hpp> |
15 | | #include <boost/json/conversion.hpp> |
16 | | #include <cstddef> |
17 | | |
18 | | namespace boost { |
19 | | namespace json { |
20 | | namespace detail { |
21 | | |
22 | | enum class writer::state : char |
23 | | { |
24 | | str1, str2, str3, esc1, utf1, |
25 | | utf2, utf3, utf4, utf5, |
26 | | lit, |
27 | | arr1, arr2, arr3, arr4, |
28 | | obj1, obj2, obj3, obj4, obj5, obj6 |
29 | | }; |
30 | | |
31 | | bool |
32 | | writer:: |
33 | | suspend(state st) |
34 | 2.38k | { |
35 | 2.38k | st_.push(st); |
36 | 2.38k | return false; |
37 | 2.38k | } |
38 | | |
39 | | template<class U, class T> |
40 | | bool |
41 | | writer:: |
42 | | suspend(state st, U u, T const* pt) |
43 | 8.37k | { |
44 | 8.37k | st_.push(pt); |
45 | 8.37k | st_.push(u); |
46 | 8.37k | st_.push(st); |
47 | 8.37k | return false; |
48 | 8.37k | } bool boost::json::detail::writer::suspend<boost::json::value const*, boost::json::array>(boost::json::detail::writer::state, boost::json::value const*, boost::json::array const*) Line | Count | Source | 43 | 6.31k | { | 44 | 6.31k | st_.push(pt); | 45 | 6.31k | st_.push(u); | 46 | 6.31k | st_.push(st); | 47 | 6.31k | return false; | 48 | 6.31k | } |
bool boost::json::detail::writer::suspend<boost::json::key_value_pair const*, boost::json::object>(boost::json::detail::writer::state, boost::json::key_value_pair const*, boost::json::object const*) Line | Count | Source | 43 | 2.05k | { | 44 | 2.05k | st_.push(pt); | 45 | 2.05k | st_.push(u); | 46 | 2.05k | st_.push(st); | 47 | 2.05k | return false; | 48 | 2.05k | } |
|
49 | | |
50 | | template<class T, bool StackEmpty> |
51 | | bool |
52 | | write_impl(writer& w, stream& ss); |
53 | | |
54 | | template<class T, bool StackEmpty> |
55 | | BOOST_FORCEINLINE |
56 | | bool |
57 | | write_impl(null_like_conversion_tag, writer& w, stream& ss) |
58 | 0 | { |
59 | | #if defined(_MSC_VER) |
60 | | # pragma warning( push ) |
61 | | # pragma warning( disable : 4127 ) |
62 | | #endif |
63 | 0 | if( StackEmpty || w.st_.empty() ) |
64 | 0 | return write_null(w, ss); |
65 | | #if defined(_MSC_VER) |
66 | | # pragma warning( pop ) |
67 | | #endif |
68 | 0 | return resume_buffer(w, ss); |
69 | 0 | } Unexecuted instantiation: bool boost::json::detail::write_impl<decltype(nullptr), true>(boost::json::detail::null_like_conversion_tag, boost::json::detail::writer&, boost::json::detail::stream&) Unexecuted instantiation: bool boost::json::detail::write_impl<decltype(nullptr), false>(boost::json::detail::null_like_conversion_tag, boost::json::detail::writer&, boost::json::detail::stream&) |
70 | | |
71 | | template<class T, bool StackEmpty> |
72 | | BOOST_FORCEINLINE |
73 | | bool |
74 | | write_impl(bool_conversion_tag, writer& w, stream& ss) |
75 | | { |
76 | | BOOST_ASSERT( w.p_ ); |
77 | | auto const t = *reinterpret_cast<T const*>(w.p_); |
78 | | |
79 | | #if defined(_MSC_VER) |
80 | | # pragma warning( push ) |
81 | | # pragma warning( disable : 4127 ) |
82 | | #endif |
83 | | if( StackEmpty || w.st_.empty() ) |
84 | | #if defined(_MSC_VER) |
85 | | # pragma warning( pop ) |
86 | | #endif |
87 | | { |
88 | | if( t ) |
89 | | return write_true(w, ss); |
90 | | else |
91 | | return write_false(w, ss); |
92 | | } |
93 | | |
94 | | return resume_buffer(w, ss); |
95 | | } |
96 | | |
97 | | template<class T, bool StackEmpty> |
98 | | BOOST_FORCEINLINE |
99 | | bool |
100 | | write_impl(integral_conversion_tag, writer& w, stream& ss0) |
101 | | { |
102 | | #if defined(_MSC_VER) |
103 | | # pragma warning( push ) |
104 | | # pragma warning( disable : 4127 ) |
105 | | #endif |
106 | | if( StackEmpty || w.st_.empty() ) |
107 | | #if defined(_MSC_VER) |
108 | | # pragma warning( pop ) |
109 | | #endif |
110 | | { |
111 | | auto const& t = *reinterpret_cast<T const*>(w.p_); |
112 | | |
113 | | #if defined(__clang__) |
114 | | # pragma clang diagnostic push |
115 | | # pragma clang diagnostic ignored "-Wsign-compare" |
116 | | #elif defined(__GNUC__) |
117 | | # pragma GCC diagnostic push |
118 | | # pragma GCC diagnostic ignored "-Wsign-compare" |
119 | | #elif defined(_MSC_VER) |
120 | | # pragma warning( push ) |
121 | | # pragma warning( disable : 4018 ) |
122 | | # pragma warning( disable : 4127 ) |
123 | | #endif |
124 | | |
125 | | if( t < 0 ) |
126 | | { |
127 | | // T is obviously signed, so this comparison is safe |
128 | | if( t >= (std::numeric_limits<std::int64_t>::min)() ) |
129 | | { |
130 | | std::int64_t i = t; |
131 | | return write_int64(w, ss0, i); |
132 | | } |
133 | | } |
134 | | else if( t <= (std::numeric_limits<std::uint64_t>::max)() ) |
135 | | { |
136 | | std::uint64_t u = t; |
137 | | return write_uint64(w, ss0, u); |
138 | | } |
139 | | #if defined(__clang__) |
140 | | # pragma clang diagnostic pop |
141 | | #elif defined(__GNUC__) |
142 | | # pragma GCC diagnostic pop |
143 | | #elif defined(_MSC_VER) |
144 | | # pragma warning( pop ) |
145 | | #endif |
146 | | |
147 | | #if defined(_MSC_VER) |
148 | | # pragma warning( push ) |
149 | | # pragma warning( disable : 4244 ) |
150 | | #endif |
151 | | double d = t; |
152 | | return write_double(w, ss0, d); |
153 | | #if defined(_MSC_VER) |
154 | | # pragma warning( pop ) |
155 | | #endif |
156 | | } |
157 | | |
158 | | return resume_buffer(w, ss0); |
159 | | } |
160 | | |
161 | | template<class T, bool StackEmpty> |
162 | | BOOST_FORCEINLINE |
163 | | bool |
164 | | write_impl(floating_point_conversion_tag, writer& w, stream& ss0) |
165 | | { |
166 | | #if defined(_MSC_VER) |
167 | | # pragma warning( push ) |
168 | | # pragma warning( disable : 4127 ) |
169 | | #endif |
170 | | if( StackEmpty || w.st_.empty() ) |
171 | | #if defined(_MSC_VER) |
172 | | # pragma warning( pop ) |
173 | | #endif |
174 | | { |
175 | | double d = *reinterpret_cast<T const*>(w.p_); |
176 | | return write_double(w, ss0, d); |
177 | | } |
178 | | |
179 | | return resume_buffer(w, ss0); |
180 | | } |
181 | | |
182 | | template<class T, bool StackEmpty> |
183 | | BOOST_FORCEINLINE |
184 | | bool |
185 | | write_impl(string_like_conversion_tag, writer& w, stream& ss0) |
186 | | { |
187 | | #if defined(_MSC_VER) |
188 | | # pragma warning( push ) |
189 | | # pragma warning( disable : 4127 ) |
190 | | #endif |
191 | | if( StackEmpty || w.st_.empty() ) |
192 | | #if defined(_MSC_VER) |
193 | | # pragma warning( pop ) |
194 | | #endif |
195 | | { |
196 | | string_view const sv = *reinterpret_cast<T const*>(w.p_); |
197 | | w.cs0_ = { sv.data(), sv.size() }; |
198 | | return write_string(w, ss0); |
199 | | } |
200 | | |
201 | | return resume_string(w, ss0); |
202 | | } |
203 | | |
204 | | template<class T, bool StackEmpty> |
205 | | BOOST_FORCEINLINE |
206 | | bool |
207 | | write_impl(sequence_conversion_tag, writer& w, stream& ss0) |
208 | 23.2k | { |
209 | 23.2k | using It = iterator_type<T const>; |
210 | 23.2k | using Elem = value_type<T>; |
211 | | |
212 | 23.2k | T const* pt; |
213 | 23.2k | local_stream ss(ss0); |
214 | 23.2k | It it; |
215 | 23.2k | It end; |
216 | | #if defined(_MSC_VER) |
217 | | # pragma warning( push ) |
218 | | # pragma warning( disable : 4127 ) |
219 | | #endif |
220 | 23.2k | if(StackEmpty || w.st_.empty()) |
221 | 16.8k | { |
222 | | #if defined(_MSC_VER) |
223 | | # pragma warning( pop ) |
224 | | #endif |
225 | 16.8k | BOOST_ASSERT( w.p_ ); |
226 | 16.8k | pt = reinterpret_cast<T const*>(w.p_); |
227 | 16.8k | it = std::begin(*pt); |
228 | 16.8k | end = std::end(*pt); |
229 | 16.8k | } |
230 | 6.31k | else |
231 | 6.31k | { |
232 | 6.31k | writer::state st; |
233 | 6.31k | w.st_.pop(st); |
234 | 6.31k | w.st_.pop(it); |
235 | 6.31k | w.st_.pop(pt); |
236 | 6.31k | end = std::end(*pt); |
237 | 6.31k | switch(st) |
238 | 6.31k | { |
239 | 0 | default: |
240 | 19 | case writer::state::arr1: goto do_arr1; |
241 | 6.05k | case writer::state::arr2: goto do_arr2; |
242 | 201 | case writer::state::arr3: goto do_arr3; |
243 | 40 | case writer::state::arr4: goto do_arr4; |
244 | 0 | break; |
245 | 6.31k | } |
246 | 6.31k | } |
247 | 16.9k | do_arr1: |
248 | 16.9k | if(BOOST_JSON_LIKELY(ss)) |
249 | 16.8k | ss.append('['); |
250 | 19 | else |
251 | 19 | return w.suspend(writer::state::arr1, it, pt); |
252 | 16.8k | if(it == end) |
253 | 2.67k | goto do_arr4; |
254 | 14.2k | for(;;) |
255 | 9.53M | { |
256 | 9.53M | w.p_ = std::addressof(*it); |
257 | 9.53M | do_arr2: |
258 | 9.53M | if( !write_impl<Elem, StackEmpty>(w, ss) ) |
259 | 6.05k | return w.suspend(writer::state::arr2, it, pt); |
260 | 9.53M | if(BOOST_JSON_UNLIKELY( ++it == end )) |
261 | 14.2k | break; |
262 | 9.51M | do_arr3: |
263 | 9.51M | if(BOOST_JSON_LIKELY(ss)) |
264 | 9.51M | ss.append(','); |
265 | 201 | else |
266 | 201 | return w.suspend(writer::state::arr3, it, pt); |
267 | 9.51M | } |
268 | 16.9k | do_arr4: |
269 | 16.9k | if(BOOST_JSON_LIKELY(ss)) |
270 | 16.8k | ss.append(']'); |
271 | 40 | else |
272 | 40 | return w.suspend(writer::state::arr4, it, pt); |
273 | 16.8k | return true; |
274 | 16.9k | } bool boost::json::detail::write_impl<boost::json::array, true>(boost::json::detail::sequence_conversion_tag, boost::json::detail::writer&, boost::json::detail::stream&) Line | Count | Source | 208 | 16.8k | { | 209 | 16.8k | using It = iterator_type<T const>; | 210 | 16.8k | using Elem = value_type<T>; | 211 | | | 212 | 16.8k | T const* pt; | 213 | 16.8k | local_stream ss(ss0); | 214 | 16.8k | It it; | 215 | 16.8k | It end; | 216 | | #if defined(_MSC_VER) | 217 | | # pragma warning( push ) | 218 | | # pragma warning( disable : 4127 ) | 219 | | #endif | 220 | 16.8k | if(StackEmpty || w.st_.empty()) | 221 | 16.8k | { | 222 | | #if defined(_MSC_VER) | 223 | | # pragma warning( pop ) | 224 | | #endif | 225 | 16.8k | BOOST_ASSERT( w.p_ ); | 226 | 16.8k | pt = reinterpret_cast<T const*>(w.p_); | 227 | 16.8k | it = std::begin(*pt); | 228 | 16.8k | end = std::end(*pt); | 229 | 16.8k | } | 230 | 0 | else | 231 | 0 | { | 232 | 0 | writer::state st; | 233 | 0 | w.st_.pop(st); | 234 | 0 | w.st_.pop(it); | 235 | 0 | w.st_.pop(pt); | 236 | 0 | end = std::end(*pt); | 237 | 0 | switch(st) | 238 | 0 | { | 239 | 0 | default: | 240 | 0 | case writer::state::arr1: goto do_arr1; | 241 | 0 | case writer::state::arr2: goto do_arr2; | 242 | 0 | case writer::state::arr3: goto do_arr3; | 243 | 0 | case writer::state::arr4: goto do_arr4; | 244 | 0 | break; | 245 | 0 | } | 246 | 0 | } | 247 | 16.8k | do_arr1: | 248 | 16.8k | if(BOOST_JSON_LIKELY(ss)) | 249 | 16.8k | ss.append('['); | 250 | 19 | else | 251 | 19 | return w.suspend(writer::state::arr1, it, pt); | 252 | 16.8k | if(it == end) | 253 | 2.66k | goto do_arr4; | 254 | 14.2k | for(;;) | 255 | 1.66M | { | 256 | 1.66M | w.p_ = std::addressof(*it); | 257 | 1.66M | do_arr2: | 258 | 1.66M | if( !write_impl<Elem, StackEmpty>(w, ss) ) | 259 | 2.53k | return w.suspend(writer::state::arr2, it, pt); | 260 | 1.66M | if(BOOST_JSON_UNLIKELY( ++it == end )) | 261 | 11.5k | break; | 262 | 1.64M | do_arr3: | 263 | 1.64M | if(BOOST_JSON_LIKELY(ss)) | 264 | 1.64M | ss.append(','); | 265 | 103 | else | 266 | 103 | return w.suspend(writer::state::arr3, it, pt); | 267 | 1.64M | } | 268 | 14.2k | do_arr4: | 269 | 14.2k | if(BOOST_JSON_LIKELY(ss)) | 270 | 14.1k | ss.append(']'); | 271 | 29 | else | 272 | 29 | return w.suspend(writer::state::arr4, it, pt); | 273 | 14.1k | return true; | 274 | 14.2k | } |
bool boost::json::detail::write_impl<boost::json::array, false>(boost::json::detail::sequence_conversion_tag, boost::json::detail::writer&, boost::json::detail::stream&) Line | Count | Source | 208 | 6.31k | { | 209 | 6.31k | using It = iterator_type<T const>; | 210 | 6.31k | using Elem = value_type<T>; | 211 | | | 212 | 6.31k | T const* pt; | 213 | 6.31k | local_stream ss(ss0); | 214 | 6.31k | It it; | 215 | 6.31k | It end; | 216 | | #if defined(_MSC_VER) | 217 | | # pragma warning( push ) | 218 | | # pragma warning( disable : 4127 ) | 219 | | #endif | 220 | 6.31k | if(StackEmpty || w.st_.empty()) | 221 | 0 | { | 222 | | #if defined(_MSC_VER) | 223 | | # pragma warning( pop ) | 224 | | #endif | 225 | 0 | BOOST_ASSERT( w.p_ ); | 226 | 0 | pt = reinterpret_cast<T const*>(w.p_); | 227 | 0 | it = std::begin(*pt); | 228 | 0 | end = std::end(*pt); | 229 | 0 | } | 230 | 6.31k | else | 231 | 6.31k | { | 232 | 6.31k | writer::state st; | 233 | 6.31k | w.st_.pop(st); | 234 | 6.31k | w.st_.pop(it); | 235 | 6.31k | w.st_.pop(pt); | 236 | 6.31k | end = std::end(*pt); | 237 | 6.31k | switch(st) | 238 | 6.31k | { | 239 | 0 | default: | 240 | 19 | case writer::state::arr1: goto do_arr1; | 241 | 6.05k | case writer::state::arr2: goto do_arr2; | 242 | 201 | case writer::state::arr3: goto do_arr3; | 243 | 40 | case writer::state::arr4: goto do_arr4; | 244 | 0 | break; | 245 | 6.31k | } | 246 | 6.31k | } | 247 | 19 | do_arr1: | 248 | 19 | if(BOOST_JSON_LIKELY(ss)) | 249 | 19 | ss.append('['); | 250 | 0 | else | 251 | 0 | return w.suspend(writer::state::arr1, it, pt); | 252 | 19 | if(it == end) | 253 | 10 | goto do_arr4; | 254 | 9 | for(;;) | 255 | 7.86M | { | 256 | 7.86M | w.p_ = std::addressof(*it); | 257 | 7.87M | do_arr2: | 258 | 7.87M | if( !write_impl<Elem, StackEmpty>(w, ss) ) | 259 | 3.51k | return w.suspend(writer::state::arr2, it, pt); | 260 | 7.87M | if(BOOST_JSON_UNLIKELY( ++it == end )) | 261 | 2.64k | break; | 262 | 7.86M | do_arr3: | 263 | 7.86M | if(BOOST_JSON_LIKELY(ss)) | 264 | 7.86M | ss.append(','); | 265 | 98 | else | 266 | 98 | return w.suspend(writer::state::arr3, it, pt); | 267 | 7.86M | } | 268 | 2.69k | do_arr4: | 269 | 2.69k | if(BOOST_JSON_LIKELY(ss)) | 270 | 2.68k | ss.append(']'); | 271 | 11 | else | 272 | 11 | return w.suspend(writer::state::arr4, it, pt); | 273 | 2.68k | return true; | 274 | 2.69k | } |
|
275 | | |
276 | | template<class T, bool StackEmpty> |
277 | | BOOST_FORCEINLINE |
278 | | bool |
279 | | write_impl(map_like_conversion_tag, writer& w, stream& ss0) |
280 | 12.1k | { |
281 | 12.1k | using It = iterator_type<T const>; |
282 | 12.1k | using Mapped = mapped_type<T>; |
283 | | |
284 | 12.1k | T const* pt; |
285 | 12.1k | local_stream ss(ss0); |
286 | 12.1k | It it; |
287 | 12.1k | It end; |
288 | | #if defined(_MSC_VER) |
289 | | # pragma warning( push ) |
290 | | # pragma warning( disable : 4127 ) |
291 | | #endif |
292 | 12.1k | if(StackEmpty || w.st_.empty()) |
293 | | #if defined(_MSC_VER) |
294 | | # pragma warning( pop ) |
295 | | #endif |
296 | 10.0k | { |
297 | 10.0k | BOOST_ASSERT( w.p_ ); |
298 | 10.0k | pt = reinterpret_cast<T const*>(w.p_); |
299 | 10.0k | it = std::begin(*pt); |
300 | 10.0k | end = std::end(*pt); |
301 | 10.0k | } |
302 | 2.05k | else |
303 | 2.05k | { |
304 | 2.05k | writer::state st; |
305 | 2.05k | w.st_.pop(st); |
306 | 2.05k | w.st_.pop(it); |
307 | 2.05k | w.st_.pop(pt); |
308 | 2.05k | end = std::end(*pt); |
309 | 2.05k | switch(st) |
310 | 2.05k | { |
311 | 0 | default: |
312 | 22 | case writer::state::obj1: goto do_obj1; |
313 | 377 | case writer::state::obj2: goto do_obj2; |
314 | 22 | case writer::state::obj3: goto do_obj3; |
315 | 1.58k | case writer::state::obj4: goto do_obj4; |
316 | 24 | case writer::state::obj5: goto do_obj5; |
317 | 28 | case writer::state::obj6: goto do_obj6; |
318 | 0 | break; |
319 | 2.05k | } |
320 | 2.05k | } |
321 | 10.1k | do_obj1: |
322 | 10.1k | if(BOOST_JSON_LIKELY( ss )) |
323 | 10.0k | ss.append('{'); |
324 | 22 | else |
325 | 22 | return w.suspend(writer::state::obj1, it, pt); |
326 | 10.0k | if(BOOST_JSON_UNLIKELY( it == end )) |
327 | 5.64k | goto do_obj6; |
328 | 4.43k | for(;;) |
329 | 14.7k | { |
330 | 14.7k | { |
331 | 14.7k | using std::get; |
332 | 14.7k | string_view const sv = get<0>(*it); |
333 | 14.7k | w.cs0_ = { sv.data(), sv.size() }; |
334 | 14.7k | } |
335 | 14.7k | if( true ) |
336 | 14.7k | { |
337 | 14.7k | if(BOOST_JSON_UNLIKELY( !write_string(w, ss) )) |
338 | 220 | return w.suspend(writer::state::obj2, it, pt); |
339 | 14.7k | } |
340 | 0 | else |
341 | 0 | { |
342 | 377 | do_obj2: |
343 | 377 | if(BOOST_JSON_UNLIKELY( !resume_string(w, ss) )) |
344 | 157 | return w.suspend(writer::state::obj2, it, pt); |
345 | 377 | } |
346 | 14.7k | do_obj3: |
347 | 14.7k | if(BOOST_JSON_LIKELY(ss)) |
348 | 14.7k | ss.append(':'); |
349 | 22 | else |
350 | 22 | return w.suspend(writer::state::obj3, it, pt); |
351 | 16.3k | do_obj4: |
352 | 16.3k | { |
353 | 16.3k | using std::get; |
354 | 16.3k | w.p_ = std::addressof( get<1>(*it) ); |
355 | 16.3k | } |
356 | 16.3k | if(BOOST_JSON_UNLIKELY(( !write_impl<Mapped, StackEmpty>(w, ss) ))) |
357 | 1.58k | return w.suspend(writer::state::obj4, it, pt); |
358 | 14.7k | ++it; |
359 | 14.7k | if(BOOST_JSON_UNLIKELY(it == end)) |
360 | 4.43k | break; |
361 | 10.3k | do_obj5: |
362 | 10.3k | if(BOOST_JSON_LIKELY(ss)) |
363 | 10.3k | ss.append(','); |
364 | 24 | else |
365 | 24 | return w.suspend(writer::state::obj5, it, pt); |
366 | 10.3k | } |
367 | 10.1k | do_obj6: |
368 | 10.1k | if(BOOST_JSON_LIKELY( ss )) |
369 | 10.0k | { |
370 | 10.0k | ss.append('}'); |
371 | 10.0k | return true; |
372 | 10.0k | } |
373 | 28 | return w.suspend(writer::state::obj6, it, pt); |
374 | 10.1k | } bool boost::json::detail::write_impl<boost::json::object, true>(boost::json::detail::map_like_conversion_tag, boost::json::detail::writer&, boost::json::detail::stream&) Line | Count | Source | 280 | 10.0k | { | 281 | 10.0k | using It = iterator_type<T const>; | 282 | 10.0k | using Mapped = mapped_type<T>; | 283 | | | 284 | 10.0k | T const* pt; | 285 | 10.0k | local_stream ss(ss0); | 286 | 10.0k | It it; | 287 | 10.0k | It end; | 288 | | #if defined(_MSC_VER) | 289 | | # pragma warning( push ) | 290 | | # pragma warning( disable : 4127 ) | 291 | | #endif | 292 | 10.0k | if(StackEmpty || w.st_.empty()) | 293 | | #if defined(_MSC_VER) | 294 | | # pragma warning( pop ) | 295 | | #endif | 296 | 10.0k | { | 297 | 10.0k | BOOST_ASSERT( w.p_ ); | 298 | 10.0k | pt = reinterpret_cast<T const*>(w.p_); | 299 | 10.0k | it = std::begin(*pt); | 300 | 10.0k | end = std::end(*pt); | 301 | 10.0k | } | 302 | 0 | else | 303 | 0 | { | 304 | 0 | writer::state st; | 305 | 0 | w.st_.pop(st); | 306 | 0 | w.st_.pop(it); | 307 | 0 | w.st_.pop(pt); | 308 | 0 | end = std::end(*pt); | 309 | 0 | switch(st) | 310 | 0 | { | 311 | 0 | default: | 312 | 0 | case writer::state::obj1: goto do_obj1; | 313 | 0 | case writer::state::obj2: goto do_obj2; | 314 | 0 | case writer::state::obj3: goto do_obj3; | 315 | 0 | case writer::state::obj4: goto do_obj4; | 316 | 0 | case writer::state::obj5: goto do_obj5; | 317 | 0 | case writer::state::obj6: goto do_obj6; | 318 | 0 | break; | 319 | 0 | } | 320 | 0 | } | 321 | 10.0k | do_obj1: | 322 | 10.0k | if(BOOST_JSON_LIKELY( ss )) | 323 | 10.0k | ss.append('{'); | 324 | 22 | else | 325 | 22 | return w.suspend(writer::state::obj1, it, pt); | 326 | 10.0k | if(BOOST_JSON_UNLIKELY( it == end )) | 327 | 5.63k | goto do_obj6; | 328 | 4.42k | for(;;) | 329 | 12.5k | { | 330 | 12.5k | { | 331 | 12.5k | using std::get; | 332 | 12.5k | string_view const sv = get<0>(*it); | 333 | 12.5k | w.cs0_ = { sv.data(), sv.size() }; | 334 | 12.5k | } | 335 | 12.5k | if( true ) | 336 | 12.5k | { | 337 | 12.5k | if(BOOST_JSON_UNLIKELY( !write_string(w, ss) )) | 338 | 159 | return w.suspend(writer::state::obj2, it, pt); | 339 | 12.5k | } | 340 | 0 | else | 341 | 0 | { | 342 | 0 | do_obj2: | 343 | 0 | if(BOOST_JSON_UNLIKELY( !resume_string(w, ss) )) | 344 | 0 | return w.suspend(writer::state::obj2, it, pt); | 345 | 0 | } | 346 | 12.4k | do_obj3: | 347 | 12.4k | if(BOOST_JSON_LIKELY(ss)) | 348 | 12.4k | ss.append(':'); | 349 | 11 | else | 350 | 11 | return w.suspend(writer::state::obj3, it, pt); | 351 | 12.4k | do_obj4: | 352 | 12.4k | { | 353 | 12.4k | using std::get; | 354 | 12.4k | w.p_ = std::addressof( get<1>(*it) ); | 355 | 12.4k | } | 356 | 12.4k | if(BOOST_JSON_UNLIKELY(( !write_impl<Mapped, StackEmpty>(w, ss) ))) | 357 | 962 | return w.suspend(writer::state::obj4, it, pt); | 358 | 11.4k | ++it; | 359 | 11.4k | if(BOOST_JSON_UNLIKELY(it == end)) | 360 | 3.28k | break; | 361 | 8.17k | do_obj5: | 362 | 8.17k | if(BOOST_JSON_LIKELY(ss)) | 363 | 8.16k | ss.append(','); | 364 | 11 | else | 365 | 11 | return w.suspend(writer::state::obj5, it, pt); | 366 | 8.17k | } | 367 | 8.91k | do_obj6: | 368 | 8.91k | if(BOOST_JSON_LIKELY( ss )) | 369 | 8.89k | { | 370 | 8.89k | ss.append('}'); | 371 | 8.89k | return true; | 372 | 8.89k | } | 373 | 18 | return w.suspend(writer::state::obj6, it, pt); | 374 | 8.91k | } |
bool boost::json::detail::write_impl<boost::json::object, false>(boost::json::detail::map_like_conversion_tag, boost::json::detail::writer&, boost::json::detail::stream&) Line | Count | Source | 280 | 2.05k | { | 281 | 2.05k | using It = iterator_type<T const>; | 282 | 2.05k | using Mapped = mapped_type<T>; | 283 | | | 284 | 2.05k | T const* pt; | 285 | 2.05k | local_stream ss(ss0); | 286 | 2.05k | It it; | 287 | 2.05k | It end; | 288 | | #if defined(_MSC_VER) | 289 | | # pragma warning( push ) | 290 | | # pragma warning( disable : 4127 ) | 291 | | #endif | 292 | 2.05k | if(StackEmpty || w.st_.empty()) | 293 | | #if defined(_MSC_VER) | 294 | | # pragma warning( pop ) | 295 | | #endif | 296 | 0 | { | 297 | 0 | BOOST_ASSERT( w.p_ ); | 298 | 0 | pt = reinterpret_cast<T const*>(w.p_); | 299 | 0 | it = std::begin(*pt); | 300 | 0 | end = std::end(*pt); | 301 | 0 | } | 302 | 2.05k | else | 303 | 2.05k | { | 304 | 2.05k | writer::state st; | 305 | 2.05k | w.st_.pop(st); | 306 | 2.05k | w.st_.pop(it); | 307 | 2.05k | w.st_.pop(pt); | 308 | 2.05k | end = std::end(*pt); | 309 | 2.05k | switch(st) | 310 | 2.05k | { | 311 | 0 | default: | 312 | 22 | case writer::state::obj1: goto do_obj1; | 313 | 377 | case writer::state::obj2: goto do_obj2; | 314 | 22 | case writer::state::obj3: goto do_obj3; | 315 | 1.58k | case writer::state::obj4: goto do_obj4; | 316 | 24 | case writer::state::obj5: goto do_obj5; | 317 | 28 | case writer::state::obj6: goto do_obj6; | 318 | 0 | break; | 319 | 2.05k | } | 320 | 2.05k | } | 321 | 22 | do_obj1: | 322 | 22 | if(BOOST_JSON_LIKELY( ss )) | 323 | 22 | ss.append('{'); | 324 | 0 | else | 325 | 0 | return w.suspend(writer::state::obj1, it, pt); | 326 | 22 | if(BOOST_JSON_UNLIKELY( it == end )) | 327 | 12 | goto do_obj6; | 328 | 10 | for(;;) | 329 | 2.17k | { | 330 | 2.17k | { | 331 | 2.17k | using std::get; | 332 | 2.17k | string_view const sv = get<0>(*it); | 333 | 2.17k | w.cs0_ = { sv.data(), sv.size() }; | 334 | 2.17k | } | 335 | 2.17k | if( true ) | 336 | 2.17k | { | 337 | 2.17k | if(BOOST_JSON_UNLIKELY( !write_string(w, ss) )) | 338 | 61 | return w.suspend(writer::state::obj2, it, pt); | 339 | 2.17k | } | 340 | 0 | else | 341 | 0 | { | 342 | 377 | do_obj2: | 343 | 377 | if(BOOST_JSON_UNLIKELY( !resume_string(w, ss) )) | 344 | 157 | return w.suspend(writer::state::obj2, it, pt); | 345 | 377 | } | 346 | 2.35k | do_obj3: | 347 | 2.35k | if(BOOST_JSON_LIKELY(ss)) | 348 | 2.34k | ss.append(':'); | 349 | 11 | else | 350 | 11 | return w.suspend(writer::state::obj3, it, pt); | 351 | 3.92k | do_obj4: | 352 | 3.92k | { | 353 | 3.92k | using std::get; | 354 | 3.92k | w.p_ = std::addressof( get<1>(*it) ); | 355 | 3.92k | } | 356 | 3.92k | if(BOOST_JSON_UNLIKELY(( !write_impl<Mapped, StackEmpty>(w, ss) ))) | 357 | 621 | return w.suspend(writer::state::obj4, it, pt); | 358 | 3.30k | ++it; | 359 | 3.30k | if(BOOST_JSON_UNLIKELY(it == end)) | 360 | 1.15k | break; | 361 | 2.17k | do_obj5: | 362 | 2.17k | if(BOOST_JSON_LIKELY(ss)) | 363 | 2.16k | ss.append(','); | 364 | 13 | else | 365 | 13 | return w.suspend(writer::state::obj5, it, pt); | 366 | 2.17k | } | 367 | 1.19k | do_obj6: | 368 | 1.19k | if(BOOST_JSON_LIKELY( ss )) | 369 | 1.18k | { | 370 | 1.18k | ss.append('}'); | 371 | 1.18k | return true; | 372 | 1.18k | } | 373 | 10 | return w.suspend(writer::state::obj6, it, pt); | 374 | 1.19k | } |
|
375 | | |
376 | | template< class T, bool StackEmpty > |
377 | | struct serialize_tuple_elem_helper |
378 | | { |
379 | | writer& w; |
380 | | stream& ss; |
381 | | T const* pt; |
382 | | |
383 | | template< std::size_t I > |
384 | | bool |
385 | | operator()( std::integral_constant<std::size_t, I> ) const |
386 | | { |
387 | | using std::get; |
388 | | w.p_ = std::addressof( get<I>(*pt) ); |
389 | | |
390 | | using Elem = tuple_element_t<I, T>; |
391 | | return write_impl<Elem, StackEmpty>(w, ss); |
392 | | } |
393 | | }; |
394 | | |
395 | | template<class T, bool StackEmpty> |
396 | | BOOST_FORCEINLINE |
397 | | bool |
398 | | write_impl(tuple_conversion_tag, writer& w, stream& ss0) |
399 | | { |
400 | | T const* pt; |
401 | | local_stream ss(ss0); |
402 | | std::size_t cur; |
403 | | constexpr std::size_t N = std::tuple_size<T>::value; |
404 | | #if defined(_MSC_VER) |
405 | | # pragma warning( push ) |
406 | | # pragma warning( disable : 4127 ) |
407 | | #endif |
408 | | if(StackEmpty || w.st_.empty()) |
409 | | { |
410 | | #if defined(_MSC_VER) |
411 | | # pragma warning( pop ) |
412 | | #endif |
413 | | BOOST_ASSERT( w.p_ ); |
414 | | pt = reinterpret_cast<T const*>(w.p_); |
415 | | cur = 0; |
416 | | } |
417 | | else |
418 | | { |
419 | | writer::state st; |
420 | | w.st_.pop(st); |
421 | | w.st_.pop(cur); |
422 | | w.st_.pop(pt); |
423 | | switch(st) |
424 | | { |
425 | | default: |
426 | | case writer::state::arr1: goto do_arr1; |
427 | | case writer::state::arr2: goto do_arr2; |
428 | | case writer::state::arr3: goto do_arr3; |
429 | | case writer::state::arr4: goto do_arr4; |
430 | | break; |
431 | | } |
432 | | } |
433 | | do_arr1: |
434 | | if(BOOST_JSON_LIKELY(ss)) |
435 | | ss.append('['); |
436 | | else |
437 | | return w.suspend(writer::state::arr1, cur, pt); |
438 | | for(;;) |
439 | | { |
440 | | do_arr2: |
441 | | { |
442 | | bool const stop = !mp11::mp_with_index<N>( |
443 | | cur, |
444 | | serialize_tuple_elem_helper<T, StackEmpty>{w, ss, pt}); |
445 | | if(BOOST_JSON_UNLIKELY( stop )) |
446 | | return w.suspend(writer::state::arr2, cur, pt); |
447 | | } |
448 | | if(BOOST_JSON_UNLIKELY( ++cur == N )) |
449 | | break; |
450 | | do_arr3: |
451 | | if(BOOST_JSON_LIKELY(ss)) |
452 | | ss.append(','); |
453 | | else |
454 | | return w.suspend(writer::state::arr3, cur, pt); |
455 | | } |
456 | | do_arr4: |
457 | | if(BOOST_JSON_LIKELY(ss)) |
458 | | ss.append(']'); |
459 | | else |
460 | | return w.suspend(writer::state::arr4, cur, pt); |
461 | | return true; |
462 | | } |
463 | | |
464 | | template< class T, bool StackEmpty > |
465 | | struct serialize_struct_elem_helper |
466 | | { |
467 | | static_assert( |
468 | | uniquely_named_members<T>::value, |
469 | | "The type has several described members with the same name."); |
470 | | |
471 | | writer& w; |
472 | | local_stream& ss; |
473 | | T const* pt; |
474 | | writer::state st; |
475 | | |
476 | | template< std::size_t I > |
477 | | writer::state |
478 | | operator()( std::integral_constant<std::size_t, I> ) const |
479 | | { |
480 | | using Ds = described_members<T>; |
481 | | using D = mp11::mp_at_c<Ds, I>; |
482 | | using M = described_member_t<T, D>; |
483 | | |
484 | | switch(st) |
485 | | { |
486 | | case writer::state::obj2: goto do_obj2; |
487 | | case writer::state::obj3: goto do_obj3; |
488 | | case writer::state::obj4: goto do_obj4; |
489 | | default: break; |
490 | | } |
491 | | |
492 | | { |
493 | | string_view const sv = D::name; |
494 | | w.cs0_ = { sv.data(), sv.size() }; |
495 | | } |
496 | | if( true ) |
497 | | { |
498 | | if(BOOST_JSON_UNLIKELY( !write_string(w, ss) )) |
499 | | return writer::state::obj2; |
500 | | } |
501 | | else |
502 | | { |
503 | | do_obj2: |
504 | | if(BOOST_JSON_UNLIKELY( !resume_string(w, ss) )) |
505 | | return writer::state::obj2; |
506 | | } |
507 | | do_obj3: |
508 | | if(BOOST_JSON_LIKELY(ss)) |
509 | | ss.append(':'); |
510 | | else |
511 | | return writer::state::obj3; |
512 | | do_obj4: |
513 | | w.p_ = std::addressof( pt->* D::pointer ); |
514 | | if(BOOST_JSON_UNLIKELY(( |
515 | | !write_impl<M, StackEmpty>(w, ss) ))) |
516 | | return writer::state::obj4; |
517 | | |
518 | | return writer::state{}; |
519 | | } |
520 | | }; |
521 | | |
522 | | template<class T, bool StackEmpty> |
523 | | BOOST_FORCEINLINE |
524 | | bool |
525 | | write_impl(described_class_conversion_tag, writer& w, stream& ss0) |
526 | | { |
527 | | using Ds = described_members<T>; |
528 | | |
529 | | T const* pt; |
530 | | local_stream ss(ss0); |
531 | | std::size_t cur; |
532 | | constexpr std::size_t N = mp11::mp_size<Ds>::value; |
533 | | writer::state st; |
534 | | #if defined(_MSC_VER) |
535 | | # pragma warning( push ) |
536 | | # pragma warning( disable : 4127 ) |
537 | | #endif |
538 | | if(StackEmpty || w.st_.empty()) |
539 | | #if defined(_MSC_VER) |
540 | | # pragma warning( pop ) |
541 | | #endif |
542 | | { |
543 | | BOOST_ASSERT( w.p_ ); |
544 | | pt = reinterpret_cast<T const*>(w.p_); |
545 | | cur = 0; |
546 | | } |
547 | | else |
548 | | { |
549 | | w.st_.pop(st); |
550 | | w.st_.pop(cur); |
551 | | w.st_.pop(pt); |
552 | | switch(st) |
553 | | { |
554 | | default: |
555 | | case writer::state::obj1: goto do_obj1; |
556 | | case writer::state::obj2: // fall through |
557 | | case writer::state::obj3: // fall through |
558 | | case writer::state::obj4: goto do_obj2; |
559 | | case writer::state::obj5: goto do_obj5; |
560 | | case writer::state::obj6: goto do_obj6; |
561 | | break; |
562 | | } |
563 | | } |
564 | | do_obj1: |
565 | | if(BOOST_JSON_LIKELY( ss )) |
566 | | ss.append('{'); |
567 | | else |
568 | | return w.suspend(writer::state::obj1, cur, pt); |
569 | | if(BOOST_JSON_UNLIKELY( cur == N )) |
570 | | goto do_obj6; |
571 | | for(;;) |
572 | | { |
573 | | st = {}; |
574 | | do_obj2: |
575 | | st = mp11::mp_with_index<N>( |
576 | | cur, |
577 | | serialize_struct_elem_helper<T, StackEmpty>{w, ss, pt, st}); |
578 | | if(BOOST_JSON_UNLIKELY( st != writer::state{} )) |
579 | | return w.suspend(st, cur, pt); |
580 | | ++cur; |
581 | | if(BOOST_JSON_UNLIKELY(cur == N)) |
582 | | break; |
583 | | do_obj5: |
584 | | if(BOOST_JSON_LIKELY(ss)) |
585 | | ss.append(','); |
586 | | else |
587 | | return w.suspend(writer::state::obj5, cur, pt); |
588 | | } |
589 | | do_obj6: |
590 | | if(BOOST_JSON_LIKELY( ss )) |
591 | | { |
592 | | ss.append('}'); |
593 | | return true; |
594 | | } |
595 | | return w.suspend(writer::state::obj6, cur, pt); |
596 | | } |
597 | | |
598 | | template<class T, bool StackEmpty> |
599 | | BOOST_FORCEINLINE |
600 | | bool |
601 | | write_impl(described_enum_conversion_tag, writer& w, stream& ss) |
602 | | { |
603 | | #ifdef BOOST_DESCRIBE_CXX14 |
604 | | using Integer = typename std::underlying_type<T>::type; |
605 | | |
606 | | #if defined(_MSC_VER) |
607 | | # pragma warning( push ) |
608 | | # pragma warning( disable : 4127 ) |
609 | | #endif |
610 | | if(StackEmpty || w.st_.empty()) |
611 | | #if defined(_MSC_VER) |
612 | | # pragma warning( pop ) |
613 | | #endif |
614 | | { |
615 | | BOOST_ASSERT( w.p_ ); |
616 | | T const* pt = reinterpret_cast<T const*>(w.p_); |
617 | | char const* const name = describe::enum_to_string(*pt, nullptr); |
618 | | if( name ) |
619 | | { |
620 | | string_view const sv = name; |
621 | | w.cs0_ = { sv.data(), sv.size() }; |
622 | | return write_string(w, ss); |
623 | | } |
624 | | else |
625 | | { |
626 | | Integer n = static_cast<Integer>(*pt); |
627 | | w.p_ = &n; |
628 | | return write_impl<Integer, true>(w, ss); |
629 | | } |
630 | | } |
631 | | else |
632 | | { |
633 | | writer::state st; |
634 | | w.st_.peek(st); |
635 | | if( st == writer::state::lit ) |
636 | | return write_impl<Integer, false>(w, ss); |
637 | | else |
638 | | return resume_string(w, ss); |
639 | | } |
640 | | #else // BOOST_DESCRIBE_CXX14 |
641 | | (void)w; |
642 | | (void)ss; |
643 | | static_assert( |
644 | | !std::is_same<T, T>::value, |
645 | | "described enums require C++14 support"); |
646 | | return false; |
647 | | #endif // BOOST_DESCRIBE_CXX14 |
648 | | } |
649 | | |
650 | | template< class T, bool StackEmpty > |
651 | | struct serialize_variant_elem_helper |
652 | | { |
653 | | writer& w; |
654 | | stream& ss; |
655 | | |
656 | | template<class Elem> |
657 | | bool |
658 | | operator()(Elem const& x) const |
659 | | { |
660 | | w.p_ = std::addressof(x); |
661 | | return write_impl<Elem, true>(w, ss); |
662 | | } |
663 | | }; |
664 | | |
665 | | template< class T > |
666 | | struct serialize_variant_elem_helper<T, false> |
667 | | { |
668 | | writer& w; |
669 | | stream& ss; |
670 | | |
671 | | template< std::size_t I > |
672 | | bool |
673 | | operator()( std::integral_constant<std::size_t, I> ) const |
674 | | { |
675 | | using std::get; |
676 | | using Elem = remove_cvref<decltype(get<I>( |
677 | | std::declval<T const&>() ))>; |
678 | | return write_impl<Elem, false>(w, ss); |
679 | | } |
680 | | }; |
681 | | |
682 | | template<class T, bool StackEmpty> |
683 | | BOOST_FORCEINLINE |
684 | | bool |
685 | | write_impl(variant_conversion_tag, writer& w, stream& ss) |
686 | | { |
687 | | T const* pt; |
688 | | |
689 | | using Index = remove_cvref<decltype( pt->index() )>; |
690 | | |
691 | | #if defined(_MSC_VER) |
692 | | # pragma warning( push ) |
693 | | # pragma warning( disable : 4127 ) |
694 | | #endif |
695 | | if(StackEmpty || w.st_.empty()) |
696 | | #if defined(_MSC_VER) |
697 | | # pragma warning( pop ) |
698 | | #endif |
699 | | { |
700 | | BOOST_ASSERT( w.p_ ); |
701 | | pt = reinterpret_cast<T const*>(w.p_); |
702 | | if(BOOST_JSON_LIKELY(( |
703 | | visit(serialize_variant_elem_helper<T, true>{w, ss}, *pt)))) |
704 | | return true; |
705 | | |
706 | | Index const ix = pt->index(); |
707 | | w.st_.push(ix); |
708 | | return false; |
709 | | } |
710 | | else |
711 | | { |
712 | | Index ix; |
713 | | w.st_.pop(ix); |
714 | | |
715 | | constexpr std::size_t N = mp11::mp_size<T>::value; |
716 | | if(BOOST_JSON_LIKELY(( mp11::mp_with_index<N>( |
717 | | ix, |
718 | | serialize_variant_elem_helper<T, false>{w, ss})))) |
719 | | return true; |
720 | | |
721 | | w.st_.push(ix); |
722 | | return false; |
723 | | } |
724 | | } |
725 | | |
726 | | template<class T, bool StackEmpty> |
727 | | BOOST_FORCEINLINE |
728 | | bool |
729 | | write_impl(optional_conversion_tag, writer& w, stream& ss) |
730 | | { |
731 | | using Elem = value_result_type<T>; |
732 | | |
733 | | bool done; |
734 | | bool has_value; |
735 | | |
736 | | #if defined(_MSC_VER) |
737 | | # pragma warning( push ) |
738 | | # pragma warning( disable : 4127 ) |
739 | | #endif |
740 | | if(StackEmpty || w.st_.empty()) |
741 | | #if defined(_MSC_VER) |
742 | | # pragma warning( pop ) |
743 | | #endif |
744 | | { |
745 | | BOOST_ASSERT( w.p_ ); |
746 | | T const* pt = reinterpret_cast<T const*>(w.p_); |
747 | | has_value = static_cast<bool>(*pt); |
748 | | if( has_value ) |
749 | | { |
750 | | w.p_ = std::addressof( *(*pt) ); |
751 | | done = write_impl<Elem, true>(w, ss); |
752 | | } |
753 | | else |
754 | | { |
755 | | w.p_ = nullptr; |
756 | | done = write_impl<std::nullptr_t, true>(w, ss);; |
757 | | } |
758 | | } |
759 | | else |
760 | | { |
761 | | w.st_.pop(has_value); |
762 | | |
763 | | if( has_value ) |
764 | | done = write_impl<Elem, false>(w, ss); |
765 | | else |
766 | | done = write_impl<std::nullptr_t, false>(w, ss); |
767 | | } |
768 | | |
769 | | if(BOOST_JSON_UNLIKELY( !done )) |
770 | | w.st_.push(has_value); |
771 | | |
772 | | return done; |
773 | | } |
774 | | |
775 | | template<class T, bool StackEmpty> |
776 | | BOOST_FORCEINLINE |
777 | | bool |
778 | | write_impl(path_conversion_tag, writer& w, stream& ss) |
779 | | { |
780 | | #if defined(_MSC_VER) |
781 | | # pragma warning( push ) |
782 | | # pragma warning( disable : 4127 ) |
783 | | #endif |
784 | | if(StackEmpty || w.st_.empty()) |
785 | | #if defined(_MSC_VER) |
786 | | # pragma warning( pop ) |
787 | | #endif |
788 | | { |
789 | | BOOST_ASSERT( w.p_ ); |
790 | | T const* pt = reinterpret_cast<T const*>(w.p_); |
791 | | |
792 | | std::string const s = pt->generic_string(); |
793 | | w.cs0_ = { s.data(), s.size() }; |
794 | | if(BOOST_JSON_LIKELY( write_string(w, ss) )) |
795 | | return true; |
796 | | |
797 | | std::size_t const used = w.cs0_.used( s.data() ); |
798 | | w.st_.push( used ); |
799 | | w.st_.push( std::move(s) ); |
800 | | return false; |
801 | | } |
802 | | else |
803 | | { |
804 | | std::string s; |
805 | | std::size_t used; |
806 | | w.st_.pop( s ); |
807 | | w.st_.pop( used ); |
808 | | |
809 | | w.cs0_ = { s.data(), s.size() }; |
810 | | w.cs0_.skip(used); |
811 | | |
812 | | if(BOOST_JSON_LIKELY( resume_string(w, ss) )) |
813 | | return true; |
814 | | |
815 | | used = w.cs0_.used( s.data() ); |
816 | | w.st_.push( used ); |
817 | | w.st_.push( std::move(s) ); |
818 | | return false; |
819 | | } |
820 | | } |
821 | | |
822 | | template<class T, bool StackEmpty> |
823 | | bool |
824 | | write_impl(writer& w, stream& ss) |
825 | 9.55M | { |
826 | 9.55M | using cat = detail::generic_conversion_category<T>; |
827 | 9.55M | return write_impl<T, StackEmpty>( cat(), w, ss ); |
828 | 9.55M | } bool boost::json::detail::write_impl<boost::json::value, true>(boost::json::detail::writer&, boost::json::detail::stream&) Line | Count | Source | 825 | 1.66M | { | 826 | 1.66M | using cat = detail::generic_conversion_category<T>; | 827 | 1.66M | return write_impl<T, StackEmpty>( cat(), w, ss ); | 828 | 1.66M | } |
bool boost::json::detail::write_impl<boost::json::value, false>(boost::json::detail::writer&, boost::json::detail::stream&) Line | Count | Source | 825 | 7.87M | { | 826 | 7.87M | using cat = detail::generic_conversion_category<T>; | 827 | 7.87M | return write_impl<T, StackEmpty>( cat(), w, ss ); | 828 | 7.87M | } |
bool boost::json::detail::write_impl<boost::json::value&, true>(boost::json::detail::writer&, boost::json::detail::stream&) Line | Count | Source | 825 | 12.4k | { | 826 | 12.4k | using cat = detail::generic_conversion_category<T>; | 827 | 12.4k | return write_impl<T, StackEmpty>( cat(), w, ss ); | 828 | 12.4k | } |
bool boost::json::detail::write_impl<boost::json::value&, false>(boost::json::detail::writer&, boost::json::detail::stream&) Line | Count | Source | 825 | 3.92k | { | 826 | 3.92k | using cat = detail::generic_conversion_category<T>; | 827 | 3.92k | return write_impl<T, StackEmpty>( cat(), w, ss ); | 828 | 3.92k | } |
Unexecuted instantiation: bool boost::json::detail::write_impl<decltype(nullptr), true>(boost::json::detail::writer&, boost::json::detail::stream&) Unexecuted instantiation: bool boost::json::detail::write_impl<decltype(nullptr), false>(boost::json::detail::writer&, boost::json::detail::stream&) |
829 | | |
830 | | } // namespace detail |
831 | | |
832 | | template<class T> |
833 | | void |
834 | | serializer::reset(T const* p) noexcept |
835 | | { |
836 | | BOOST_CORE_STATIC_ASSERT( !std::is_pointer<T>::value ); |
837 | | BOOST_CORE_STATIC_ASSERT( std::is_object<T>::value ); |
838 | | |
839 | | p_ = p; |
840 | | fn0_ = &detail::write_impl<T, true>; |
841 | | fn1_ = &detail::write_impl<T, false>; |
842 | | st_.clear(); |
843 | | done_ = false; |
844 | | } |
845 | | |
846 | | } // namespace json |
847 | | } // namespace boost |
848 | | |
849 | | #endif // BOOST_JSON_IMPL_SERIALIZER_HPP |