File indexing completed on 2025-09-17 09:03:23
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <limits> // numeric_limits
0012 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
0013 #include <utility> // declval
0014 #include <tuple> // tuple
0015 #include <string> // char_traits
0016
0017 #include <nlohmann/detail/iterators/iterator_traits.hpp>
0018 #include <nlohmann/detail/macro_scope.hpp>
0019 #include <nlohmann/detail/meta/call_std/begin.hpp>
0020 #include <nlohmann/detail/meta/call_std/end.hpp>
0021 #include <nlohmann/detail/meta/cpp_future.hpp>
0022 #include <nlohmann/detail/meta/detected.hpp>
0023 #include <nlohmann/json_fwd.hpp>
0024
0025 NLOHMANN_JSON_NAMESPACE_BEGIN
0026
0027
0028
0029
0030
0031
0032
0033
0034 namespace detail
0035 {
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 template<typename> struct is_basic_json : std::false_type {};
0051
0052 NLOHMANN_BASIC_JSON_TPL_DECLARATION
0053 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
0054
0055
0056
0057
0058 template<typename BasicJsonContext>
0059 struct is_basic_json_context :
0060 std::integral_constant < bool,
0061 is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
0062 || std::is_same<BasicJsonContext, std::nullptr_t>::value >
0063 {};
0064
0065
0066
0067
0068
0069 template<typename>
0070 class json_ref;
0071
0072 template<typename>
0073 struct is_json_ref : std::false_type {};
0074
0075 template<typename T>
0076 struct is_json_ref<json_ref<T>> : std::true_type {};
0077
0078
0079
0080
0081
0082 template<typename T>
0083 using mapped_type_t = typename T::mapped_type;
0084
0085 template<typename T>
0086 using key_type_t = typename T::key_type;
0087
0088 template<typename T>
0089 using value_type_t = typename T::value_type;
0090
0091 template<typename T>
0092 using difference_type_t = typename T::difference_type;
0093
0094 template<typename T>
0095 using pointer_t = typename T::pointer;
0096
0097 template<typename T>
0098 using reference_t = typename T::reference;
0099
0100 template<typename T>
0101 using iterator_category_t = typename T::iterator_category;
0102
0103 template<typename T, typename... Args>
0104 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
0105
0106 template<typename T, typename... Args>
0107 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
0108
0109 template<typename T, typename U>
0110 using get_template_function = decltype(std::declval<T>().template get<U>());
0111
0112
0113 template<typename BasicJsonType, typename T, typename = void>
0114 struct has_from_json : std::false_type {};
0115
0116
0117
0118
0119
0120 template <typename BasicJsonType, typename T>
0121 struct is_getable
0122 {
0123 static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
0124 };
0125
0126 template<typename BasicJsonType, typename T>
0127 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
0128 {
0129 using serializer = typename BasicJsonType::template json_serializer<T, void>;
0130
0131 static constexpr bool value =
0132 is_detected_exact<void, from_json_function, serializer,
0133 const BasicJsonType&, T&>::value;
0134 };
0135
0136
0137
0138 template<typename BasicJsonType, typename T, typename = void>
0139 struct has_non_default_from_json : std::false_type {};
0140
0141 template<typename BasicJsonType, typename T>
0142 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
0143 {
0144 using serializer = typename BasicJsonType::template json_serializer<T, void>;
0145
0146 static constexpr bool value =
0147 is_detected_exact<T, from_json_function, serializer,
0148 const BasicJsonType&>::value;
0149 };
0150
0151
0152
0153 template<typename BasicJsonType, typename T, typename = void>
0154 struct has_to_json : std::false_type {};
0155
0156 template<typename BasicJsonType, typename T>
0157 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
0158 {
0159 using serializer = typename BasicJsonType::template json_serializer<T, void>;
0160
0161 static constexpr bool value =
0162 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
0163 T>::value;
0164 };
0165
0166 template<typename T>
0167 using detect_key_compare = typename T::key_compare;
0168
0169 template<typename T>
0170 struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
0171
0172
0173 template<typename BasicJsonType>
0174 struct actual_object_comparator
0175 {
0176 using object_t = typename BasicJsonType::object_t;
0177 using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
0178 using type = typename std::conditional < has_key_compare<object_t>::value,
0179 typename object_t::key_compare, object_comparator_t>::type;
0180 };
0181
0182 template<typename BasicJsonType>
0183 using actual_object_comparator_t = typename actual_object_comparator<BasicJsonType>::type;
0184
0185
0186
0187
0188
0189
0190 template<typename T>
0191 struct char_traits : std::char_traits<T>
0192 {};
0193
0194
0195 template<>
0196 struct char_traits<unsigned char> : std::char_traits<char>
0197 {
0198 using char_type = unsigned char;
0199 using int_type = uint64_t;
0200
0201
0202 static int_type to_int_type(char_type c) noexcept
0203 {
0204 return static_cast<int_type>(c);
0205 }
0206
0207 static char_type to_char_type(int_type i) noexcept
0208 {
0209 return static_cast<char_type>(i);
0210 }
0211
0212 static constexpr int_type eof() noexcept
0213 {
0214 return static_cast<int_type>(EOF);
0215 }
0216 };
0217
0218
0219 template<>
0220 struct char_traits<signed char> : std::char_traits<char>
0221 {
0222 using char_type = signed char;
0223 using int_type = uint64_t;
0224
0225
0226 static int_type to_int_type(char_type c) noexcept
0227 {
0228 return static_cast<int_type>(c);
0229 }
0230
0231 static char_type to_char_type(int_type i) noexcept
0232 {
0233 return static_cast<char_type>(i);
0234 }
0235
0236 static constexpr int_type eof() noexcept
0237 {
0238 return static_cast<int_type>(EOF);
0239 }
0240 };
0241
0242
0243
0244
0245
0246
0247 template<class...> struct conjunction : std::true_type { };
0248 template<class B> struct conjunction<B> : B { };
0249 template<class B, class... Bn>
0250 struct conjunction<B, Bn...>
0251 : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
0252
0253
0254 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
0255
0256
0257
0258
0259 template <typename T>
0260 struct is_default_constructible : std::is_default_constructible<T> {};
0261
0262 template <typename T1, typename T2>
0263 struct is_default_constructible<std::pair<T1, T2>>
0264 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
0265
0266 template <typename T1, typename T2>
0267 struct is_default_constructible<const std::pair<T1, T2>>
0268 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
0269
0270 template <typename... Ts>
0271 struct is_default_constructible<std::tuple<Ts...>>
0272 : conjunction<is_default_constructible<Ts>...> {};
0273
0274 template <typename... Ts>
0275 struct is_default_constructible<const std::tuple<Ts...>>
0276 : conjunction<is_default_constructible<Ts>...> {};
0277
0278 template <typename T, typename... Args>
0279 struct is_constructible : std::is_constructible<T, Args...> {};
0280
0281 template <typename T1, typename T2>
0282 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
0283
0284 template <typename T1, typename T2>
0285 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
0286
0287 template <typename... Ts>
0288 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
0289
0290 template <typename... Ts>
0291 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
0292
0293 template<typename T, typename = void>
0294 struct is_iterator_traits : std::false_type {};
0295
0296 template<typename T>
0297 struct is_iterator_traits<iterator_traits<T>>
0298 {
0299 private:
0300 using traits = iterator_traits<T>;
0301
0302 public:
0303 static constexpr auto value =
0304 is_detected<value_type_t, traits>::value &&
0305 is_detected<difference_type_t, traits>::value &&
0306 is_detected<pointer_t, traits>::value &&
0307 is_detected<iterator_category_t, traits>::value &&
0308 is_detected<reference_t, traits>::value;
0309 };
0310
0311 template<typename T>
0312 struct is_range
0313 {
0314 private:
0315 using t_ref = typename std::add_lvalue_reference<T>::type;
0316
0317 using iterator = detected_t<result_of_begin, t_ref>;
0318 using sentinel = detected_t<result_of_end, t_ref>;
0319
0320
0321
0322
0323 static constexpr auto is_iterator_begin =
0324 is_iterator_traits<iterator_traits<iterator>>::value;
0325
0326 public:
0327 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
0328 };
0329
0330 template<typename R>
0331 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
0332
0333 template<typename T>
0334 using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;
0335
0336
0337
0338
0339
0340 template<typename T, typename = void>
0341 struct is_complete_type : std::false_type {};
0342
0343 template<typename T>
0344 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
0345
0346 template<typename BasicJsonType, typename CompatibleObjectType,
0347 typename = void>
0348 struct is_compatible_object_type_impl : std::false_type {};
0349
0350 template<typename BasicJsonType, typename CompatibleObjectType>
0351 struct is_compatible_object_type_impl <
0352 BasicJsonType, CompatibleObjectType,
0353 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
0354 is_detected<key_type_t, CompatibleObjectType>::value >>
0355 {
0356 using object_t = typename BasicJsonType::object_t;
0357
0358
0359 static constexpr bool value =
0360 is_constructible<typename object_t::key_type,
0361 typename CompatibleObjectType::key_type>::value &&
0362 is_constructible<typename object_t::mapped_type,
0363 typename CompatibleObjectType::mapped_type>::value;
0364 };
0365
0366 template<typename BasicJsonType, typename CompatibleObjectType>
0367 struct is_compatible_object_type
0368 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
0369
0370 template<typename BasicJsonType, typename ConstructibleObjectType,
0371 typename = void>
0372 struct is_constructible_object_type_impl : std::false_type {};
0373
0374 template<typename BasicJsonType, typename ConstructibleObjectType>
0375 struct is_constructible_object_type_impl <
0376 BasicJsonType, ConstructibleObjectType,
0377 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
0378 is_detected<key_type_t, ConstructibleObjectType>::value >>
0379 {
0380 using object_t = typename BasicJsonType::object_t;
0381
0382 static constexpr bool value =
0383 (is_default_constructible<ConstructibleObjectType>::value &&
0384 (std::is_move_assignable<ConstructibleObjectType>::value ||
0385 std::is_copy_assignable<ConstructibleObjectType>::value) &&
0386 (is_constructible<typename ConstructibleObjectType::key_type,
0387 typename object_t::key_type>::value &&
0388 std::is_same <
0389 typename object_t::mapped_type,
0390 typename ConstructibleObjectType::mapped_type >::value)) ||
0391 (has_from_json<BasicJsonType,
0392 typename ConstructibleObjectType::mapped_type>::value ||
0393 has_non_default_from_json <
0394 BasicJsonType,
0395 typename ConstructibleObjectType::mapped_type >::value);
0396 };
0397
0398 template<typename BasicJsonType, typename ConstructibleObjectType>
0399 struct is_constructible_object_type
0400 : is_constructible_object_type_impl<BasicJsonType,
0401 ConstructibleObjectType> {};
0402
0403 template<typename BasicJsonType, typename CompatibleStringType>
0404 struct is_compatible_string_type
0405 {
0406 static constexpr auto value =
0407 is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
0408 };
0409
0410 template<typename BasicJsonType, typename ConstructibleStringType>
0411 struct is_constructible_string_type
0412 {
0413
0414 #ifdef __INTEL_COMPILER
0415 using laundered_type = decltype(std::declval<ConstructibleStringType>());
0416 #else
0417 using laundered_type = ConstructibleStringType;
0418 #endif
0419
0420 static constexpr auto value =
0421 conjunction <
0422 is_constructible<laundered_type, typename BasicJsonType::string_t>,
0423 is_detected_exact<typename BasicJsonType::string_t::value_type,
0424 value_type_t, laundered_type >>::value;
0425 };
0426
0427 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
0428 struct is_compatible_array_type_impl : std::false_type {};
0429
0430 template<typename BasicJsonType, typename CompatibleArrayType>
0431 struct is_compatible_array_type_impl <
0432 BasicJsonType, CompatibleArrayType,
0433 enable_if_t <
0434 is_detected<iterator_t, CompatibleArrayType>::value&&
0435 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
0436
0437
0438 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
0439 {
0440 static constexpr bool value =
0441 is_constructible<BasicJsonType,
0442 range_value_t<CompatibleArrayType>>::value;
0443 };
0444
0445 template<typename BasicJsonType, typename CompatibleArrayType>
0446 struct is_compatible_array_type
0447 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
0448
0449 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
0450 struct is_constructible_array_type_impl : std::false_type {};
0451
0452 template<typename BasicJsonType, typename ConstructibleArrayType>
0453 struct is_constructible_array_type_impl <
0454 BasicJsonType, ConstructibleArrayType,
0455 enable_if_t<std::is_same<ConstructibleArrayType,
0456 typename BasicJsonType::value_type>::value >>
0457 : std::true_type {};
0458
0459 template<typename BasicJsonType, typename ConstructibleArrayType>
0460 struct is_constructible_array_type_impl <
0461 BasicJsonType, ConstructibleArrayType,
0462 enable_if_t < !std::is_same<ConstructibleArrayType,
0463 typename BasicJsonType::value_type>::value&&
0464 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
0465 is_default_constructible<ConstructibleArrayType>::value&&
0466 (std::is_move_assignable<ConstructibleArrayType>::value ||
0467 std::is_copy_assignable<ConstructibleArrayType>::value)&&
0468 is_detected<iterator_t, ConstructibleArrayType>::value&&
0469 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
0470 is_detected<range_value_t, ConstructibleArrayType>::value&&
0471
0472
0473 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
0474 is_complete_type <
0475 detected_t<range_value_t, ConstructibleArrayType >>::value >>
0476 {
0477 using value_type = range_value_t<ConstructibleArrayType>;
0478
0479 static constexpr bool value =
0480 std::is_same<value_type,
0481 typename BasicJsonType::array_t::value_type>::value ||
0482 has_from_json<BasicJsonType,
0483 value_type>::value ||
0484 has_non_default_from_json <
0485 BasicJsonType,
0486 value_type >::value;
0487 };
0488
0489 template<typename BasicJsonType, typename ConstructibleArrayType>
0490 struct is_constructible_array_type
0491 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
0492
0493 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
0494 typename = void>
0495 struct is_compatible_integer_type_impl : std::false_type {};
0496
0497 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
0498 struct is_compatible_integer_type_impl <
0499 RealIntegerType, CompatibleNumberIntegerType,
0500 enable_if_t < std::is_integral<RealIntegerType>::value&&
0501 std::is_integral<CompatibleNumberIntegerType>::value&&
0502 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
0503 {
0504
0505 using RealLimits = std::numeric_limits<RealIntegerType>;
0506 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
0507
0508 static constexpr auto value =
0509 is_constructible<RealIntegerType,
0510 CompatibleNumberIntegerType>::value &&
0511 CompatibleLimits::is_integer &&
0512 RealLimits::is_signed == CompatibleLimits::is_signed;
0513 };
0514
0515 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
0516 struct is_compatible_integer_type
0517 : is_compatible_integer_type_impl<RealIntegerType,
0518 CompatibleNumberIntegerType> {};
0519
0520 template<typename BasicJsonType, typename CompatibleType, typename = void>
0521 struct is_compatible_type_impl: std::false_type {};
0522
0523 template<typename BasicJsonType, typename CompatibleType>
0524 struct is_compatible_type_impl <
0525 BasicJsonType, CompatibleType,
0526 enable_if_t<is_complete_type<CompatibleType>::value >>
0527 {
0528 static constexpr bool value =
0529 has_to_json<BasicJsonType, CompatibleType>::value;
0530 };
0531
0532 template<typename BasicJsonType, typename CompatibleType>
0533 struct is_compatible_type
0534 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
0535
0536 template<typename T1, typename T2>
0537 struct is_constructible_tuple : std::false_type {};
0538
0539 template<typename T1, typename... Args>
0540 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
0541
0542 template<typename BasicJsonType, typename T>
0543 struct is_json_iterator_of : std::false_type {};
0544
0545 template<typename BasicJsonType>
0546 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
0547
0548 template<typename BasicJsonType>
0549 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
0550 {};
0551
0552
0553 template<template <typename...> class Primary, typename T>
0554 struct is_specialization_of : std::false_type {};
0555
0556 template<template <typename...> class Primary, typename... Args>
0557 struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
0558
0559 template<typename T>
0560 using is_json_pointer = is_specialization_of<::nlohmann::json_pointer, uncvref_t<T>>;
0561
0562
0563 template<typename Compare, typename A, typename B, typename = void>
0564 struct is_comparable : std::false_type {};
0565
0566 template<typename Compare, typename A, typename B>
0567 struct is_comparable<Compare, A, B, void_t<
0568 decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
0569 decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
0570 >> : std::true_type {};
0571
0572 template<typename T>
0573 using detect_is_transparent = typename T::is_transparent;
0574
0575
0576
0577 template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
0578 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
0579 using is_usable_as_key_type = typename std::conditional <
0580 is_comparable<Comparator, ObjectKeyType, KeyTypeCVRef>::value
0581 && !(ExcludeObjectKeyType && std::is_same<KeyType,
0582 ObjectKeyType>::value)
0583 && (!RequireTransparentComparator
0584 || is_detected <detect_is_transparent, Comparator>::value)
0585 && !is_json_pointer<KeyType>::value,
0586 std::true_type,
0587 std::false_type >::type;
0588
0589
0590
0591
0592
0593
0594
0595 template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
0596 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
0597 using is_usable_as_basic_json_key_type = typename std::conditional <
0598 is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
0599 typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
0600 RequireTransparentComparator, ExcludeObjectKeyType>::value
0601 && !is_json_iterator_of<BasicJsonType, KeyType>::value,
0602 std::true_type,
0603 std::false_type >::type;
0604
0605 template<typename ObjectType, typename KeyType>
0606 using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
0607
0608
0609 template<typename BasicJsonType, typename KeyType>
0610 using has_erase_with_key_type = typename std::conditional <
0611 is_detected <
0612 detect_erase_with_key_type,
0613 typename BasicJsonType::object_t, KeyType >::value,
0614 std::true_type,
0615 std::false_type >::type;
0616
0617
0618
0619 template <typename T>
0620 struct is_ordered_map
0621 {
0622 using one = char;
0623
0624 struct two
0625 {
0626 char x[2];
0627 };
0628
0629 template <typename C> static one test( decltype(&C::capacity) ) ;
0630 template <typename C> static two test(...);
0631
0632 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) };
0633 };
0634
0635
0636 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
0637 T conditional_static_cast(U value)
0638 {
0639 return static_cast<T>(value);
0640 }
0641
0642 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
0643 T conditional_static_cast(U value)
0644 {
0645 return value;
0646 }
0647
0648 template<typename... Types>
0649 using all_integral = conjunction<std::is_integral<Types>...>;
0650
0651 template<typename... Types>
0652 using all_signed = conjunction<std::is_signed<Types>...>;
0653
0654 template<typename... Types>
0655 using all_unsigned = conjunction<std::is_unsigned<Types>...>;
0656
0657
0658 template<typename... Types>
0659 using same_sign = std::integral_constant < bool,
0660 all_signed<Types...>::value || all_unsigned<Types...>::value >;
0661
0662 template<typename OfType, typename T>
0663 using never_out_of_range = std::integral_constant < bool,
0664 (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
0665 || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
0666
0667 template<typename OfType, typename T,
0668 bool OfTypeSigned = std::is_signed<OfType>::value,
0669 bool TSigned = std::is_signed<T>::value>
0670 struct value_in_range_of_impl2;
0671
0672 template<typename OfType, typename T>
0673 struct value_in_range_of_impl2<OfType, T, false, false>
0674 {
0675 static constexpr bool test(T val)
0676 {
0677 using CommonType = typename std::common_type<OfType, T>::type;
0678 return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
0679 }
0680 };
0681
0682 template<typename OfType, typename T>
0683 struct value_in_range_of_impl2<OfType, T, true, false>
0684 {
0685 static constexpr bool test(T val)
0686 {
0687 using CommonType = typename std::common_type<OfType, T>::type;
0688 return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
0689 }
0690 };
0691
0692 template<typename OfType, typename T>
0693 struct value_in_range_of_impl2<OfType, T, false, true>
0694 {
0695 static constexpr bool test(T val)
0696 {
0697 using CommonType = typename std::common_type<OfType, T>::type;
0698 return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
0699 }
0700 };
0701
0702 template<typename OfType, typename T>
0703 struct value_in_range_of_impl2<OfType, T, true, true>
0704 {
0705 static constexpr bool test(T val)
0706 {
0707 using CommonType = typename std::common_type<OfType, T>::type;
0708 return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
0709 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
0710 }
0711 };
0712
0713 template<typename OfType, typename T,
0714 bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
0715 typename = detail::enable_if_t<all_integral<OfType, T>::value>>
0716 struct value_in_range_of_impl1;
0717
0718 template<typename OfType, typename T>
0719 struct value_in_range_of_impl1<OfType, T, false>
0720 {
0721 static constexpr bool test(T val)
0722 {
0723 return value_in_range_of_impl2<OfType, T>::test(val);
0724 }
0725 };
0726
0727 template<typename OfType, typename T>
0728 struct value_in_range_of_impl1<OfType, T, true>
0729 {
0730 static constexpr bool test(T )
0731 {
0732 return true;
0733 }
0734 };
0735
0736 template<typename OfType, typename T>
0737 inline constexpr bool value_in_range_of(T val)
0738 {
0739 return value_in_range_of_impl1<OfType, T>::test(val);
0740 }
0741
0742 template<bool Value>
0743 using bool_constant = std::integral_constant<bool, Value>;
0744
0745
0746
0747
0748
0749 namespace impl
0750 {
0751
0752 template<typename T>
0753 inline constexpr bool is_c_string()
0754 {
0755 using TUnExt = typename std::remove_extent<T>::type;
0756 using TUnCVExt = typename std::remove_cv<TUnExt>::type;
0757 using TUnPtr = typename std::remove_pointer<T>::type;
0758 using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
0759 return
0760 (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)
0761 || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
0762 }
0763
0764 }
0765
0766
0767 template<typename T>
0768 struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
0769
0770 template<typename T>
0771 using is_c_string_uncvref = is_c_string<uncvref_t<T>>;
0772
0773
0774
0775
0776
0777 namespace impl
0778 {
0779
0780 template<typename T>
0781 inline constexpr bool is_transparent()
0782 {
0783 return is_detected<detect_is_transparent, T>::value;
0784 }
0785
0786 }
0787
0788
0789 template<typename T>
0790 struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
0791
0792
0793
0794 }
0795 NLOHMANN_JSON_NAMESPACE_END