8 #include <nlohmann/detail/iterators/iterator_traits.hpp>
9 #include <nlohmann/detail/macro_scope.hpp>
10 #include <nlohmann/detail/meta/cpp_future.hpp>
11 #include <nlohmann/detail/meta/detected.hpp>
12 #include <nlohmann/json_fwd.hpp>
39 template<
typename>
struct is_basic_json : std::false_type {};
41 NLOHMANN_BASIC_JSON_TPL_DECLARATION
42 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
49 using mapped_type_t =
typename T::mapped_type;
52 using key_type_t =
typename T::key_type;
55 using value_type_t =
typename T::value_type;
58 using difference_type_t =
typename T::difference_type;
61 using pointer_t =
typename T::pointer;
64 using reference_t =
typename T::reference;
67 using iterator_category_t =
typename T::iterator_category;
70 using iterator_t =
typename T::iterator;
72 template <
typename T,
typename... Args>
73 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
75 template <
typename T,
typename... Args>
76 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
78 template <
typename T,
typename U>
79 using get_template_function = decltype(std::declval<T>().
template get<U>());
82 template <
typename BasicJsonType,
typename T,
typename =
void>
83 struct has_from_json : std::false_type {};
85 template <
typename BasicJsonType,
typename T>
86 struct has_from_json<BasicJsonType, T,
87 enable_if_t<not is_basic_json<T>::value>>
89 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
91 static constexpr
bool value =
92 is_detected_exact<void, from_json_function, serializer,
93 const BasicJsonType&, T&>::value;
98 template <
typename BasicJsonType,
typename T,
typename =
void>
99 struct has_non_default_from_json : std::false_type {};
101 template<
typename BasicJsonType,
typename T>
102 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
104 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
106 static constexpr
bool value =
107 is_detected_exact<T, from_json_function, serializer,
108 const BasicJsonType&>::value;
113 template <
typename BasicJsonType,
typename T,
typename =
void>
114 struct has_to_json : std::false_type {};
116 template <
typename BasicJsonType,
typename T>
117 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
119 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
121 static constexpr
bool value =
122 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
131 template <
typename T,
typename =
void>
132 struct is_iterator_traits : std::false_type {};
134 template <
typename T>
135 struct is_iterator_traits<iterator_traits<T>>
138 using traits = iterator_traits<T>;
141 static constexpr
auto value =
142 is_detected<value_type_t, traits>::value &&
143 is_detected<difference_type_t, traits>::value &&
144 is_detected<pointer_t, traits>::value &&
145 is_detected<iterator_category_t, traits>::value &&
146 is_detected<reference_t, traits>::value;
151 template <
typename T,
typename =
void>
152 struct is_complete_type : std::false_type {};
154 template <
typename T>
155 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
157 template <
typename BasicJsonType,
typename CompatibleObjectType,
159 struct is_compatible_object_type_impl : std::false_type {};
161 template <
typename BasicJsonType,
typename CompatibleObjectType>
162 struct is_compatible_object_type_impl <
163 BasicJsonType, CompatibleObjectType,
164 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
165 is_detected<key_type_t, CompatibleObjectType>::value >>
168 using object_t =
typename BasicJsonType::object_t;
171 static constexpr
bool value =
172 std::is_constructible<
typename object_t::key_type,
173 typename CompatibleObjectType::key_type>::value and
174 std::is_constructible<
typename object_t::mapped_type,
175 typename CompatibleObjectType::mapped_type>::value;
178 template <
typename BasicJsonType,
typename CompatibleObjectType>
179 struct is_compatible_object_type
180 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
182 template <
typename BasicJsonType,
typename ConstructibleObjectType,
184 struct is_constructible_object_type_impl : std::false_type {};
186 template <
typename BasicJsonType,
typename ConstructibleObjectType>
187 struct is_constructible_object_type_impl <
188 BasicJsonType, ConstructibleObjectType,
189 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
190 is_detected<key_type_t, ConstructibleObjectType>::value >>
192 using object_t =
typename BasicJsonType::object_t;
194 static constexpr
bool value =
195 (std::is_default_constructible<ConstructibleObjectType>::value and
196 (std::is_move_assignable<ConstructibleObjectType>::value or
197 std::is_copy_assignable<ConstructibleObjectType>::value) and
198 (std::is_constructible<
typename ConstructibleObjectType::key_type,
199 typename object_t::key_type>::value and
201 typename object_t::mapped_type,
202 typename ConstructibleObjectType::mapped_type >::value)) or
203 (has_from_json<BasicJsonType,
204 typename ConstructibleObjectType::mapped_type>::value or
205 has_non_default_from_json <
207 typename ConstructibleObjectType::mapped_type >::value);
210 template <
typename BasicJsonType,
typename ConstructibleObjectType>
211 struct is_constructible_object_type
212 : is_constructible_object_type_impl<BasicJsonType,
213 ConstructibleObjectType> {};
215 template <
typename BasicJsonType,
typename CompatibleStringType,
217 struct is_compatible_string_type_impl : std::false_type {};
219 template <
typename BasicJsonType,
typename CompatibleStringType>
220 struct is_compatible_string_type_impl <
221 BasicJsonType, CompatibleStringType,
222 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
223 value_type_t, CompatibleStringType>::value >>
225 static constexpr
auto value =
226 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
229 template <
typename BasicJsonType,
typename ConstructibleStringType>
230 struct is_compatible_string_type
231 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
233 template <
typename BasicJsonType,
typename ConstructibleStringType,
235 struct is_constructible_string_type_impl : std::false_type {};
237 template <
typename BasicJsonType,
typename ConstructibleStringType>
238 struct is_constructible_string_type_impl <
239 BasicJsonType, ConstructibleStringType,
240 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
241 value_type_t, ConstructibleStringType>::value >>
243 static constexpr
auto value =
244 std::is_constructible<ConstructibleStringType,
245 typename BasicJsonType::string_t>::value;
248 template <
typename BasicJsonType,
typename ConstructibleStringType>
249 struct is_constructible_string_type
250 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
252 template <
typename BasicJsonType,
typename CompatibleArrayType,
typename =
void>
253 struct is_compatible_array_type_impl : std::false_type {};
255 template <
typename BasicJsonType,
typename CompatibleArrayType>
256 struct is_compatible_array_type_impl <
257 BasicJsonType, CompatibleArrayType,
258 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
259 is_detected<iterator_t, CompatibleArrayType>::value and
263 not is_iterator_traits<
264 iterator_traits<CompatibleArrayType>>::value >>
266 static constexpr
bool value =
267 std::is_constructible<BasicJsonType,
268 typename CompatibleArrayType::value_type>::value;
271 template <
typename BasicJsonType,
typename CompatibleArrayType>
272 struct is_compatible_array_type
273 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
275 template <
typename BasicJsonType,
typename ConstructibleArrayType,
typename =
void>
276 struct is_constructible_array_type_impl : std::false_type {};
278 template <
typename BasicJsonType,
typename ConstructibleArrayType>
279 struct is_constructible_array_type_impl <
280 BasicJsonType, ConstructibleArrayType,
281 enable_if_t<std::is_same<ConstructibleArrayType,
282 typename BasicJsonType::value_type>::value >>
285 template <
typename BasicJsonType,
typename ConstructibleArrayType>
286 struct is_constructible_array_type_impl <
287 BasicJsonType, ConstructibleArrayType,
288 enable_if_t<not std::is_same<ConstructibleArrayType,
289 typename BasicJsonType::value_type>::value and
290 std::is_default_constructible<ConstructibleArrayType>::value and
291 (std::is_move_assignable<ConstructibleArrayType>::value or
292 std::is_copy_assignable<ConstructibleArrayType>::value) and
293 is_detected<value_type_t, ConstructibleArrayType>::value and
294 is_detected<iterator_t, ConstructibleArrayType>::value and
296 detected_t<value_type_t, ConstructibleArrayType>>::value >>
298 static constexpr
bool value =
304 not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value and
306 (std::is_same<
typename ConstructibleArrayType::value_type,
307 typename BasicJsonType::array_t::value_type>::value or
308 has_from_json<BasicJsonType,
309 typename ConstructibleArrayType::value_type>::value or
310 has_non_default_from_json <
311 BasicJsonType,
typename ConstructibleArrayType::value_type >::value);
314 template <
typename BasicJsonType,
typename ConstructibleArrayType>
315 struct is_constructible_array_type
316 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
318 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType,
320 struct is_compatible_integer_type_impl : std::false_type {};
322 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
323 struct is_compatible_integer_type_impl <
324 RealIntegerType, CompatibleNumberIntegerType,
325 enable_if_t<std::is_integral<RealIntegerType>::value and
326 std::is_integral<CompatibleNumberIntegerType>::value and
327 not std::is_same<bool, CompatibleNumberIntegerType>::value >>
330 using RealLimits = std::numeric_limits<RealIntegerType>;
331 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
333 static constexpr
auto value =
334 std::is_constructible<RealIntegerType,
335 CompatibleNumberIntegerType>::value and
336 CompatibleLimits::is_integer and
337 RealLimits::is_signed == CompatibleLimits::is_signed;
340 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
341 struct is_compatible_integer_type
342 : is_compatible_integer_type_impl<RealIntegerType,
343 CompatibleNumberIntegerType> {};
345 template <
typename BasicJsonType,
typename CompatibleType,
typename =
void>
346 struct is_compatible_type_impl: std::false_type {};
348 template <
typename BasicJsonType,
typename CompatibleType>
349 struct is_compatible_type_impl <
350 BasicJsonType, CompatibleType,
351 enable_if_t<is_complete_type<CompatibleType>::value >>
353 static constexpr
bool value =
354 has_to_json<BasicJsonType, CompatibleType>::value;
357 template <
typename BasicJsonType,
typename CompatibleType>
358 struct is_compatible_type
359 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
362 template<
class...>
struct conjunction : std::true_type { };
363 template<
class B1>
struct conjunction<B1> : B1 { };
364 template<
class B1,
class... Bn>
365 struct conjunction<B1, Bn...>
366 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
368 template <
typename T1,
typename T2>
369 struct is_constructible_tuple : std::false_type {};
371 template <
typename T1,
typename... Args>
372 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};