value_t.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // __ _____ _____ _____
  2. // __| | __| | | | JSON for Modern C++
  3. // | | |__ | | | | | | version 3.11.3
  4. // |_____|_____|_____|_|___| https://github.com/nlohmann/json
  5. //
  6. // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
  7. // SPDX-License-Identifier: MIT
  8. #pragma once
  9. #include <array> // array
  10. #include <cstddef> // size_t
  11. #include <cstdint> // uint8_t
  12. #include <string> // string
  13. #include <nlohmann/detail/macro_scope.hpp>
  14. #if JSON_HAS_THREE_WAY_COMPARISON
  15. #include <compare> // partial_ordering
  16. #endif
  17. NLOHMANN_JSON_NAMESPACE_BEGIN
  18. namespace detail
  19. {
  20. ///////////////////////////
  21. // JSON type enumeration //
  22. ///////////////////////////
  23. /*!
  24. @brief the JSON type enumeration
  25. This enumeration collects the different JSON types. It is internally used to
  26. distinguish the stored values, and the functions @ref basic_json::is_null(),
  27. @ref basic_json::is_object(), @ref basic_json::is_array(),
  28. @ref basic_json::is_string(), @ref basic_json::is_boolean(),
  29. @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
  30. @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
  31. @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
  32. @ref basic_json::is_structured() rely on it.
  33. @note There are three enumeration entries (number_integer, number_unsigned, and
  34. number_float), because the library distinguishes these three types for numbers:
  35. @ref basic_json::number_unsigned_t is used for unsigned integers,
  36. @ref basic_json::number_integer_t is used for signed integers, and
  37. @ref basic_json::number_float_t is used for floating-point numbers or to
  38. approximate integers which do not fit in the limits of their respective type.
  39. @sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON
  40. value with the default value for a given type
  41. @since version 1.0.0
  42. */
  43. enum class value_t : std::uint8_t
  44. {
  45. null, ///< null value
  46. object, ///< object (unordered set of name/value pairs)
  47. array, ///< array (ordered collection of values)
  48. string, ///< string value
  49. boolean, ///< boolean value
  50. number_integer, ///< number value (signed integer)
  51. number_unsigned, ///< number value (unsigned integer)
  52. number_float, ///< number value (floating-point)
  53. binary, ///< binary array (ordered collection of bytes)
  54. discarded ///< discarded by the parser callback function
  55. };
  56. /*!
  57. @brief comparison operator for JSON types
  58. Returns an ordering that is similar to Python:
  59. - order: null < boolean < number < object < array < string < binary
  60. - furthermore, each type is not smaller than itself
  61. - discarded values are not comparable
  62. - binary is represented as a b"" string in python and directly comparable to a
  63. string; however, making a binary array directly comparable with a string would
  64. be surprising behavior in a JSON file.
  65. @since version 1.0.0
  66. */
  67. #if JSON_HAS_THREE_WAY_COMPARISON
  68. inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
  69. #else
  70. inline bool operator<(const value_t lhs, const value_t rhs) noexcept
  71. #endif
  72. {
  73. static constexpr std::array<std::uint8_t, 9> order = {{
  74. 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
  75. 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
  76. 6 /* binary */
  77. }
  78. };
  79. const auto l_index = static_cast<std::size_t>(lhs);
  80. const auto r_index = static_cast<std::size_t>(rhs);
  81. #if JSON_HAS_THREE_WAY_COMPARISON
  82. if (l_index < order.size() && r_index < order.size())
  83. {
  84. return order[l_index] <=> order[r_index]; // *NOPAD*
  85. }
  86. return std::partial_ordering::unordered;
  87. #else
  88. return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
  89. #endif
  90. }
  91. // GCC selects the built-in operator< over an operator rewritten from
  92. // a user-defined spaceship operator
  93. // Clang, MSVC, and ICC select the rewritten candidate
  94. // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
  95. #if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
  96. inline bool operator<(const value_t lhs, const value_t rhs) noexcept
  97. {
  98. return std::is_lt(lhs <=> rhs); // *NOPAD*
  99. }
  100. #endif
  101. } // namespace detail
  102. NLOHMANN_JSON_NAMESPACE_END