Skip to content

Commit 10e1095

Browse files
committed
Require value to be deleted after most value conversions
1 parent a43c138 commit 10e1095

File tree

3 files changed

+142
-111
lines changed

3 files changed

+142
-111
lines changed

src/generic/ondemand/document-inl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ simdjson_really_inline document::operator raw_json_string() & noexcept(false) {
4444
simdjson_really_inline document::operator bool() noexcept(false) { return as_value(); }
4545
#endif
4646

47-
simdjson_really_inline simdjson_result<array::iterator> document::begin() & noexcept { return as_value().begin(); }
47+
simdjson_really_inline simdjson_result<array::iterator> document::begin() & noexcept {
48+
return as_value().get_array().begin();
49+
}
4850
simdjson_really_inline simdjson_result<array::iterator> document::end() & noexcept { return {}; }
4951
simdjson_really_inline simdjson_result<value> document::operator[](std::string_view key) & noexcept { return as_value()[key]; }
5052

src/generic/ondemand/value-inl.h

Lines changed: 101 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -33,94 +33,119 @@ simdjson_really_inline value value::start(json_iterator_ref &&iter) noexcept {
3333
return { std::forward<json_iterator_ref>(iter), iter->advance() };
3434
}
3535

36-
simdjson_really_inline simdjson_result<array> value::get_array() noexcept {
36+
simdjson_really_inline simdjson_result<array> value::get_array() && noexcept {
3737
if (*json != '[') {
3838
log_error("not an array");
39+
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
3940
return INCORRECT_TYPE;
4041
}
41-
return array::started(std::move(iter));
42+
return array::started(std::forward<json_iterator_ref>(iter));
4243
}
43-
simdjson_really_inline simdjson_result<object> value::get_object() noexcept {
44+
simdjson_really_inline simdjson_result<object> value::get_object() && noexcept {
4445
if (*json != '{') {
4546
log_error("not an object");
47+
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
4648
return INCORRECT_TYPE;
4749
}
48-
return object::started(std::move(iter));
50+
return object::started(std::forward<json_iterator_ref>(iter));
4951
}
50-
simdjson_really_inline simdjson_result<raw_json_string> value::get_raw_json_string() noexcept {
52+
simdjson_really_inline simdjson_result<raw_json_string> value::get_raw_json_string() && noexcept {
5153
log_value("string");
52-
if (*json != '"') { log_error("not a string"); return INCORRECT_TYPE; }
53-
auto result = raw_json_string{&json[1]};
5454
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
55-
return result;
55+
if (*json != '"') { log_error("not a string"); return INCORRECT_TYPE; }
56+
return raw_json_string{&json[1]};
5657
}
57-
simdjson_really_inline simdjson_result<std::string_view> value::get_string() noexcept {
58+
simdjson_really_inline simdjson_result<std::string_view> value::get_string() && noexcept {
5859
log_value("string");
59-
if (*json != '"') { log_error("not a string"); return INCORRECT_TYPE; }
60+
if (*json != '"') {
61+
log_error("not a string");
62+
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
63+
return INCORRECT_TYPE;
64+
}
6065
auto result = raw_json_string{&json[1]}.unescape(iter->current_string_buf_loc);
6166
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
6267
return result;
6368
}
64-
simdjson_really_inline simdjson_result<double> value::get_double() noexcept {
69+
simdjson_really_inline simdjson_result<double> value::get_double() && noexcept {
6570
log_value("double");
71+
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
6672
double result;
6773
error_code error;
6874
if ((error = stage2::numberparsing::parse_double(json).get(result))) { log_error("not a double"); return error; }
69-
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
7075
return result;
7176
}
72-
simdjson_really_inline simdjson_result<uint64_t> value::get_uint64() noexcept {
77+
simdjson_really_inline simdjson_result<uint64_t> value::get_uint64() && noexcept {
7378
log_value("unsigned");
79+
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
7480
uint64_t result;
7581
error_code error;
7682
if ((error = stage2::numberparsing::parse_unsigned(json).get(result))) { log_error("not a unsigned integer"); return error; }
77-
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
7883
return result;
7984
}
80-
simdjson_really_inline simdjson_result<int64_t> value::get_int64() noexcept {
85+
simdjson_really_inline simdjson_result<int64_t> value::get_int64() && noexcept {
8186
log_value("integer");
87+
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
8288
int64_t result;
8389
error_code error;
8490
if ((error = stage2::numberparsing::parse_integer(json).get(result))) { log_error("not an integer"); return error; }
85-
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
8691
return result;
8792
}
88-
simdjson_really_inline simdjson_result<bool> value::get_bool() noexcept {
93+
simdjson_really_inline simdjson_result<bool> value::get_bool() && noexcept {
8994
log_value("bool");
95+
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
9096
auto not_true = stage2::atomparsing::str4ncmp(json, "true");
9197
auto not_false = stage2::atomparsing::str4ncmp(json, "fals") | (json[4] ^ 'e');
9298
bool error = (not_true && not_false) || stage2::is_not_structural_or_whitespace(json[not_true ? 5 : 4]);
9399
if (error) { log_error("not a boolean"); return INCORRECT_TYPE; }
94-
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
95100
return simdjson_result<bool>(!not_true, error ? INCORRECT_TYPE : SUCCESS);
96101
}
97-
simdjson_really_inline bool value::is_null() noexcept {
102+
simdjson_really_inline bool value::is_null() & noexcept {
98103
log_value("null");
104+
// Since it's a *reference*, we may want to check something other than is_null() if it isn't null,
105+
// so we don't release the iterator unless it is actually null
99106
if (stage2::atomparsing::str4ncmp(json, "null")) { return false; }
100107
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
101108
return true;
102109
}
110+
simdjson_really_inline bool value::is_null() && noexcept {
111+
log_value("null");
112+
iter.release(); // Communicate that we have handled the value PERF TODO elided, right?
113+
if (stage2::atomparsing::str4ncmp(json, "null")) { return false; }
114+
return true;
115+
}
103116

104117
#if SIMDJSON_EXCEPTIONS
105-
simdjson_really_inline value::operator array() noexcept(false) { return get_array(); }
106-
simdjson_really_inline value::operator object() noexcept(false) { return get_object(); }
107-
simdjson_really_inline value::operator uint64_t() noexcept(false) { return get_uint64(); }
108-
simdjson_really_inline value::operator int64_t() noexcept(false) { return get_int64(); }
109-
simdjson_really_inline value::operator double() noexcept(false) { return get_double(); }
110-
simdjson_really_inline value::operator std::string_view() noexcept(false) { return get_string(); }
111-
simdjson_really_inline value::operator raw_json_string() noexcept(false) { return get_raw_json_string(); }
112-
simdjson_really_inline value::operator bool() noexcept(false) { return get_bool(); }
118+
simdjson_really_inline value::operator array() && noexcept(false) {
119+
return std::forward<value>(*this).get_array();
120+
}
121+
simdjson_really_inline value::operator object() && noexcept(false) {
122+
return std::forward<value>(*this).get_object();
123+
}
124+
simdjson_really_inline value::operator uint64_t() && noexcept(false) {
125+
return std::forward<value>(*this).get_uint64();
126+
}
127+
simdjson_really_inline value::operator int64_t() && noexcept(false) {
128+
return std::forward<value>(*this).get_int64();
129+
}
130+
simdjson_really_inline value::operator double() && noexcept(false) {
131+
return std::forward<value>(*this).get_double();
132+
}
133+
simdjson_really_inline value::operator std::string_view() && noexcept(false) {
134+
return std::forward<value>(*this).get_string();
135+
}
136+
simdjson_really_inline value::operator raw_json_string() && noexcept(false) {
137+
return std::forward<value>(*this).get_raw_json_string();
138+
}
139+
simdjson_really_inline value::operator bool() && noexcept(false) {
140+
return std::forward<value>(*this).get_bool();
141+
}
113142
#endif
114143

115-
simdjson_really_inline simdjson_result<array::iterator> value::begin() noexcept { return get_array().begin(); }
116-
simdjson_really_inline simdjson_result<array::iterator> value::end() noexcept { return {}; }
117-
// TODO this CANNOT be reused. Each time you try, it will get you a new object.
118-
// Probably make it move-only to avoid this issue.
119-
simdjson_really_inline simdjson_result<value> value::operator[](std::string_view key) noexcept {
120-
return get_object()[key];
144+
simdjson_really_inline simdjson_result<value> value::operator[](std::string_view key) && noexcept {
145+
return std::forward<value>(*this).get_object()[key];
121146
}
122-
simdjson_really_inline simdjson_result<value> value::operator[](const char *key) noexcept {
123-
return get_object()[key];
147+
simdjson_really_inline simdjson_result<value> value::operator[](const char *key) && noexcept {
148+
return std::forward<value>(*this).get_object()[key];
124149
}
125150

126151
simdjson_really_inline void value::log_value(const char *type) const noexcept {
@@ -163,90 +188,94 @@ simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>
163188

164189
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::begin() noexcept {
165190
if (error()) { return error(); }
166-
return std::move(first.begin());
191+
return std::move(first).get_array().begin();
167192
}
168193
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::end() noexcept {
169194
if (error()) { return error(); }
170-
return std::move(first.end());
195+
return {};
171196
}
172197
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator[](std::string_view key) noexcept {
173198
if (error()) { return error(); }
174-
return first[key];
199+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first)[key];
175200
}
176201
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator[](const char *key) noexcept {
177202
if (error()) { return error(); }
178-
return first[key];
203+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first)[key];
179204
}
180205

181-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_array() noexcept {
206+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_array() && noexcept {
182207
if (error()) { return error(); }
183-
return first.get_array();
208+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first).get_array();
184209
}
185-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_object() noexcept {
210+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_object() && noexcept {
186211
if (error()) { return error(); }
187-
return first.get_object();
212+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first).get_object();
188213
}
189-
simdjson_really_inline simdjson_result<uint64_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_uint64() noexcept {
214+
simdjson_really_inline simdjson_result<uint64_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_uint64() && noexcept {
190215
if (error()) { return error(); }
191-
return first.get_uint64();
216+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first).get_uint64();
192217
}
193-
simdjson_really_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_int64() noexcept {
218+
simdjson_really_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_int64() && noexcept {
194219
if (error()) { return error(); }
195-
return first.get_int64();
220+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first).get_int64();
196221
}
197-
simdjson_really_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_double() noexcept {
222+
simdjson_really_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_double() && noexcept {
198223
if (error()) { return error(); }
199-
return first.get_double();
224+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first).get_double();
200225
}
201-
simdjson_really_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_string() noexcept {
226+
simdjson_really_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_string() && noexcept {
202227
if (error()) { return error(); }
203-
return first.get_string();
228+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first).get_string();
204229
}
205-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_raw_json_string() noexcept {
230+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_raw_json_string() && noexcept {
206231
if (error()) { return error(); }
207-
return first.get_raw_json_string();
232+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first).get_raw_json_string();
208233
}
209-
simdjson_really_inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_bool() noexcept {
234+
simdjson_really_inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_bool() && noexcept {
210235
if (error()) { return error(); }
211-
return first.get_bool();
236+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first).get_bool();
212237
}
213-
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::is_null() noexcept {
238+
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::is_null() & noexcept {
214239
if (error()) { return false; }
215240
return first.is_null();
216241
}
242+
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::is_null() && noexcept {
243+
if (error()) { return false; }
244+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first).is_null();
245+
}
217246

218247
#if SIMDJSON_EXCEPTIONS
219-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator SIMDJSON_IMPLEMENTATION::ondemand::array() noexcept(false) {
248+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator SIMDJSON_IMPLEMENTATION::ondemand::array() && noexcept(false) {
220249
if (error()) { throw simdjson_error(error()); }
221-
return first;
250+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first);
222251
}
223-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator SIMDJSON_IMPLEMENTATION::ondemand::object() noexcept(false) {
252+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator SIMDJSON_IMPLEMENTATION::ondemand::object() && noexcept(false) {
224253
if (error()) { throw simdjson_error(error()); }
225-
return first;
254+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first);
226255
}
227-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator uint64_t() noexcept(false) {
256+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator uint64_t() && noexcept(false) {
228257
if (error()) { throw simdjson_error(error()); }
229-
return first;
258+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first);
230259
}
231-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator int64_t() noexcept(false) {
260+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator int64_t() && noexcept(false) {
232261
if (error()) { throw simdjson_error(error()); }
233-
return first;
262+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first);
234263
}
235-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator double() noexcept(false) {
264+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator double() && noexcept(false) {
236265
if (error()) { throw simdjson_error(error()); }
237-
return first;
266+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first);
238267
}
239-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator std::string_view() noexcept(false) {
268+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator std::string_view() && noexcept(false) {
240269
if (error()) { throw simdjson_error(error()); }
241-
return first;
270+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first);
242271
}
243-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false) {
272+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() && noexcept(false) {
244273
if (error()) { throw simdjson_error(error()); }
245-
return first;
274+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first);
246275
}
247-
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator bool() noexcept(false) {
276+
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator bool() && noexcept(false) {
248277
if (error()) { throw simdjson_error(error()); }
249-
return first;
278+
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first);
250279
}
251280
#endif
252281

0 commit comments

Comments
 (0)