Horizon
to_json.hpp
1 #pragma once
2 
3 #include <algorithm> // copy
4 #include <iterator> // begin, end
5 #include <string> // string
6 #include <tuple> // tuple, get
7 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
8 #include <utility> // move, forward, declval, pair
9 #include <valarray> // valarray
10 #include <vector> // vector
11 
12 #include <nlohmann/detail/iterators/iteration_proxy.hpp>
13 #include <nlohmann/detail/meta/cpp_future.hpp>
14 #include <nlohmann/detail/meta/type_traits.hpp>
15 #include <nlohmann/detail/value_t.hpp>
16 
17 namespace nlohmann
18 {
19 namespace detail
20 {
22 // constructors //
24 
25 template<value_t> struct external_constructor;
26 
27 template<>
29 {
30  template<typename BasicJsonType>
31  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
32  {
33  j.m_type = value_t::boolean;
34  j.m_value = b;
35  j.assert_invariant();
36  }
37 };
38 
39 template<>
41 {
42  template<typename BasicJsonType>
43  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
44  {
45  j.m_type = value_t::string;
46  j.m_value = s;
47  j.assert_invariant();
48  }
49 
50  template<typename BasicJsonType>
51  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
52  {
53  j.m_type = value_t::string;
54  j.m_value = std::move(s);
55  j.assert_invariant();
56  }
57 
58  template < typename BasicJsonType, typename CompatibleStringType,
59  enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
60  int > = 0 >
61  static void construct(BasicJsonType& j, const CompatibleStringType& str)
62  {
63  j.m_type = value_t::string;
64  j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
65  j.assert_invariant();
66  }
67 };
68 
69 template<>
71 {
72  template<typename BasicJsonType>
73  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
74  {
75  j.m_type = value_t::binary;
76  typename BasicJsonType::binary_t value{b};
77  j.m_value = value;
78  j.assert_invariant();
79  }
80 
81  template<typename BasicJsonType>
82  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
83  {
84  j.m_type = value_t::binary;
85  typename BasicJsonType::binary_t value{std::move(b)};
86  j.m_value = value;
87  j.assert_invariant();
88  }
89 };
90 
91 template<>
93 {
94  template<typename BasicJsonType>
95  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
96  {
97  j.m_type = value_t::number_float;
98  j.m_value = val;
99  j.assert_invariant();
100  }
101 };
102 
103 template<>
105 {
106  template<typename BasicJsonType>
107  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
108  {
109  j.m_type = value_t::number_unsigned;
110  j.m_value = val;
111  j.assert_invariant();
112  }
113 };
114 
115 template<>
117 {
118  template<typename BasicJsonType>
119  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
120  {
121  j.m_type = value_t::number_integer;
122  j.m_value = val;
123  j.assert_invariant();
124  }
125 };
126 
127 template<>
129 {
130  template<typename BasicJsonType>
131  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
132  {
133  j.m_type = value_t::array;
134  j.m_value = arr;
135  j.assert_invariant();
136  }
137 
138  template<typename BasicJsonType>
139  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
140  {
141  j.m_type = value_t::array;
142  j.m_value = std::move(arr);
143  j.assert_invariant();
144  }
145 
146  template < typename BasicJsonType, typename CompatibleArrayType,
147  enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
148  int > = 0 >
149  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
150  {
151  using std::begin;
152  using std::end;
153  j.m_type = value_t::array;
154  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
155  j.assert_invariant();
156  }
157 
158  template<typename BasicJsonType>
159  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
160  {
161  j.m_type = value_t::array;
162  j.m_value = value_t::array;
163  j.m_value.array->reserve(arr.size());
164  for (const bool x : arr)
165  {
166  j.m_value.array->push_back(x);
167  }
168  j.assert_invariant();
169  }
170 
171  template<typename BasicJsonType, typename T,
172  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
173  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
174  {
175  j.m_type = value_t::array;
176  j.m_value = value_t::array;
177  j.m_value.array->resize(arr.size());
178  if (arr.size() > 0)
179  {
180  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
181  }
182  j.assert_invariant();
183  }
184 };
185 
186 template<>
188 {
189  template<typename BasicJsonType>
190  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
191  {
192  j.m_type = value_t::object;
193  j.m_value = obj;
194  j.assert_invariant();
195  }
196 
197  template<typename BasicJsonType>
198  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
199  {
200  j.m_type = value_t::object;
201  j.m_value = std::move(obj);
202  j.assert_invariant();
203  }
204 
205  template < typename BasicJsonType, typename CompatibleObjectType,
206  enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
207  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
208  {
209  using std::begin;
210  using std::end;
211 
212  j.m_type = value_t::object;
213  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
214  j.assert_invariant();
215  }
216 };
217 
219 // to_json //
221 
222 template<typename BasicJsonType, typename T,
223  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
224 void to_json(BasicJsonType& j, T b) noexcept
225 {
227 }
228 
229 template<typename BasicJsonType, typename CompatibleString,
230  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
231 void to_json(BasicJsonType& j, const CompatibleString& s)
232 {
233  external_constructor<value_t::string>::construct(j, s);
234 }
235 
236 template<typename BasicJsonType>
237 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
238 {
239  external_constructor<value_t::string>::construct(j, std::move(s));
240 }
241 
242 template<typename BasicJsonType, typename FloatType,
243  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
244 void to_json(BasicJsonType& j, FloatType val) noexcept
245 {
246  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
247 }
248 
249 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
250  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
251 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
252 {
253  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
254 }
255 
256 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
257  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
258 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
259 {
260  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
261 }
262 
263 template<typename BasicJsonType, typename EnumType,
264  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
265 void to_json(BasicJsonType& j, EnumType e) noexcept
266 {
267  using underlying_type = typename std::underlying_type<EnumType>::type;
268  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
269 }
270 
271 template<typename BasicJsonType>
272 void to_json(BasicJsonType& j, const std::vector<bool>& e)
273 {
274  external_constructor<value_t::array>::construct(j, e);
275 }
276 
277 template < typename BasicJsonType, typename CompatibleArrayType,
278  enable_if_t < is_compatible_array_type<BasicJsonType,
279  CompatibleArrayType>::value&&
280  !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
281  !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
282  !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
283  !is_basic_json<CompatibleArrayType>::value,
284  int > = 0 >
285 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
286 {
287  external_constructor<value_t::array>::construct(j, arr);
288 }
289 
290 template<typename BasicJsonType>
291 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
292 {
293  external_constructor<value_t::binary>::construct(j, bin);
294 }
295 
296 template<typename BasicJsonType, typename T,
297  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
298 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
299 {
300  external_constructor<value_t::array>::construct(j, std::move(arr));
301 }
302 
303 template<typename BasicJsonType>
304 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
305 {
306  external_constructor<value_t::array>::construct(j, std::move(arr));
307 }
308 
309 template < typename BasicJsonType, typename CompatibleObjectType,
310  enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
311 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
312 {
313  external_constructor<value_t::object>::construct(j, obj);
314 }
315 
316 template<typename BasicJsonType>
317 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
318 {
319  external_constructor<value_t::object>::construct(j, std::move(obj));
320 }
321 
322 template <
323  typename BasicJsonType, typename T, std::size_t N,
324  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
325  const T(&)[N]>::value,
326  int > = 0 >
327 void to_json(BasicJsonType& j, const T(&arr)[N])
328 {
329  external_constructor<value_t::array>::construct(j, arr);
330 }
331 
332 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
333 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
334 {
335  j = { p.first, p.second };
336 }
337 
338 // for https://github.com/nlohmann/json/pull/1134
339 template<typename BasicJsonType, typename T,
340  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
341 void to_json(BasicJsonType& j, const T& b)
342 {
343  j = { {b.key(), b.value()} };
344 }
345 
346 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
347 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
348 {
349  j = { std::get<Idx>(t)... };
350 }
351 
352 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
353 void to_json(BasicJsonType& j, const T& t)
354 {
355  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
356 }
357 
359 {
360  template<typename BasicJsonType, typename T>
361  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
362  -> decltype(to_json(j, std::forward<T>(val)), void())
363  {
364  return to_json(j, std::forward<T>(val));
365  }
366 };
367 } // namespace detail
368 
370 namespace
371 {
372 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
373 } // namespace
374 } // namespace nlohmann
value_t
the JSON type enumeration
Definition: value_t.hpp:41
@ number_integer
number value (signed integer)
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
@ value
the parser finished reading a JSON value
namespace for Niels Lohmann
Definition: adl_serializer.hpp:9
Definition: to_json.hpp:25
Definition: cpp_future.hpp:55
Definition: to_json.hpp:359