Skip to content

Commit fb95b36

Browse files
committed
json_iterator * -> json_iterator_ref
1 parent 0a79713 commit fb95b36

11 files changed

+117
-48
lines changed

src/generic/ondemand/array-inl.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,18 @@ namespace ondemand {
4141
//
4242

4343
simdjson_really_inline array::array() noexcept = default;
44-
simdjson_really_inline array::array(json_iterator *_iter, bool has_value) noexcept
45-
: iter{_iter}, has_next{has_value}, error{SUCCESS}
44+
simdjson_really_inline array::array(json_iterator_ref &&_iter, bool has_value) noexcept
45+
: iter{std::forward<json_iterator_ref>(_iter)}, has_next{has_value}, error{SUCCESS}
4646
{
4747
}
4848
simdjson_really_inline array::array(array &&other) noexcept
49-
: iter{other.iter}, has_next{other.has_next}, error{other.error}
49+
: iter{std::forward<array>(other).iter}, has_next{other.has_next}, error{other.error}
5050
{
5151
// Terminate the other iterator
5252
other.has_next = false;
5353
}
5454
simdjson_really_inline array &array::operator=(array &&other) noexcept {
55-
iter = other.iter;
55+
iter = std::forward<array>(other).iter;
5656
has_next = other.has_next;
5757
error = other.error;
5858
// Terminate the other iterator
@@ -67,13 +67,13 @@ simdjson_really_inline array::~array() noexcept {
6767
}
6868
}
6969

70-
simdjson_really_inline simdjson_result<array> array::start(json_iterator *iter) noexcept {
70+
simdjson_really_inline simdjson_result<array> array::start(json_iterator_ref &&iter) noexcept {
7171
bool has_value;
7272
SIMDJSON_TRY( iter->start_array().get(has_value) );
73-
return array(iter, has_value);
73+
return array(std::forward<json_iterator_ref>(iter), has_value);
7474
}
75-
simdjson_really_inline array array::started(json_iterator *iter) noexcept {
76-
return array(iter, iter->started_array());
75+
simdjson_really_inline array array::started(json_iterator_ref &&iter) noexcept {
76+
return array(std::forward<json_iterator_ref>(iter), iter->started_array());
7777
}
7878
simdjson_really_inline array::iterator array::begin() noexcept {
7979
return *this;
@@ -96,7 +96,7 @@ simdjson_really_inline array::iterator &array::iterator::operator=(const array::
9696

9797
simdjson_really_inline simdjson_result<value> array::iterator::operator*() noexcept {
9898
if (a->error) { return a->report_error(); }
99-
return value::start(a->iter);
99+
return value::start(a->iter.borrow());
100100
}
101101
simdjson_really_inline bool array::iterator::operator==(const array::iterator &) noexcept {
102102
return !a->has_next;

src/generic/ondemand/array.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ class array {
5353
* @param doc The document containing the array.
5454
* @error INCORRECT_TYPE if the iterator is not at [.
5555
*/
56-
static simdjson_really_inline simdjson_result<array> start(json_iterator *iter) noexcept;
56+
static simdjson_really_inline simdjson_result<array> start(json_iterator_ref &&iter) noexcept;
5757
/**
5858
* Begin array iteration.
5959
*
6060
* @param doc The document containing the array. The iterator must be just after the opening `[`.
6161
*/
62-
static simdjson_really_inline array started(json_iterator *iter) noexcept;
62+
static simdjson_really_inline array started(json_iterator_ref &&iter) noexcept;
6363

6464
/**
6565
* Report the current error and set finished so it won't be reported again.
@@ -73,15 +73,15 @@ class array {
7373
* reflect the array's depth. The iterator must be just after the opening `[`.
7474
* @param has_value Whether the array has a value (false means empty array).
7575
*/
76-
simdjson_really_inline array(json_iterator *iter, bool has_value) noexcept;
76+
simdjson_really_inline array(json_iterator_ref &&iter, bool has_value) noexcept;
7777

7878
/**
7979
* Document containing this array.
8080
*
8181
* PERF NOTE: expected to be elided in favor of the parent document: this is set when the array
8282
* is first used, and never changes afterwards.
8383
*/
84-
json_iterator *iter{};
84+
json_iterator_ref iter{};
8585
/**
8686
* Whether we have anything to yield.
8787
*

src/generic/ondemand/document-inl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace ondemand {
44

55
simdjson_really_inline document::document(document &&other) noexcept = default;
66
simdjson_really_inline document &document::operator=(document &&other) noexcept = default;
7-
simdjson_really_inline document::document(ondemand::json_iterator && _iter) noexcept
7+
simdjson_really_inline document::document(ondemand::json_iterator &&_iter) noexcept
88
: iter(std::forward<json_iterator>(_iter))
99
{
1010
logger::log_start_value(iter, "document");
@@ -20,7 +20,7 @@ simdjson_really_inline value document::as_value() noexcept {
2020
logger::log_error(iter, "Document value can only be used once! ondemand::document is a forward-only input iterator.");
2121
abort(); // TODO is there anything softer we can do? I'd rather not make this a simdjson_result just for user error.
2222
}
23-
return value::start(&iter);
23+
return value::start(iter.borrow());
2424
}
2525

2626
simdjson_really_inline simdjson_result<array> document::get_array() & noexcept { return as_value().get_array(); }

src/generic/ondemand/field-inl.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ simdjson_really_inline field::field(raw_json_string key, ondemand::value &&value
1212
{
1313
}
1414

15-
simdjson_really_inline simdjson_result<field> field::start(json_iterator *iter) noexcept {
15+
simdjson_really_inline simdjson_result<field> field::start(json_iterator_ref &&iter) noexcept {
1616
raw_json_string key;
1717
SIMDJSON_TRY( iter->field_key().get(key) );
1818
SIMDJSON_TRY( iter->field_value() );
19-
return field::start(iter, key);
19+
return field::start(std::forward<json_iterator_ref>(iter), key);
2020
}
2121

22-
simdjson_really_inline simdjson_result<field> field::start(json_iterator *iter, raw_json_string key) noexcept {
23-
return field(key, value::start(iter));
22+
simdjson_really_inline simdjson_result<field> field::start(json_iterator_ref &&iter, raw_json_string key) noexcept {
23+
return field(key, value::start(std::forward<json_iterator_ref>(iter)));
2424
}
2525

2626
simdjson_really_inline raw_json_string field::key() const noexcept {

src/generic/ondemand/field.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ class field : public std::pair<raw_json_string, value> {
1919
simdjson_really_inline ondemand::value &value() noexcept;
2020
protected:
2121
simdjson_really_inline field(raw_json_string key, ondemand::value &&value) noexcept;
22-
static simdjson_really_inline simdjson_result<field> start(json_iterator *iter) noexcept;
23-
static simdjson_really_inline simdjson_result<field> start(json_iterator *iter, raw_json_string key) noexcept;
22+
static simdjson_really_inline simdjson_result<field> start(json_iterator_ref &&iter) noexcept;
23+
static simdjson_really_inline simdjson_result<field> start(json_iterator_ref &&iter, raw_json_string key) noexcept;
2424
friend struct simdjson_result<field>;
2525
friend class object;
2626
};

src/generic/ondemand/json_iterator-inl.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,41 @@ simdjson_really_inline bool json_iterator::is_alive() const noexcept {
260260
return parser;
261261
}
262262

263+
simdjson_really_inline json_iterator_ref json_iterator::borrow() noexcept {
264+
return json_iterator_ref(this);
265+
}
266+
267+
//
268+
// json_iterator_ref
269+
//
270+
simdjson_really_inline json_iterator_ref::json_iterator_ref() noexcept = default;
271+
simdjson_really_inline json_iterator_ref::json_iterator_ref(json_iterator_ref &&other) noexcept = default;
272+
simdjson_really_inline json_iterator_ref &json_iterator_ref::operator=(json_iterator_ref &&other) noexcept = default;
273+
simdjson_really_inline json_iterator_ref::json_iterator_ref(json_iterator *_iter) noexcept
274+
: iter{_iter}
275+
{
276+
}
277+
simdjson_really_inline json_iterator_ref::~json_iterator_ref() noexcept = default;
278+
279+
simdjson_really_inline json_iterator_ref json_iterator_ref::borrow() noexcept {
280+
return json_iterator_ref(iter);
281+
}
282+
283+
simdjson_really_inline json_iterator *json_iterator_ref::operator->() noexcept {
284+
return iter;
285+
}
286+
simdjson_really_inline json_iterator &json_iterator_ref::operator*() noexcept {
287+
return *iter;
288+
}
289+
simdjson_really_inline const json_iterator &json_iterator_ref::operator*() const noexcept {
290+
return *iter;
291+
}
292+
293+
simdjson_really_inline bool json_iterator_ref::is_alive() const noexcept {
294+
return iter != nullptr;
295+
}
296+
297+
263298
} // namespace ondemand
264299
} // namespace SIMDJSON_IMPLEMENTATION
265300
} // namespace {

src/generic/ondemand/json_iterator.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ namespace {
22
namespace SIMDJSON_IMPLEMENTATION {
33
namespace ondemand {
44

5+
class json_iterator_ref;
6+
57
/**
68
* Iterates through JSON, with structure-sensitive algorithms.
79
*
@@ -140,14 +142,40 @@ class json_iterator : public token_iterator {
140142
template<int N>
141143
SIMDJSON_WARN_UNUSED simdjson_really_inline bool advance_to_buffer(uint8_t (&buf)[N]) noexcept;
142144

145+
simdjson_really_inline json_iterator_ref borrow() noexcept;
146+
143147
friend class document;
144148
friend class object;
145149
friend class array;
146150
friend class value;
147151
friend class raw_json_string;
148152
friend class parser;
149153
friend simdjson_really_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta) noexcept;
150-
};
154+
}; // json_iterator
155+
156+
class json_iterator_ref {
157+
public:
158+
simdjson_really_inline json_iterator_ref() noexcept;
159+
simdjson_really_inline json_iterator_ref(json_iterator_ref &&other) noexcept;
160+
simdjson_really_inline json_iterator_ref &operator=(json_iterator_ref &&other) noexcept;
161+
simdjson_really_inline json_iterator_ref(const json_iterator_ref &other) noexcept = delete;
162+
simdjson_really_inline json_iterator_ref &operator=(const json_iterator_ref &other) noexcept = delete;
163+
simdjson_really_inline ~json_iterator_ref() noexcept;
164+
165+
simdjson_really_inline json_iterator_ref borrow() noexcept;
166+
167+
simdjson_really_inline json_iterator *operator->() noexcept;
168+
simdjson_really_inline json_iterator &operator*() noexcept;
169+
simdjson_really_inline const json_iterator &operator*() const noexcept;
170+
171+
simdjson_really_inline bool is_alive() const noexcept;
172+
173+
private:
174+
simdjson_really_inline json_iterator_ref(json_iterator *iter) noexcept;
175+
json_iterator *iter;
176+
177+
friend class json_iterator;
178+
}; // class json_iterator_ref
151179

152180
} // namespace ondemand
153181
} // namespace SIMDJSON_IMPLEMENTATION

src/generic/ondemand/object-inl.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,18 @@ namespace ondemand {
4444
//
4545

4646
simdjson_really_inline object::object() noexcept = default;
47-
simdjson_really_inline object::object(json_iterator *_iter, bool _has_value) noexcept
48-
: iter{_iter}, has_next{_has_value}, at_start{true}, error{SUCCESS}
47+
simdjson_really_inline object::object(json_iterator_ref &&_iter, bool _has_value) noexcept
48+
: iter{std::forward<json_iterator_ref>(_iter)}, has_next{_has_value}, at_start{true}, error{SUCCESS}
4949
{
5050
}
5151
simdjson_really_inline object::object(object &&other) noexcept
52-
: iter{other.iter}, has_next{other.has_next}, at_start{other.at_start}, error{other.error}
52+
: iter{std::forward<object>(other).iter}, has_next{other.has_next}, at_start{other.at_start}, error{other.error}
5353
{
5454
// Terminate the other iterator
5555
other.has_next = false;
5656
}
5757
simdjson_really_inline object &object::operator=(object &&other) noexcept {
58-
iter = other.iter;
58+
iter = std::forward<object>(other).iter;
5959
has_next = other.has_next;
6060
at_start = other.at_start;
6161
error = other.error;
@@ -91,7 +91,7 @@ simdjson_really_inline simdjson_result<value> object::operator[](const std::stri
9191
// Check if it matches
9292
if (actual_key == key) {
9393
logger::log_event(*iter, "match", key, -2);
94-
return value::start(iter);
94+
return value::start(iter.borrow());
9595
}
9696
logger::log_event(*iter, "no match", key, -2);
9797
iter->skip(); // Skip the value entirely
@@ -102,13 +102,13 @@ simdjson_really_inline simdjson_result<value> object::operator[](const std::stri
102102
return NO_SUCH_FIELD;
103103
}
104104

105-
simdjson_really_inline simdjson_result<object> object::start(json_iterator *iter) noexcept {
105+
simdjson_really_inline simdjson_result<object> object::start(json_iterator_ref &&iter) noexcept {
106106
bool has_value;
107107
SIMDJSON_TRY( iter->start_object().get(has_value) );
108-
return object(iter, has_value);
108+
return object(std::forward<json_iterator_ref>(iter), has_value);
109109
}
110-
simdjson_really_inline object object::started(json_iterator *iter) noexcept {
111-
return object(iter, iter->started_object());
110+
simdjson_really_inline object object::started(json_iterator_ref &&iter) noexcept {
111+
return object(std::forward<json_iterator_ref>(iter), iter->started_object());
112112
}
113113
simdjson_really_inline object::iterator object::begin() noexcept {
114114
return *this;
@@ -135,7 +135,7 @@ simdjson_really_inline object::iterator &object::iterator::operator=(const objec
135135
simdjson_really_inline simdjson_result<field> object::iterator::operator*() noexcept {
136136
if (o->error) { return o->report_error(); }
137137
if (o->at_start) { o->at_start = false; }
138-
return field::start(o->iter);
138+
return field::start(o->iter.borrow());
139139
}
140140
simdjson_really_inline bool object::iterator::operator==(const object::iterator &) noexcept {
141141
return !o->has_next;

src/generic/ondemand/object.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ class object {
5151
* @param doc The document containing the object. The iterator must be just after the opening `{`.
5252
* @param error If this is not SUCCESS, creates an error chained object.
5353
*/
54-
static simdjson_really_inline simdjson_result<object> start(json_iterator *iter) noexcept;
55-
static simdjson_really_inline object started(json_iterator *iter) noexcept;
54+
static simdjson_really_inline simdjson_result<object> start(json_iterator_ref &&iter) noexcept;
55+
static simdjson_really_inline object started(json_iterator_ref &&iter) noexcept;
5656

5757
/**
5858
* Internal object creation. Call object::begin(doc) instead of this.
@@ -62,7 +62,7 @@ class object {
6262
* @param is_empty Whether this container is empty or not.
6363
* @param error The error to report. If the error is not SUCCESS, this is an error chained object.
6464
*/
65-
simdjson_really_inline object(json_iterator *_iter, bool is_empty) noexcept;
65+
simdjson_really_inline object(json_iterator_ref &&_iter, bool is_empty) noexcept;
6666

6767
simdjson_really_inline error_code report_error() noexcept;
6868

@@ -72,7 +72,7 @@ class object {
7272
* PERF NOTE: expected to be elided in favor of the parent document: this is set when the object
7373
* is first used, and never changes afterwards.
7474
*/
75-
json_iterator *iter{};
75+
json_iterator_ref iter{};
7676
/**
7777
* Whether we have anything to yield.
7878
*

src/generic/ondemand/value-inl.h

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,23 @@ namespace SIMDJSON_IMPLEMENTATION {
33
namespace ondemand {
44

55
simdjson_really_inline value::value() noexcept = default;
6-
simdjson_really_inline value::value(value &&other) noexcept {
7-
*this = std::forward<value>(other);
6+
simdjson_really_inline value::value(value &&other) noexcept
7+
: iter{std::forward<value>(other).iter},
8+
json{other.json}
9+
{
10+
other.json = nullptr;
811
};
912
simdjson_really_inline value &value::operator=(value &&other) noexcept {
10-
iter = other.iter;
13+
iter = std::forward<value>(other).iter;
1114
json = other.json;
1215
other.json = nullptr;
1316
return *this;
1417
}
15-
simdjson_really_inline value::value(json_iterator *_iter, const uint8_t *_json) noexcept : iter{_iter}, json{_json} {
16-
SIMDJSON_ASSUME(iter != nullptr);
18+
simdjson_really_inline value::value(json_iterator_ref && _iter, const uint8_t *_json) noexcept
19+
: iter{std::forward<json_iterator_ref>(_iter)},
20+
json{_json}
21+
{
22+
SIMDJSON_ASSUME(iter.is_alive());
1723
SIMDJSON_ASSUME(json != nullptr);
1824
}
1925

@@ -32,8 +38,8 @@ simdjson_really_inline value::~value() noexcept {
3238
}
3339
}
3440

35-
simdjson_really_inline value value::start(json_iterator *iter) noexcept {
36-
return { iter, iter->advance() };
41+
simdjson_really_inline value value::start(json_iterator_ref &&iter) noexcept {
42+
return { std::forward<json_iterator_ref>(iter), iter->advance() };
3743
}
3844

3945
simdjson_really_inline simdjson_result<array> value::get_array() noexcept {
@@ -42,15 +48,15 @@ simdjson_really_inline simdjson_result<array> value::get_array() noexcept {
4248
return INCORRECT_TYPE;
4349
}
4450
json = nullptr; // Communicate that we have handled the value PERF TODO elided, right?
45-
return array::started(iter);
51+
return array::started(std::move(iter));
4652
}
4753
simdjson_really_inline simdjson_result<object> value::get_object() noexcept {
4854
if (*json != '{') {
4955
log_error("not an object");
5056
return INCORRECT_TYPE;
5157
}
5258
json = nullptr; // Communicate that we have handled the value PERF TODO elided, right?
53-
return object::started(iter);
59+
return object::started(std::move(iter));
5460
}
5561
simdjson_really_inline simdjson_result<raw_json_string> value::get_raw_json_string() noexcept {
5662
log_value("string");

src/generic/ondemand/value.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class value {
5959
*
6060
* Use value::read() instead of this.
6161
*/
62-
simdjson_really_inline value(json_iterator *iter, const uint8_t *json) noexcept;
62+
simdjson_really_inline value(json_iterator_ref &&iter, const uint8_t *json) noexcept;
6363

6464
/**
6565
* Read a value.
@@ -68,12 +68,12 @@ class value {
6868
*
6969
* @param doc The document containing the value. Iterator must be at the value start position.
7070
*/
71-
static simdjson_really_inline value start(json_iterator *iter) noexcept;
71+
static simdjson_really_inline value start(json_iterator_ref &&iter) noexcept;
7272

7373
simdjson_really_inline void log_value(const char *type) const noexcept;
7474
simdjson_really_inline void log_error(const char *message) const noexcept;
7575

76-
json_iterator *iter{}; // For the string buffer (if we need it)
76+
json_iterator_ref iter{}; // For the string buffer (if we need it)
7777
const uint8_t *json{}; // The JSON text of the value
7878

7979
friend class document;

0 commit comments

Comments
 (0)