]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/third_party/nlohmann-json/include/nlohmann/detail/meta/type_traits.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / third_party / nlohmann-json / include / nlohmann / detail / meta / type_traits.hpp
1 #pragma once
2
3 #include <limits> // numeric_limits
4 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
5 #include <utility> // declval
6 #include <tuple> // tuple
7
8 #include <nlohmann/detail/macro_scope.hpp>
9
10 #include <nlohmann/detail/iterators/iterator_traits.hpp>
11 #include <nlohmann/detail/meta/call_std/begin.hpp>
12 #include <nlohmann/detail/meta/call_std/end.hpp>
13 #include <nlohmann/detail/meta/cpp_future.hpp>
14 #include <nlohmann/detail/meta/detected.hpp>
15 #include <nlohmann/json_fwd.hpp>
16
17 namespace nlohmann
18 {
19 /*!
20 @brief detail namespace with internal helper functions
21
22 This namespace collects functions that should not be exposed,
23 implementations of some @ref basic_json methods, and meta-programming helpers.
24
25 @since version 2.1.0
26 */
27 namespace detail
28 {
29 /////////////
30 // helpers //
31 /////////////
32
33 // Note to maintainers:
34 //
35 // Every trait in this file expects a non CV-qualified type.
36 // The only exceptions are in the 'aliases for detected' section
37 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
38 //
39 // In this case, T has to be properly CV-qualified to constraint the function arguments
40 // (e.g. to_json(BasicJsonType&, const T&))
41
42 template<typename> struct is_basic_json : std::false_type {};
43
44 NLOHMANN_BASIC_JSON_TPL_DECLARATION
45 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
46
47 //////////////////////
48 // json_ref helpers //
49 //////////////////////
50
51 template<typename>
52 class json_ref;
53
54 template<typename>
55 struct is_json_ref : std::false_type {};
56
57 template<typename T>
58 struct is_json_ref<json_ref<T>> : std::true_type {};
59
60 //////////////////////////
61 // aliases for detected //
62 //////////////////////////
63
64 template<typename T>
65 using mapped_type_t = typename T::mapped_type;
66
67 template<typename T>
68 using key_type_t = typename T::key_type;
69
70 template<typename T>
71 using value_type_t = typename T::value_type;
72
73 template<typename T>
74 using difference_type_t = typename T::difference_type;
75
76 template<typename T>
77 using pointer_t = typename T::pointer;
78
79 template<typename T>
80 using reference_t = typename T::reference;
81
82 template<typename T>
83 using iterator_category_t = typename T::iterator_category;
84
85 template<typename T, typename... Args>
86 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
87
88 template<typename T, typename... Args>
89 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
90
91 template<typename T, typename U>
92 using get_template_function = decltype(std::declval<T>().template get<U>());
93
94 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
95 template<typename BasicJsonType, typename T, typename = void>
96 struct has_from_json : std::false_type {};
97
98 // trait checking if j.get<T> is valid
99 // use this trait instead of std::is_constructible or std::is_convertible,
100 // both rely on, or make use of implicit conversions, and thus fail when T
101 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
102 template <typename BasicJsonType, typename T>
103 struct is_getable
104 {
105 static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
106 };
107
108 template<typename BasicJsonType, typename T>
109 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
110 {
111 using serializer = typename BasicJsonType::template json_serializer<T, void>;
112
113 static constexpr bool value =
114 is_detected_exact<void, from_json_function, serializer,
115 const BasicJsonType&, T&>::value;
116 };
117
118 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
119 // this overload is used for non-default-constructible user-defined-types
120 template<typename BasicJsonType, typename T, typename = void>
121 struct has_non_default_from_json : std::false_type {};
122
123 template<typename BasicJsonType, typename T>
124 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
125 {
126 using serializer = typename BasicJsonType::template json_serializer<T, void>;
127
128 static constexpr bool value =
129 is_detected_exact<T, from_json_function, serializer,
130 const BasicJsonType&>::value;
131 };
132
133 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
134 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
135 template<typename BasicJsonType, typename T, typename = void>
136 struct has_to_json : std::false_type {};
137
138 template<typename BasicJsonType, typename T>
139 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
140 {
141 using serializer = typename BasicJsonType::template json_serializer<T, void>;
142
143 static constexpr bool value =
144 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
145 T>::value;
146 };
147
148
149 ///////////////////
150 // is_ functions //
151 ///////////////////
152
153 // https://en.cppreference.com/w/cpp/types/conjunction
154 template<class...> struct conjunction : std::true_type { };
155 template<class B1> struct conjunction<B1> : B1 { };
156 template<class B1, class... Bn>
157 struct conjunction<B1, Bn...>
158 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
159
160 // https://en.cppreference.com/w/cpp/types/negation
161 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
162
163 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
164 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
165 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
166 template <typename T>
167 struct is_default_constructible : std::is_default_constructible<T> {};
168
169 template <typename T1, typename T2>
170 struct is_default_constructible<std::pair<T1, T2>>
171 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
172
173 template <typename T1, typename T2>
174 struct is_default_constructible<const std::pair<T1, T2>>
175 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
176
177 template <typename... Ts>
178 struct is_default_constructible<std::tuple<Ts...>>
179 : conjunction<is_default_constructible<Ts>...> {};
180
181 template <typename... Ts>
182 struct is_default_constructible<const std::tuple<Ts...>>
183 : conjunction<is_default_constructible<Ts>...> {};
184
185
186 template <typename T, typename... Args>
187 struct is_constructible : std::is_constructible<T, Args...> {};
188
189 template <typename T1, typename T2>
190 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
191
192 template <typename T1, typename T2>
193 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
194
195 template <typename... Ts>
196 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
197
198 template <typename... Ts>
199 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
200
201
202 template<typename T, typename = void>
203 struct is_iterator_traits : std::false_type {};
204
205 template<typename T>
206 struct is_iterator_traits<iterator_traits<T>>
207 {
208 private:
209 using traits = iterator_traits<T>;
210
211 public:
212 static constexpr auto value =
213 is_detected<value_type_t, traits>::value &&
214 is_detected<difference_type_t, traits>::value &&
215 is_detected<pointer_t, traits>::value &&
216 is_detected<iterator_category_t, traits>::value &&
217 is_detected<reference_t, traits>::value;
218 };
219
220 template<typename T>
221 struct is_range
222 {
223 private:
224 using t_ref = typename std::add_lvalue_reference<T>::type;
225
226 using iterator = detected_t<result_of_begin, t_ref>;
227 using sentinel = detected_t<result_of_end, t_ref>;
228
229 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
230 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
231 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
232 static constexpr auto is_iterator_begin =
233 is_iterator_traits<iterator_traits<iterator>>::value;
234
235 public:
236 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
237 };
238
239 template<typename R>
240 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
241
242 template<typename T>
243 using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;
244
245 // The following implementation of is_complete_type is taken from
246 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
247 // and is written by Xiang Fan who agreed to using it in this library.
248
249 template<typename T, typename = void>
250 struct is_complete_type : std::false_type {};
251
252 template<typename T>
253 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
254
255 template<typename BasicJsonType, typename CompatibleObjectType,
256 typename = void>
257 struct is_compatible_object_type_impl : std::false_type {};
258
259 template<typename BasicJsonType, typename CompatibleObjectType>
260 struct is_compatible_object_type_impl <
261 BasicJsonType, CompatibleObjectType,
262 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
263 is_detected<key_type_t, CompatibleObjectType>::value >>
264 {
265 using object_t = typename BasicJsonType::object_t;
266
267 // macOS's is_constructible does not play well with nonesuch...
268 static constexpr bool value =
269 is_constructible<typename object_t::key_type,
270 typename CompatibleObjectType::key_type>::value &&
271 is_constructible<typename object_t::mapped_type,
272 typename CompatibleObjectType::mapped_type>::value;
273 };
274
275 template<typename BasicJsonType, typename CompatibleObjectType>
276 struct is_compatible_object_type
277 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
278
279 template<typename BasicJsonType, typename ConstructibleObjectType,
280 typename = void>
281 struct is_constructible_object_type_impl : std::false_type {};
282
283 template<typename BasicJsonType, typename ConstructibleObjectType>
284 struct is_constructible_object_type_impl <
285 BasicJsonType, ConstructibleObjectType,
286 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
287 is_detected<key_type_t, ConstructibleObjectType>::value >>
288 {
289 using object_t = typename BasicJsonType::object_t;
290
291 static constexpr bool value =
292 (is_default_constructible<ConstructibleObjectType>::value &&
293 (std::is_move_assignable<ConstructibleObjectType>::value ||
294 std::is_copy_assignable<ConstructibleObjectType>::value) &&
295 (is_constructible<typename ConstructibleObjectType::key_type,
296 typename object_t::key_type>::value &&
297 std::is_same <
298 typename object_t::mapped_type,
299 typename ConstructibleObjectType::mapped_type >::value)) ||
300 (has_from_json<BasicJsonType,
301 typename ConstructibleObjectType::mapped_type>::value ||
302 has_non_default_from_json <
303 BasicJsonType,
304 typename ConstructibleObjectType::mapped_type >::value);
305 };
306
307 template<typename BasicJsonType, typename ConstructibleObjectType>
308 struct is_constructible_object_type
309 : is_constructible_object_type_impl<BasicJsonType,
310 ConstructibleObjectType> {};
311
312 template<typename BasicJsonType, typename CompatibleStringType>
313 struct is_compatible_string_type
314 {
315 static constexpr auto value =
316 is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
317 };
318
319 template<typename BasicJsonType, typename ConstructibleStringType>
320 struct is_constructible_string_type
321 {
322 static constexpr auto value =
323 is_constructible<ConstructibleStringType,
324 typename BasicJsonType::string_t>::value;
325 };
326
327 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
328 struct is_compatible_array_type_impl : std::false_type {};
329
330 template<typename BasicJsonType, typename CompatibleArrayType>
331 struct is_compatible_array_type_impl <
332 BasicJsonType, CompatibleArrayType,
333 enable_if_t <
334 is_detected<iterator_t, CompatibleArrayType>::value&&
335 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
336 // special case for types like std::filesystem::path whose iterator's value_type are themselves
337 // c.f. https://github.com/nlohmann/json/pull/3073
338 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
339 {
340 static constexpr bool value =
341 is_constructible<BasicJsonType,
342 range_value_t<CompatibleArrayType>>::value;
343 };
344
345 template<typename BasicJsonType, typename CompatibleArrayType>
346 struct is_compatible_array_type
347 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
348
349 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
350 struct is_constructible_array_type_impl : std::false_type {};
351
352 template<typename BasicJsonType, typename ConstructibleArrayType>
353 struct is_constructible_array_type_impl <
354 BasicJsonType, ConstructibleArrayType,
355 enable_if_t<std::is_same<ConstructibleArrayType,
356 typename BasicJsonType::value_type>::value >>
357 : std::true_type {};
358
359 template<typename BasicJsonType, typename ConstructibleArrayType>
360 struct is_constructible_array_type_impl <
361 BasicJsonType, ConstructibleArrayType,
362 enable_if_t < !std::is_same<ConstructibleArrayType,
363 typename BasicJsonType::value_type>::value&&
364 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
365 is_default_constructible<ConstructibleArrayType>::value&&
366 (std::is_move_assignable<ConstructibleArrayType>::value ||
367 std::is_copy_assignable<ConstructibleArrayType>::value)&&
368 is_detected<iterator_t, ConstructibleArrayType>::value&&
369 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
370 is_detected<range_value_t, ConstructibleArrayType>::value&&
371 // special case for types like std::filesystem::path whose iterator's value_type are themselves
372 // c.f. https://github.com/nlohmann/json/pull/3073
373 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
374 is_complete_type <
375 detected_t<range_value_t, ConstructibleArrayType >>::value >>
376 {
377 using value_type = range_value_t<ConstructibleArrayType>;
378
379 static constexpr bool value =
380 std::is_same<value_type,
381 typename BasicJsonType::array_t::value_type>::value ||
382 has_from_json<BasicJsonType,
383 value_type>::value ||
384 has_non_default_from_json <
385 BasicJsonType,
386 value_type >::value;
387 };
388
389 template<typename BasicJsonType, typename ConstructibleArrayType>
390 struct is_constructible_array_type
391 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
392
393 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
394 typename = void>
395 struct is_compatible_integer_type_impl : std::false_type {};
396
397 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
398 struct is_compatible_integer_type_impl <
399 RealIntegerType, CompatibleNumberIntegerType,
400 enable_if_t < std::is_integral<RealIntegerType>::value&&
401 std::is_integral<CompatibleNumberIntegerType>::value&&
402 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
403 {
404 // is there an assert somewhere on overflows?
405 using RealLimits = std::numeric_limits<RealIntegerType>;
406 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
407
408 static constexpr auto value =
409 is_constructible<RealIntegerType,
410 CompatibleNumberIntegerType>::value &&
411 CompatibleLimits::is_integer &&
412 RealLimits::is_signed == CompatibleLimits::is_signed;
413 };
414
415 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
416 struct is_compatible_integer_type
417 : is_compatible_integer_type_impl<RealIntegerType,
418 CompatibleNumberIntegerType> {};
419
420 template<typename BasicJsonType, typename CompatibleType, typename = void>
421 struct is_compatible_type_impl: std::false_type {};
422
423 template<typename BasicJsonType, typename CompatibleType>
424 struct is_compatible_type_impl <
425 BasicJsonType, CompatibleType,
426 enable_if_t<is_complete_type<CompatibleType>::value >>
427 {
428 static constexpr bool value =
429 has_to_json<BasicJsonType, CompatibleType>::value;
430 };
431
432 template<typename BasicJsonType, typename CompatibleType>
433 struct is_compatible_type
434 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
435
436 template<typename T1, typename T2>
437 struct is_constructible_tuple : std::false_type {};
438
439 template<typename T1, typename... Args>
440 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
441
442 // a naive helper to check if a type is an ordered_map (exploits the fact that
443 // ordered_map inherits capacity() from std::vector)
444 template <typename T>
445 struct is_ordered_map
446 {
447 using one = char;
448
449 struct two
450 {
451 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
452 };
453
454 template <typename C> static one test( decltype(&C::capacity) ) ;
455 template <typename C> static two test(...);
456
457 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
458 };
459
460 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
461 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
462 T conditional_static_cast(U value)
463 {
464 return static_cast<T>(value);
465 }
466
467 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
468 T conditional_static_cast(U value)
469 {
470 return value;
471 }
472
473 } // namespace detail
474 } // namespace nlohmann