Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:02:19

0001 //     __ _____ _____ _____
0002 //  __|  |   __|     |   | |  JSON for Modern C++
0003 // |  |  |__   |  |  | | | |  version 3.11.2
0004 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0005 //
0006 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
0007 // SPDX-License-Identifier: MIT
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 @brief detail namespace with internal helper functions
0027 
0028 This namespace collects functions that should not be exposed,
0029 implementations of some @ref basic_json methods, and meta-programming helpers.
0030 
0031 @since version 2.1.0
0032 */
0033 namespace detail
0034 {
0035 
0036 /////////////
0037 // helpers //
0038 /////////////
0039 
0040 // Note to maintainers:
0041 //
0042 // Every trait in this file expects a non CV-qualified type.
0043 // The only exceptions are in the 'aliases for detected' section
0044 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
0045 //
0046 // In this case, T has to be properly CV-qualified to constraint the function arguments
0047 // (e.g. to_json(BasicJsonType&, const T&))
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 // used by exceptions create() member functions
0055 // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
0056 // false_type otherwise
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 // json_ref helpers //
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 // aliases for detected //
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 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
0112 template<typename BasicJsonType, typename T, typename = void>
0113 struct has_from_json : std::false_type {};
0114 
0115 // trait checking if j.get<T> is valid
0116 // use this trait instead of std::is_constructible or std::is_convertible,
0117 // both rely on, or make use of implicit conversions, and thus fail when T
0118 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
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 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
0136 // this overload is used for non-default-constructible user-defined-types
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 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
0151 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
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 // obtains the actual object key comparator
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 // is_ functions //
0186 ///////////////////
0187 
0188 // https://en.cppreference.com/w/cpp/types/conjunction
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 // https://en.cppreference.com/w/cpp/types/negation
0196 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
0197 
0198 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
0199 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
0200 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
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     // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
0265     // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
0266     // but reimplementing these would be too much work, as a lot of other concepts are used underneath
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 // The following implementation of is_complete_type is taken from
0281 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
0282 // and is written by Xiang Fan who agreed to using it in this library.
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     // macOS's is_constructible does not play well with nonesuch...
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     // launder type through decltype() to fix compilation failure on ICPC
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 // special case for types like std::filesystem::path whose iterator's value_type are themselves
0381 // c.f. https://github.com/nlohmann/json/pull/3073
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 // special case for types like std::filesystem::path whose iterator's value_type are themselves
0416 // c.f. https://github.com/nlohmann/json/pull/3073
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     // is there an assert somewhere on overflows?
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 // checks if a given type T is a template specialization of Primary
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 // checks if A and B are comparable using Compare functor
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 // type trait to check if KeyType can be used as object key (without a BasicJsonType)
0520 // see is_usable_as_basic_json_key_type below
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 // type trait to check if KeyType can be used as object key
0534 // true if:
0535 //   - KeyType is comparable with BasicJsonType::object_t::key_type
0536 //   - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
0537 //   - the comparator is transparent or RequireTransparentComparator is false
0538 //   - KeyType is not a JSON iterator or json_pointer
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 // type trait to check if object_t has an erase() member functions accepting KeyType
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 // a naive helper to check if a type is an ordered_map (exploits the fact that
0562 // ordered_map inherits capacity() from std::vector)
0563 template <typename T>
0564 struct is_ordered_map
0565 {
0566     using one = char;
0567 
0568     struct two
0569     {
0570         char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
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) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
0577 };
0578 
0579 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
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 // there's a disjunction trait in another PR; replace when merged
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 /*val*/)
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 // is_c_string
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 }  // namespace impl
0710 
0711 // checks whether T is a [cv] char */[cv] char[] C string
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 // is_transparent
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 }  // namespace impl
0732 
0733 // checks whether T has a member named is_transparent
0734 template<typename T>
0735 struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
0736 
0737 ///////////////////////////////////////////////////////////////////////////////
0738 
0739 }  // namespace detail
0740 NLOHMANN_JSON_NAMESPACE_END