Skip to content

Commit 56e2b38

Browse files
committed
Add bool result from tie()/get(), get<T>(T&,error_code&)
1 parent a5ccff7 commit 56e2b38

File tree

12 files changed

+132
-54
lines changed

12 files changed

+132
-54
lines changed

benchmark/statisticalmodel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ really_inline void simdjson_process_atom(stat_t &s,
5252
} else if (element.is<bool>()) {
5353
simdjson::error_code err;
5454
bool v;
55-
element.get<bool>().tie(v,err);
55+
element.get(v,err);
5656
if (v) {
5757
s.true_count++;
5858
} else {

doc/basics.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
8484
double value; // variable where we store the value to be parsed
8585
simdjson::padded_string numberstring = "1.2"_padded; // our JSON input ("1.2")
8686
simdjson::dom::parser parser;
87-
parser.parse(numberstring).get<double>().tie(value,error);
87+
parser.parse(numberstring).get(value,error);
8888
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
8989
std::cout << "I parsed " << value << " from " << numberstring.data() << std::endl;
9090
```
@@ -213,7 +213,7 @@ dom::parser parser;
213213
padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded;
214214
dom::object object;
215215
simdjson::error_code error;
216-
parser.parse(json).get<dom::object>().tie(object, error);
216+
parser.parse(json).get(object, error);
217217
for (dom::key_value_pair field : object) {
218218
cout << field.key << " = " << field.value << endl;
219219
}
@@ -299,13 +299,13 @@ auto cars_json = R"( [
299299
dom::parser parser;
300300
dom::array cars;
301301
simdjson::error_code error;
302-
parser.parse(cars_json).get<dom::array>().tie(cars, error);
302+
parser.parse(cars_json).get(cars, error);
303303
if (error) { cerr << error << endl; exit(1); }
304304

305305
// Iterating through an array of objects
306306
for (dom::element car_element : cars) {
307307
dom::object car;
308-
car_element.get<dom::object>().tie(car, error);
308+
car_element.get(car, error);
309309
if (error) { cerr << error << endl; exit(1); }
310310

311311
// Accessing a field by name
@@ -318,18 +318,18 @@ cout << "Make/Model: " << make << "/" << model << endl;
318318

319319
// Casting a JSON element to an integer
320320
uint64_t year;
321-
car["year"].get<uint64_t>().tie(year, error);
321+
car["year"].get(year, error);
322322
if (error) { cerr << error << endl; exit(1); }
323323
cout << "- This car is " << 2020 - year << "years old." << endl;
324324

325325
// Iterating through an array of floats
326326
double total_tire_pressure = 0;
327327
dom::array tire_pressure_array;
328-
car["tire_pressure"].get<dom::array>().tie(tire_pressure_array, error);
328+
car["tire_pressure"].get(tire_pressure_array, error);
329329
if (error) { cerr << error << endl; exit(1); }
330330
for (dom::element tire_pressure_element : tire_pressure_array) {
331331
double tire_pressure;
332-
tire_pressure_element.get<double>().tie(tire_pressure, error);
332+
tire_pressure_element.get(tire_pressure, error);
333333
if (error) { cerr << error << endl; exit(1); }
334334
total_tire_pressure += tire_pressure;
335335
}
@@ -351,31 +351,31 @@ auto abstract_json = R"( [
351351
dom::parser parser;
352352
dom::array rootarray;
353353
simdjson::error_code error;
354-
parser.parse(abstract_json).get<dom::array>().tie(rootarray, error);
354+
parser.parse(abstract_json).get(rootarray, error);
355355
if (error) { cerr << error << endl; exit(1); }
356356
// Iterate through an array of objects
357357
for (dom::element elem : rootarray) {
358358
dom::object obj;
359-
elem.get<dom::object>().tie(obj, error);
359+
elem.get(obj, error);
360360
if (error) { cerr << error << endl; exit(1); }
361361
for(auto & key_value : obj) {
362362
cout << "key: " << key_value.key << " : ";
363363
dom::object innerobj;
364-
key_value.value.get<dom::object>().tie(innerobj, error);
364+
key_value.value.get(innerobj, error);
365365
if (error) { cerr << error << endl; exit(1); }
366366

367367
double va;
368-
innerobj["a"].get<double>().tie(va, error);
368+
innerobj["a"].get(va, error);
369369
if (error) { cerr << error << endl; exit(1); }
370370
cout << "a: " << va << ", ";
371371

372372
double vb;
373-
innerobj["b"].get<double>().tie(vb, error);
373+
innerobj["b"].get(vb, error);
374374
if (error) { cerr << error << endl; exit(1); }
375375
cout << "b: " << vb << ", ";
376376

377377
int64_t vc;
378-
innerobj["c"].get<int64_t>().tie(vc, error);
378+
innerobj["c"].get(vc, error);
379379
if (error) { cerr << error << endl; exit(1); }
380380
cout << "c: " << vc << endl;
381381

@@ -392,7 +392,7 @@ And another one:
392392
dom::parser parser;
393393
double v;
394394
simdjson::error_code error;
395-
parser.parse(abstract_json)["str"]["123"]["abc"].get<double>().tie(v, error);
395+
parser.parse(abstract_json)["str"]["123"]["abc"].get(v, error);
396396
if (error) { cerr << error << endl; exit(1); }
397397
cout << "number: " << v << endl;
398398
```

include/simdjson/dom/element.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,63 @@ class element {
206206
template<typename T>
207207
really_inline simdjson_result<T> get() const noexcept;
208208

209+
/**
210+
* Get the value as the provided type (T).
211+
*
212+
* Supported types:
213+
* - Boolean: bool
214+
* - Number: double, uint64_t, int64_t
215+
* - String: std::string_view, const char *
216+
* - Array: dom::array
217+
* - Object: dom::object
218+
*
219+
* @tparam T bool, double, uint64_t, int64_t, std::string_view, const char *, dom::array, dom::object
220+
*
221+
* @param value The variable to set to the value. May not be set if there is an error.
222+
* @param error The variable to set to the error. Set to SUCCESS if there is no error.
223+
*
224+
* @returns true if the value was set, or false if there wsa an error.
225+
*/
226+
template<typename T>
227+
inline bool get(T &value, error_code &error) const noexcept;
228+
229+
/**
230+
* Get the value as the provided type (T), setting error if it's not the given type.
231+
*
232+
* Supported types:
233+
* - Boolean: bool
234+
* - Number: double, uint64_t, int64_t
235+
* - String: std::string_view, const char *
236+
* - Array: dom::array
237+
* - Object: dom::object
238+
*
239+
* @tparam T bool, double, uint64_t, int64_t, std::string_view, const char *, dom::array, dom::object
240+
*
241+
* @param value The variable to set to the given type. value is undefined if there is an error.
242+
* @param error The variable to store the error. error is set to error_code::SUCCEED if there is an error.
243+
*/
244+
template<typename T>
245+
inline void tie(T &value, error_code &error) && noexcept;
246+
247+
/**
248+
* Get the value as the provided type (T).
249+
*
250+
* Supported types:
251+
* - Boolean: bool
252+
* - Number: double, uint64_t, int64_t
253+
* - String: std::string_view, const char *
254+
* - Array: dom::array
255+
* - Object: dom::object
256+
*
257+
* @tparam T bool, double, uint64_t, int64_t, std::string_view, const char *, dom::array, dom::object
258+
*
259+
* @param value The variable to set to the given type. value is undefined if there is an error.
260+
*
261+
* @returns true if the value was able to be set, false if there was an error.
262+
*/
263+
template<typename T>
264+
WARN_UNUSED inline bool tie(T &value) && noexcept;
265+
209266
#if SIMDJSON_EXCEPTIONS
210267
/**
211268
* Read this element as a boolean.
@@ -421,6 +478,8 @@ struct simdjson_result<dom::element> : public internal::simdjson_result_base<dom
421478
inline simdjson_result<bool> is() const noexcept;
422479
template<typename T>
423480
inline simdjson_result<T> get() const noexcept;
481+
template<typename T>
482+
inline bool get(T &value, error_code &error) const noexcept;
424483

425484
inline simdjson_result<dom::array> get_array() const noexcept;
426485
inline simdjson_result<dom::object> get_object() const noexcept;

include/simdjson/error.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,10 @@ struct simdjson_result_base : public std::pair<T, error_code> {
119119

120120
/**
121121
* Move the value and the error to the provided variables.
122+
*
123+
* @return true if the value was set, false if there was an error.
122124
*/
123-
really_inline void tie(T &value, error_code &error) && noexcept;
125+
really_inline bool tie(T &value, error_code &error) && noexcept;
124126

125127
/**
126128
* The error.
@@ -181,8 +183,10 @@ struct simdjson_result : public internal::simdjson_result_base<T> {
181183

182184
/**
183185
* Move the value and the error to the provided variables.
186+
*
187+
* @return true if the value was set, false if there was an error.
184188
*/
185-
really_inline void tie(T& t, error_code & e) && noexcept;
189+
really_inline bool tie(T &value, error_code &error) && noexcept;
186190

187191
/**
188192
* The error.

include/simdjson/inline/element.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ inline simdjson_result<T> simdjson_result<dom::element>::get() const noexcept {
3333
if (error()) { return error(); }
3434
return first.get<T>();
3535
}
36+
template<typename T>
37+
inline bool simdjson_result<dom::element>::get(T &value, error_code &_error) const noexcept {
38+
if (error()) {
39+
_error = error();
40+
return !_error;
41+
} else {
42+
return first.get(value, _error);
43+
}
44+
}
3645

3746
inline simdjson_result<dom::array> simdjson_result<dom::element>::get_array() const noexcept {
3847
if (error()) { return error(); }
@@ -267,6 +276,11 @@ inline simdjson_result<object> element::get_object() const noexcept {
267276
}
268277
}
269278

279+
template<typename T>
280+
inline bool element::get(T &value, error_code &error) const noexcept {
281+
return get<T>().tie(value, error);
282+
}
283+
270284
template<typename T>
271285
inline bool element::is() const noexcept {
272286
auto result = get<T>();

include/simdjson/inline/error.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ namespace internal {
4141
//
4242

4343
template<typename T>
44-
really_inline void simdjson_result_base<T>::tie(T &value, error_code &error) && noexcept {
44+
really_inline bool simdjson_result_base<T>::tie(T &value, error_code &error) && noexcept {
4545
// on the clang compiler that comes with current macOS (Apple clang version 11.0.0),
4646
// tie(width, error) = size["w"].get<uint64_t>();
4747
// fails with "error: no viable overloaded '='""
4848
value = std::forward<simdjson_result_base<T>>(*this).first;
4949
error = this->second;
50+
return !error;
5051
}
5152

5253
template<typename T>
@@ -95,8 +96,8 @@ really_inline simdjson_result_base<T>::simdjson_result_base() noexcept
9596
///
9697

9798
template<typename T>
98-
really_inline void simdjson_result<T>::tie(T &value, error_code &error) && noexcept {
99-
std::forward<internal::simdjson_result_base<T>>(*this).tie(value, error);
99+
really_inline bool simdjson_result<T>::tie(T &value, error_code &error) && noexcept {
100+
return std::forward<internal::simdjson_result_base<T>>(*this).tie(value, error);
100101
}
101102

102103
template<typename T>

tests/basictests.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ namespace parse_api_tests {
677677
if (error) { cerr << error << endl; return false; }
678678

679679
dom::array arr;
680-
doc.get<dom::array>().tie(arr, error); // let us get the array
680+
doc.get(arr, error); // let us get the array
681681
if (error) { cerr << error << endl; return false; }
682682

683683
if(arr.size() != 9) { cerr << "bad array size"<< endl; return false; }
@@ -1033,11 +1033,11 @@ namespace dom_api_tests {
10331033
if (doc["obj"]["a"].get<uint64_t>().first != 1) { cerr << "Expected uint64_t(doc[\"obj\"][\"a\"]) to be 1, was " << doc["obj"]["a"].first << endl; return false; }
10341034

10351035
object obj;
1036-
doc.get<dom::object>().tie(obj, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0
1036+
doc.get(obj, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0
10371037
if (error) { cerr << "Error: " << error << endl; return false; }
10381038
if (obj["obj"]["a"].get<uint64_t>().first != 1) { cerr << "Expected uint64_t(doc[\"obj\"][\"a\"]) to be 1, was " << doc["obj"]["a"].first << endl; return false; }
10391039

1040-
obj["obj"].get<dom::object>().tie(obj, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0
1040+
obj["obj"].get(obj, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0
10411041
if (obj["a"].get<uint64_t>().first != 1) { cerr << "Expected uint64_t(obj[\"a\"]) to be 1, was " << obj["a"].first << endl; return false; }
10421042
if (obj["b"].get<uint64_t>().first != 2) { cerr << "Expected uint64_t(obj[\"b\"]) to be 2, was " << obj["b"].first << endl; return false; }
10431043
if (obj["c/d"].get<uint64_t>().first != 3) { cerr << "Expected uint64_t(obj[\"c\"]) to be 3, was " << obj["c"].first << endl; return false; }
@@ -1071,14 +1071,14 @@ namespace dom_api_tests {
10711071
if (error) { cerr << "Error: " << error << endl; return false; }
10721072
for (auto tweet : tweets) {
10731073
object user;
1074-
tweet["user"].get<dom::object>().tie(user, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
1074+
tweet["user"].get(user, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
10751075
if (error) { cerr << "Error: " << error << endl; return false; }
10761076
bool default_profile;
1077-
user["default_profile"].get<bool>().tie(default_profile, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
1077+
user["default_profile"].get(default_profile, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
10781078
if (error) { cerr << "Error: " << error << endl; return false; }
10791079
if (default_profile) {
10801080
std::string_view screen_name;
1081-
user["screen_name"].get<std::string_view>().tie(screen_name, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
1081+
user["screen_name"].get(screen_name, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
10821082
if (error) { cerr << "Error: " << error << endl; return false; }
10831083
default_users.insert(screen_name);
10841084
}
@@ -1099,13 +1099,13 @@ namespace dom_api_tests {
10991099
if (!not_found) {
11001100
for (auto image : media) {
11011101
object sizes;
1102-
image["sizes"].get<dom::object>().tie(sizes, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
1102+
image["sizes"].get(sizes, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
11031103
if (error) { cerr << "Error: " << error << endl; return false; }
11041104
for (auto size : sizes) {
11051105
uint64_t width, height;
1106-
size.value["w"].get<uint64_t>().tie(width, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
1106+
size.value["w"].get(width, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
11071107
if (error) { cerr << "Error: " << error << endl; return false; }
1108-
size.value["h"].get<uint64_t>().tie(height, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
1108+
size.value["h"].get(height, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
11091109
if (error) { cerr << "Error: " << error << endl; return false; }
11101110
image_sizes.insert(make_pair(width, height));
11111111
}

tests/cast_tester.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ template<typename T>
5858
bool cast_tester<T>::test_get(element element, T expected) {
5959
T actual;
6060
error_code error;
61-
element.get<T>().tie(actual, error);
61+
element.get(actual, error);
6262
ASSERT_SUCCESS(error);
6363
return assert_equal(actual, expected);
6464
}
@@ -67,7 +67,7 @@ template<typename T>
6767
bool cast_tester<T>::test_get(simdjson_result<element> element, T expected) {
6868
T actual;
6969
error_code error;
70-
element.get<T>().tie(actual, error);
70+
element.get(actual, error);
7171
ASSERT_SUCCESS(error);
7272
return assert_equal(actual, expected);
7373
}
@@ -76,7 +76,7 @@ template<typename T>
7676
bool cast_tester<T>::test_get_error(element element, error_code expected_error) {
7777
T actual;
7878
error_code error;
79-
element.get<T>().tie(actual, error);
79+
element.get(actual, error);
8080
ASSERT_EQUAL(error, expected_error);
8181
return true;
8282
}
@@ -85,7 +85,7 @@ template<typename T>
8585
bool cast_tester<T>::test_get_error(simdjson_result<element> element, error_code expected_error) {
8686
T actual;
8787
error_code error;
88-
element.get<T>().tie(actual, error);
88+
element.get(actual, error);
8989
ASSERT_EQUAL(error, expected_error);
9090
return true;
9191
}

tests/extracting_values_example.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ int main() {
66
double value; // variable where we store the value to be parsed
77
simdjson::padded_string numberstring = "1.2"_padded; // our JSON input ("1.2")
88
simdjson::dom::parser parser;
9-
parser.parse(numberstring).get<double>().tie(value,error);
9+
parser.parse(numberstring).get(value,error);
1010
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
1111
std::cout << "I parsed " << value << " from " << numberstring.data() << std::endl;
1212
}

tests/readme_examples.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ void basics_cpp17_2() {
157157
padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded;
158158
dom::object object;
159159
simdjson::error_code error;
160-
parser.parse(json).get<dom::object>().tie(object, error);
160+
parser.parse(json).get(object, error);
161161
for (dom::key_value_pair field : object) {
162162
cout << field.key << " = " << field.value << endl;
163163
}

0 commit comments

Comments
 (0)