Skip to content

Commit 7da544b

Browse files
committedFeb 1, 2023
Added support for null value

File tree

5 files changed

+39
-6
lines changed

5 files changed

+39
-6
lines changed
 

‎examples/test.json

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"title": "example glossary",
44
"GlossDiv": {
55
"title": "S",
6+
"subtitle": null,
67
"GlossList": {
78
"GlossEntry": {
89
"ID": "SGML",

‎include/json2cpp/json2cpp.hpp

+14-2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ template<typename CharType> struct data_variant
8888
std::uint64_t uint64_t_;
8989
double double_;
9090
std::basic_string_view<CharType> string_view_;
91+
std::nullptr_t null_;
9192

9293
constexpr explicit value_t() : empty_{} {}
9394
constexpr explicit value_t(monostate) : value_t() {}
@@ -99,9 +100,10 @@ template<typename CharType> struct data_variant
99100
constexpr explicit value_t(std::uint64_t i) : uint64_t_{ i } {}
100101
constexpr explicit value_t(double d) : double_{ d } {}
101102
constexpr explicit value_t(std::basic_string_view<CharType> s) : string_view_{ s } {}
103+
constexpr explicit value_t(std::nullptr_t) : null_{} {}
102104
};
103105

104-
enum struct selected_type { empty, boolean, binary, array, object, integer, uinteger, floating_point, string };
106+
enum struct selected_type { empty, boolean, binary, array, object, integer, uinteger, floating_point, string, nullish };
105107

106108
value_t value{ monostate{} };
107109
selected_type selected{ selected_type::empty };
@@ -125,6 +127,8 @@ template<typename CharType> struct data_variant
125127
constexpr data_variant(double d) : value{ d }, selected{ selected_type::floating_point } {}
126128
// cppcheck-suppress noExplicitConstructor
127129
constexpr data_variant(std::basic_string_view<CharType> s) : value{ s }, selected{ selected_type::string } {}
130+
// cppcheck-suppress noExplicitConstructor
131+
constexpr data_variant(std::nullptr_t) : value{ nullptr }, selected{ selected_type::nullish } {}
128132

129133
[[nodiscard]] constexpr bool is_boolean() const noexcept { return selected == selected_type::boolean; }
130134

@@ -204,6 +208,8 @@ template<typename CharType> struct data_variant
204208
return nullptr;
205209
}
206210
}
211+
212+
[[nodiscard]] constexpr bool is_null() const noexcept { return selected == selected_type::nullish; }
207213
};
208214

209215
template<typename CharType> struct basic_json
@@ -435,6 +441,12 @@ template<typename CharType> struct basic_json
435441
} else {
436442
throw std::runtime_error("Unexpected type: bool requested");
437443
}
444+
} else if constexpr (std::is_same_v<Type, std::nullptr_t>) {
445+
if (data.is_null()) {
446+
return nullptr;
447+
} else {
448+
throw std::runtime_error("Unexpected type: null requested");
449+
}
438450
} else {
439451
throw std::runtime_error("Unexpected type for get()");
440452
}
@@ -447,7 +459,7 @@ template<typename CharType> struct basic_json
447459
[[nodiscard]] constexpr bool is_structured() const noexcept { return is_object() || is_array(); }
448460
[[nodiscard]] constexpr bool is_number() const noexcept { return is_number_integer() || is_number_float(); }
449461
[[nodiscard]] constexpr bool is_number_integer() const noexcept { return is_number_signed() || is_number_unsigned(); }
450-
[[nodiscard]] constexpr bool is_null() const noexcept { return data.selected == data_t::selected_type::empty; }
462+
[[nodiscard]] constexpr bool is_null() const noexcept { return data.selected == data_t::selected_type::nullish; }
451463
[[nodiscard]] constexpr bool is_binary() const noexcept { return data.selected == data_t::selected_type::binary; }
452464

453465
[[nodiscard]] constexpr bool is_number_signed() const noexcept

‎src/json2cpp.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ std::string compile(const nlohmann::json &value, std::size_t &obj_count, std::ve
7878
return fmt::format("bool{{{}}}", value.get<bool>());
7979
} else if (value.is_string()) {
8080
return fmt::format("string_view{{{}}}", json_string(value.get<std::string>()));
81+
} else if (value.is_null()) {
82+
return "std::nullptr_t{}";
8183
}
8284

8385
return "unhandled";

‎src/schema_validator.cpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ SOFTWARE.
2424

2525
#include <filesystem>
2626
#include <fstream>
27+
#ifdef __GNUC__
28+
#pragma GCC diagnostic push
29+
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
30+
#endif
2731
#include <functional>
32+
#ifdef __GNUC__
33+
#pragma GCC diagnostic pop
34+
#endif
2835
#include <iostream>
2936

3037
#include <docopt/docopt.h>
@@ -140,6 +147,7 @@ template<typename JSON>
140147
void walk_internal(std::int64_t &int_sum,
141148
double &double_sum,
142149
std::size_t &string_sizes,
150+
int &null_count,
143151
int &array_count,
144152
int &object_count,
145153
const JSON &obj)
@@ -150,15 +158,17 @@ void walk_internal(std::int64_t &int_sum,
150158
double_sum += obj.template get<double>();
151159
} else if (obj.is_string()) {
152160
string_sizes += obj.template get<std::string_view>().size();
161+
} else if (obj.is_null()) {
162+
++null_count;
153163
} else if (obj.is_array()) {
154164
++array_count;
155165
for (const auto &child : obj) {
156-
walk_internal(int_sum, double_sum, string_sizes, array_count, object_count, child);
166+
walk_internal(int_sum, double_sum, string_sizes, null_count, array_count, object_count, child);
157167
}
158168
} else if (obj.is_object()) {
159169
++object_count;
160170
for (const auto &child : obj) {
161-
walk_internal(int_sum, double_sum, string_sizes, array_count, object_count, child);
171+
walk_internal(int_sum, double_sum, string_sizes, null_count, array_count, object_count, child);
162172
}
163173
}
164174
}
@@ -168,14 +178,15 @@ template<typename JSON> void walk(const JSON &objects)
168178
std::int64_t int_sum{};
169179
double double_sum{};
170180
std::size_t string_sizes{};
181+
int null_count{};
171182
int array_count{};
172183
int object_count{};
173184

174185
spdlog::info("Starting tree walk");
175186

176-
walk_internal(int_sum, double_sum, string_sizes, array_count, object_count, objects);
187+
walk_internal(int_sum, double_sum, string_sizes, null_count, array_count, object_count, objects);
177188

178-
spdlog::info("{} {} {} {} {}", int_sum, double_sum, string_sizes, array_count, object_count);
189+
spdlog::info("{} {} {} {} {} {}", int_sum, double_sum, string_sizes, null_count, array_count, object_count);
179190
}
180191

181192
int main(int argc, const char **argv)

‎test/valijson_tests.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
#include "allof_integers_and_numbers.schema.hpp"
22
#include "array_doubles_10_20_30_40.hpp"
33
#include "array_integers_10_20_30_40.hpp"
4+
#ifdef __GNUC__
5+
#pragma GCC diagnostic push
6+
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
7+
#endif
48
#include <catch2/catch.hpp>
9+
#ifdef __GNUC__
10+
#pragma GCC diagnostic pop
11+
#endif
512
#include <json2cpp/json2cpp_adapter.hpp>
613
#include <valijson/schema.hpp>
714
#include <valijson/schema_parser.hpp>

0 commit comments

Comments
 (0)
Please sign in to comment.