Skip to content

Commit c57524e

Browse files
committed
Initial integration with valijson
1 parent 7c7d0f0 commit c57524e

File tree

3 files changed

+288
-181
lines changed

3 files changed

+288
-181
lines changed

include/json2cpp/constexpr_json.hpp

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ template<typename T> struct span
2222
: begin_{ input.data() }, end_{ std::next(input.data(), Size) }
2323
{}
2424

25+
constexpr span() : begin_{ nullptr }, end_{ nullptr } {}
26+
2527
constexpr const T *begin() const { return begin_; }
2628

2729
constexpr const T *end() const { return end_; }
@@ -51,9 +53,9 @@ struct json
5153
{
5254
if (end == true) {
5355
if (is_array_) {
54-
index_ = value.array().size();
56+
index_ = value.array_data().size();
5557
} else if (is_object_) {
56-
index_ = value.object().size();
58+
index_ = value.object_data().size();
5759
}
5860
}
5961
}
@@ -63,18 +65,25 @@ struct json
6365
if (is_array_) {
6466
return (*parent_value_)[index_];
6567
} else if (is_object_) {
66-
return std::next(parent_value_->object().begin(), static_cast<std::ptrdiff_t>(index_))->second;
68+
return std::next(parent_value_->object_data().begin(), static_cast<std::ptrdiff_t>(index_))->second;
6769
} else {
6870
return *parent_value_;
6971
}
7072
}
7173

74+
constexpr const json *operator->() const {
75+
return &(*(*this));
76+
}
77+
7278
constexpr std::size_t index() const { return index_; }
7379

80+
constexpr const json &value() const { return *(*this); }
81+
82+
7483
constexpr std::string_view key() const
7584
{
7685
if (is_object_) {
77-
return std::next(parent_value_->object().begin(), static_cast<std::ptrdiff_t>(index_))->first;
86+
return std::next(parent_value_->object_data().begin(), static_cast<std::ptrdiff_t>(index_))->first;
7887
} else {
7988
throw std::runtime_error("json value is not an object, it has no key");
8089
}
@@ -93,6 +102,19 @@ struct json
93102
return index_ < other.index_;
94103
}
95104

105+
constexpr iterator &operator--()
106+
{
107+
--index_;
108+
return *this;
109+
}
110+
111+
constexpr iterator operator--(int)
112+
{
113+
iterator result{ *this };
114+
index_--;
115+
return result;
116+
}
117+
96118
constexpr iterator &operator++()
97119
{
98120
++index_;
@@ -106,13 +128,28 @@ struct json
106128
return result;
107129
}
108130

131+
constexpr iterator &operator+=(const std::ptrdiff_t value)
132+
{
133+
index_ = static_cast<std::size_t>(static_cast<std::ptrdiff_t>(index_) + value);
134+
return *this;
135+
}
136+
137+
138+
constexpr iterator &operator+=(const std::size_t value)
139+
{
140+
index_ += value;
141+
return *this;
142+
}
143+
109144
const json *parent_value_{ nullptr };
110145

111146
std::size_t index_{ 0 };
112147
bool is_object_{ false };
113148
bool is_array_{ false };
114149
};
115150

151+
using const_iterator = iterator;
152+
116153
constexpr iterator begin() const { return iterator{ *this }; }
117154

118155
constexpr iterator end() const { return iterator{ *this, true }; }
@@ -133,16 +170,28 @@ struct json
133170

134171
constexpr const json &operator[](const std::size_t idx) const
135172
{
136-
if (const auto &children = array(); children.size() < idx) {
173+
if (const auto &children = array_data(); children.size() < idx) {
137174
return *std::next(children.begin(), static_cast<std::ptrdiff_t>(idx));
138175
} else {
139176
throw std::runtime_error("index out of range");
140177
}
141178
}
142179

180+
constexpr iterator find(const std::string_view key) const
181+
{
182+
for (auto itr = begin(); itr != end(); ++itr)
183+
{
184+
if (itr.key() == key) {
185+
return itr;
186+
}
187+
}
188+
189+
return end();
190+
}
191+
143192
constexpr const json &operator[](const std::string_view key) const
144193
{
145-
const auto &children = object();
194+
const auto &children = object_data();
146195

147196
// find_if is not constexpr yet in C++17
148197
for (const auto &value : children) {
@@ -153,7 +202,7 @@ struct json
153202
throw std::runtime_error("Key not found");
154203
}
155204

156-
constexpr const array_t &array() const
205+
constexpr const array_t &array_data() const
157206
{
158207
if (const auto *result = std::get_if<array_t>(&data); result != nullptr) {
159208
return *result;
@@ -162,7 +211,7 @@ struct json
162211
}
163212
}
164213

165-
constexpr const object_t &object() const
214+
constexpr const object_t &object_data() const
166215
{
167216
if (const auto *result = std::get_if<object_t>(&data); result != nullptr) {
168217
return *result;
@@ -171,6 +220,32 @@ struct json
171220
}
172221
}
173222

223+
constexpr static json object() { return json{ object_t{} }; }
224+
225+
constexpr static json array() { return json{ array_t{} }; }
226+
227+
228+
template<typename Type> constexpr Type get() const
229+
{
230+
if constexpr (std::is_same_v<Type, std::uint64_t> || std::is_same_v<Type, std::int64_t>) {
231+
if (const auto *uint_value = std::get_if<std::uint64_t>(&data); uint_value != nullptr) {
232+
return Type(*uint_value);
233+
} else if (const auto *value = std::get_if<std::int64_t>(&data); value != nullptr) {
234+
return Type(*value);
235+
}
236+
} else if constexpr (std::is_same_v<Type, double>) {
237+
if (const auto *value = std::get_if<double>(&data); value != nullptr) { return *value; }
238+
} else if constexpr (std::is_same_v<Type, std::string_view>) {
239+
if (const auto *value = std::get_if<std::string_view>(&data); value != nullptr) { return *value; }
240+
} else if constexpr (std::is_same_v<Type, bool>) {
241+
if (const auto *value = std::get_if<bool>(&data); value != nullptr) { return *value; }
242+
} else {
243+
throw std::runtime_error("Unexpected type for get()");
244+
}
245+
246+
throw std::runtime_error("Incorrect type for get()");
247+
}
248+
174249
constexpr bool is_object() const noexcept { return std::holds_alternative<object_t>(data); }
175250

176251
constexpr bool is_array() const noexcept { return std::holds_alternative<array_t>(data); }

0 commit comments

Comments
 (0)