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