WPILibC++ 2024.3.2
to_json.h
Go to the documentation of this file.
1// __ _____ _____ _____
2// __| | __| | | | JSON for Modern C++
3// | | |__ | | | | | | version 3.11.2
4// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7// SPDX-License-Identifier: MIT
8
9#pragma once
10
11#include <algorithm> // copy
12#include <iterator> // begin, end
13#include <string> // string
14#include <tuple> // tuple, get
15#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
16#include <utility> // move, forward, declval, pair
17#include <valarray> // valarray
18#include <vector> // vector
19
25#include <wpi/detail/value_t.h>
26
28namespace detail
29{
30
31//////////////////
32// constructors //
33//////////////////
34
35/*
36 * Note all external_constructor<>::construct functions need to call
37 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
38 * allocated value (e.g., a string). See bug issue
39 * https://github.com/nlohmann/json/issues/2865 for more information.
40 */
41
42template<value_t> struct external_constructor;
43
44template<>
46{
47 template<typename BasicJsonType>
48 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
49 {
50 j.m_value.destroy(j.m_type);
51 j.m_type = value_t::boolean;
52 j.m_value = b;
53 j.assert_invariant();
54 }
55};
56
57template<>
59{
60 template<typename BasicJsonType>
61 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
62 {
63 j.m_value.destroy(j.m_type);
64 j.m_type = value_t::string;
65 j.m_value = s;
66 j.assert_invariant();
67 }
68
69 template<typename BasicJsonType>
70 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
71 {
72 j.m_value.destroy(j.m_type);
73 j.m_type = value_t::string;
74 j.m_value = std::move(s);
75 j.assert_invariant();
76 }
77
78 template < typename BasicJsonType, typename CompatibleStringType,
80 int > = 0 >
81 static void construct(BasicJsonType& j, const CompatibleStringType& str)
82 {
83 j.m_value.destroy(j.m_type);
84 j.m_type = value_t::string;
85 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
86 j.assert_invariant();
87 }
88};
89
90template<>
92{
93 template<typename BasicJsonType>
94 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
95 {
96 j.m_value.destroy(j.m_type);
97 j.m_type = value_t::binary;
98 j.m_value = typename BasicJsonType::binary_t(b);
99 j.assert_invariant();
100 }
101
102 template<typename BasicJsonType>
103 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
104 {
105 j.m_value.destroy(j.m_type);
106 j.m_type = value_t::binary;
107 j.m_value = typename BasicJsonType::binary_t(std::move(b));
108 j.assert_invariant();
109 }
110};
111
112template<>
114{
115 template<typename BasicJsonType>
116 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
117 {
118 j.m_value.destroy(j.m_type);
119 j.m_type = value_t::number_float;
120 j.m_value = val;
121 j.assert_invariant();
122 }
123};
124
125template<>
127{
128 template<typename BasicJsonType>
129 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
130 {
131 j.m_value.destroy(j.m_type);
132 j.m_type = value_t::number_unsigned;
133 j.m_value = val;
134 j.assert_invariant();
135 }
136};
137
138template<>
140{
141 template<typename BasicJsonType>
142 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
143 {
144 j.m_value.destroy(j.m_type);
145 j.m_type = value_t::number_integer;
146 j.m_value = val;
147 j.assert_invariant();
148 }
149};
150
151template<>
153{
154 template<typename BasicJsonType>
155 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
156 {
157 j.m_value.destroy(j.m_type);
158 j.m_type = value_t::array;
159 j.m_value = arr;
160 j.set_parents();
161 j.assert_invariant();
162 }
163
164 template<typename BasicJsonType>
165 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
166 {
167 j.m_value.destroy(j.m_type);
168 j.m_type = value_t::array;
169 j.m_value = std::move(arr);
170 j.set_parents();
171 j.assert_invariant();
172 }
173
174 template < typename BasicJsonType, typename CompatibleArrayType,
176 int > = 0 >
177 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
178 {
179 using std::begin;
180 using std::end;
181
182 j.m_value.destroy(j.m_type);
183 j.m_type = value_t::array;
184 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
185 j.set_parents();
186 j.assert_invariant();
187 }
188
189 template<typename BasicJsonType>
190 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
191 {
192 j.m_value.destroy(j.m_type);
193 j.m_type = value_t::array;
194 j.m_value = value_t::array;
195 j.m_value.array->reserve(arr.size());
196 for (const bool x : arr)
197 {
198 j.m_value.array->push_back(x);
199 j.set_parent(j.m_value.array->back());
200 }
201 j.assert_invariant();
202 }
203
204 template<typename BasicJsonType, typename T,
206 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
207 {
208 j.m_value.destroy(j.m_type);
209 j.m_type = value_t::array;
210 j.m_value = value_t::array;
211 j.m_value.array->resize(arr.size());
212 if (arr.size() > 0)
213 {
214 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
215 }
216 j.set_parents();
217 j.assert_invariant();
218 }
219};
220
221template<>
223{
224 template<typename BasicJsonType>
225 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
226 {
227 j.m_value.destroy(j.m_type);
228 j.m_type = value_t::object;
229 j.m_value = obj;
230 j.set_parents();
231 j.assert_invariant();
232 }
233
234 template<typename BasicJsonType>
235 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
236 {
237 j.m_value.destroy(j.m_type);
238 j.m_type = value_t::object;
239 j.m_value = std::move(obj);
240 j.set_parents();
241 j.assert_invariant();
242 }
243
244 template < typename BasicJsonType, typename CompatibleObjectType,
246 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
247 {
248 using std::begin;
249 using std::end;
250
251 j.m_value.destroy(j.m_type);
252 j.m_type = value_t::object;
253 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
254 j.set_parents();
255 j.assert_invariant();
256 }
257};
258
259/////////////
260// to_json //
261/////////////
262
263template<typename BasicJsonType, typename T,
265inline void to_json(BasicJsonType& j, T b) noexcept
266{
268}
269
270template < typename BasicJsonType, typename BoolRef,
272 ((std::is_same<std::vector<bool>::reference, BoolRef>::value
273 && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
274 || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
275 && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
276 typename BasicJsonType::boolean_t >::value))
277 && std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >
278inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
279{
280 external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
281}
282
283template<typename BasicJsonType, typename CompatibleString,
285inline void to_json(BasicJsonType& j, const CompatibleString& s)
286{
288}
289
290template<typename BasicJsonType>
291inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
292{
294}
295
296template<typename BasicJsonType, typename FloatType,
298inline void to_json(BasicJsonType& j, FloatType val) noexcept
299{
300 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
301}
302
303template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
305inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
306{
307 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
308}
309
310template<typename BasicJsonType, typename CompatibleNumberIntegerType,
312inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
313{
314 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
315}
316
317#if !JSON_DISABLE_ENUM_SERIALIZATION
318template<typename BasicJsonType, typename EnumType,
320inline void to_json(BasicJsonType& j, EnumType e) noexcept
321{
322 using underlying_type = typename std::underlying_type<EnumType>::type;
323 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
324}
325#endif // JSON_DISABLE_ENUM_SERIALIZATION
326
327template<typename BasicJsonType>
328inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
329{
331}
332
333template < typename BasicJsonType, typename CompatibleArrayType,
334 enable_if_t < is_compatible_array_type<BasicJsonType,
335 CompatibleArrayType>::value&&
336 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
338 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
339 !is_basic_json<CompatibleArrayType>::value,
340 int > = 0 >
341inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
342{
344}
345
346template<typename BasicJsonType>
347inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
348{
350}
351
352template<typename BasicJsonType, typename T,
354inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
355{
357}
358
359template<typename BasicJsonType>
360inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
361{
363}
364
365template < typename BasicJsonType, typename CompatibleObjectType,
366 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
367inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
368{
370}
371
372template<typename BasicJsonType>
373inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
374{
376}
377
378template <
379 typename BasicJsonType, typename T, std::size_t N,
380 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
381 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
382 int > = 0 >
383inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
384{
386}
387
388template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
389inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
390{
391 j = { p.first, p.second };
392}
393
394// for https://github.com/nlohmann/json/pull/1134
395template<typename BasicJsonType, typename T,
397inline void to_json(BasicJsonType& j, const T& b)
398{
399 j = { {b.key(), b.value()} };
400}
401
402template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
403inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
404{
405 j = { std::get<Idx>(t)... };
406}
407
408template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
409inline void to_json(BasicJsonType& j, const T& t)
410{
411 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
412}
413
414#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
415template<typename BasicJsonType>
416inline void to_json(BasicJsonType& j, const std_fs::path& p)
417{
418 j = p.string();
419}
420#endif
421
423{
424 template<typename BasicJsonType, typename T>
425 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
426 -> decltype(to_json(j, std::forward<T>(val)), void())
427 {
428 return to_json(j, std::forward<T>(val));
429 }
430};
431} // namespace detail
432
433#ifndef JSON_HAS_CPP_17
434/// namespace to hold default `to_json` function
435/// to see why this is required:
436/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
437namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
438{
439#endif
440JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
442#ifndef JSON_HAS_CPP_17
443} // namespace
444#endif
445
#define WPI_JSON_NAMESPACE_END
Definition: abi_macros.h:59
#define WPI_JSON_NAMESPACE_BEGIN
Definition: abi_macros.h:53
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:256
#define JSON_INLINE_VARIABLE
Definition: macro_scope.h:139
detail namespace with internal helper functions
Definition: xchar.h:20
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: to_json.h:403
auto copy(const Range &range, OutputIt out) -> OutputIt
Definition: ranges.h:26
void to_json(BasicJsonType &j, const T &b)
Definition: to_json.h:397
typename std::enable_if< B, T >::type enable_if_t
Definition: cpp_future.h:38
make_integer_sequence< size_t, N > make_index_sequence
Definition: ranges.h:201
value_t
the JSON type enumeration
Definition: value_t.h:54
@ number_integer
number value (signed integer)
@ boolean
boolean value
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ string
string value
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void to_json(BasicJsonType &j, T b) noexcept
Definition: to_json.h:265
type
Definition: core.h:556
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: cpp_future.h:24
static constexpr const charge::coulomb_t e(1.6021766208e-19)
elementary charge.
b
Definition: data.h:44
array(T, Ts...) -> array< T, 1+sizeof...(Ts)>
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: to_json.h:190
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: to_json.h:165
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: to_json.h:155
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: to_json.h:177
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: to_json.h:206
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: to_json.h:94
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: to_json.h:103
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: to_json.h:48
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: to_json.h:116
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: to_json.h:142
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: to_json.h:129
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: to_json.h:225
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: to_json.h:246
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: to_json.h:235
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: to_json.h:70
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: to_json.h:81
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: to_json.h:61
Definition: to_json.h:42
Definition: ranges.h:187
static constexpr auto value
Definition: type_traits.h:350
Definition: cpp_future.h:155
Definition: to_json.h:423
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: to_json.h:425