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 | |
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 |
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 = {._M_elems: { |
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__) |
111 | inline bool operator<(const value_t lhs, const value_t rhs) noexcept |
112 | { |
113 | return std::is_lt(cmp: lhs <=> rhs); // *NOPAD* |
114 | } |
115 | #endif |
116 | |
117 | } // namespace detail |
118 | NLOHMANN_JSON_NAMESPACE_END |
119 | |