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