Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:03:23

0001 //     __ _____ _____ _____
0002 //  __|  |   __|     |   | |  JSON for Modern C++
0003 // |  |  |__   |  |  | | | |  version 3.11.3
0004 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
0005 //
0006 // SPDX-FileCopyrightText: 2013-2023 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 #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 @brief detail namespace with internal helper functions
0028 
0029 This namespace collects functions that should not be exposed,
0030 implementations of some @ref basic_json methods, and meta-programming helpers.
0031 
0032 @since version 2.1.0
0033 */
0034 namespace detail
0035 {
0036 
0037 /////////////
0038 // helpers //
0039 /////////////
0040 
0041 // Note to maintainers:
0042 //
0043 // Every trait in this file expects a non CV-qualified type.
0044 // The only exceptions are in the 'aliases for detected' section
0045 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
0046 //
0047 // In this case, T has to be properly CV-qualified to constraint the function arguments
0048 // (e.g. to_json(BasicJsonType&, const T&))
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 // used by exceptions create() member functions
0056 // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
0057 // false_type otherwise
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 // json_ref helpers //
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 // aliases for detected //
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 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
0113 template<typename BasicJsonType, typename T, typename = void>
0114 struct has_from_json : std::false_type {};
0115 
0116 // trait checking if j.get<T> is valid
0117 // use this trait instead of std::is_constructible or std::is_convertible,
0118 // both rely on, or make use of implicit conversions, and thus fail when T
0119 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
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 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
0137 // this overload is used for non-default-constructible user-defined-types
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 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
0152 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
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 // obtains the actual object key comparator
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 // char_traits //
0187 /////////////////
0188 
0189 // Primary template of char_traits calls std char_traits
0190 template<typename T>
0191 struct char_traits : std::char_traits<T>
0192 {};
0193 
0194 // Explicitly define char traits for unsigned char since it is not standard
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     // Redefine to_int_type function
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 // Explicitly define char traits for signed char since it is not standard
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     // Redefine to_int_type function
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 // is_ functions //
0244 ///////////////////
0245 
0246 // https://en.cppreference.com/w/cpp/types/conjunction
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 // https://en.cppreference.com/w/cpp/types/negation
0254 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
0255 
0256 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
0257 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
0258 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
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     // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
0321     // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
0322     // but reimplementing these would be too much work, as a lot of other concepts are used underneath
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 // The following implementation of is_complete_type is taken from
0337 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
0338 // and is written by Xiang Fan who agreed to using it in this library.
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     // macOS's is_constructible does not play well with nonesuch...
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     // launder type through decltype() to fix compilation failure on ICPC
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 // special case for types like std::filesystem::path whose iterator's value_type are themselves
0437 // c.f. https://github.com/nlohmann/json/pull/3073
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 // special case for types like std::filesystem::path whose iterator's value_type are themselves
0472 // c.f. https://github.com/nlohmann/json/pull/3073
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     // is there an assert somewhere on overflows?
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 // checks if a given type T is a template specialization of Primary
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 // checks if A and B are comparable using Compare functor
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 // type trait to check if KeyType can be used as object key (without a BasicJsonType)
0576 // see is_usable_as_basic_json_key_type below
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 // type trait to check if KeyType can be used as object key
0590 // true if:
0591 //   - KeyType is comparable with BasicJsonType::object_t::key_type
0592 //   - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
0593 //   - the comparator is transparent or RequireTransparentComparator is false
0594 //   - KeyType is not a JSON iterator or json_pointer
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 // type trait to check if object_t has an erase() member functions accepting KeyType
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 // a naive helper to check if a type is an ordered_map (exploits the fact that
0618 // ordered_map inherits capacity() from std::vector)
0619 template <typename T>
0620 struct is_ordered_map
0621 {
0622     using one = char;
0623 
0624     struct two
0625     {
0626         char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
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) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
0633 };
0634 
0635 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
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 // there's a disjunction trait in another PR; replace when merged
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 /*val*/)
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 // is_c_string
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 }  // namespace impl
0765 
0766 // checks whether T is a [cv] char */[cv] char[] C string
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 // is_transparent
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 }  // namespace impl
0787 
0788 // checks whether T has a member named is_transparent
0789 template<typename T>
0790 struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
0791 
0792 ///////////////////////////////////////////////////////////////////////////////
0793 
0794 }  // namespace detail
0795 NLOHMANN_JSON_NAMESPACE_END