Add value.type()
This commit is contained in:
parent
29fe1866ef
commit
2ed24666b5
|
@ -43,12 +43,14 @@ SIMDJSON_DISABLE_UNDESIRED_WARNINGS
|
|||
// Public API
|
||||
#include "simdjson/simdjson_version.h"
|
||||
#include "simdjson/error.h"
|
||||
#include "simdjson/json_type.h"
|
||||
#include "simdjson/minify.h"
|
||||
#include "simdjson/padded_string.h"
|
||||
#include "simdjson/implementation.h"
|
||||
|
||||
// Inline functions
|
||||
#include "simdjson/error-inl.h"
|
||||
#include "simdjson/json_type-inl.h"
|
||||
#include "simdjson/padded_string-inl.h"
|
||||
|
||||
// DOM
|
||||
|
|
|
@ -96,7 +96,7 @@ simdjson_really_inline const T& simdjson_result_base<T>::value_unsafe() const& n
|
|||
|
||||
template<typename T>
|
||||
simdjson_really_inline T&& simdjson_result_base<T>::value_unsafe() && noexcept {
|
||||
return std::forward<T>(this->first);;
|
||||
return std::forward<T>(this->first);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -135,6 +135,13 @@ struct simdjson_result_base : protected std::pair<T, error_code> {
|
|||
*/
|
||||
simdjson_really_inline error_code get(T &value) && noexcept;
|
||||
|
||||
/**
|
||||
* Move the value to the provided variable.
|
||||
*
|
||||
* @param value The variable to assign the value to. May not be set if there is an error.
|
||||
*/
|
||||
simdjson_really_inline const T &value(error_code &error) const & noexcept;
|
||||
|
||||
/**
|
||||
* The error.
|
||||
*/
|
||||
|
|
|
@ -49,6 +49,16 @@ simdjson_really_inline implementation_simdjson_result_base<T>::operator T&&() &&
|
|||
return std::forward<implementation_simdjson_result_base<T>>(*this).take_value();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
simdjson_really_inline const T& implementation_simdjson_result_base<T>::value_unsafe() const& noexcept {
|
||||
return this->first;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
simdjson_really_inline T&& implementation_simdjson_result_base<T>::value_unsafe() && noexcept {
|
||||
return std::forward<T>(this->first);
|
||||
}
|
||||
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -97,6 +97,18 @@ struct implementation_simdjson_result_base {
|
|||
*/
|
||||
simdjson_really_inline operator T&&() && noexcept(false);
|
||||
|
||||
/**
|
||||
* Get the result value. This function is safe if and only
|
||||
* the error() method returns a value that evoluates to false.
|
||||
*/
|
||||
simdjson_really_inline const T& value_unsafe() const& noexcept;
|
||||
|
||||
/**
|
||||
* Take the result value (move it). This function is safe if and only
|
||||
* the error() method returns a value that evoluates to false.
|
||||
*/
|
||||
simdjson_really_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
|
||||
T first{};
|
||||
|
|
|
@ -115,6 +115,10 @@ simdjson_really_inline simdjson_result<value> document::operator[](const char *k
|
|||
return resume_value()[key];
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<json_type> document::type() noexcept {
|
||||
return get_root_value_iterator().type();
|
||||
}
|
||||
|
||||
} // namespace ondemand
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
} // namespace simdjson
|
||||
|
@ -239,6 +243,11 @@ template<> simdjson_really_inline error_code simdjson_result<SIMDJSON_IMPLEMENTA
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<json_type> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::type() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.type();
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
|
|
|
@ -263,6 +263,17 @@ public:
|
|||
/** @overload simdjson_really_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept; */
|
||||
simdjson_really_inline simdjson_result<value> operator[](const char *key) & noexcept;
|
||||
|
||||
/**
|
||||
* Get the type of this JSON value.
|
||||
*
|
||||
* NOTE: If you're only expecting a value to be one type (a typical case), it's generally
|
||||
* better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just
|
||||
* let it throw an exception).
|
||||
*
|
||||
* @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse".
|
||||
*/
|
||||
simdjson_really_inline simdjson_result<json_type> type() noexcept;
|
||||
|
||||
protected:
|
||||
simdjson_really_inline document(ondemand::json_iterator &&iter) noexcept;
|
||||
simdjson_really_inline const uint8_t *text(uint32_t idx) const noexcept;
|
||||
|
@ -337,6 +348,8 @@ public:
|
|||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) & noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) & noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(const char *key) & noexcept;
|
||||
|
||||
simdjson_really_inline simdjson_result<json_type> type() noexcept;
|
||||
};
|
||||
|
||||
} // namespace simdjson
|
||||
|
|
|
@ -117,6 +117,10 @@ simdjson_really_inline simdjson_result<value> value::operator[](const char *key)
|
|||
return start_or_resume_object()[key];
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<json_type> value::type() noexcept {
|
||||
return iter.type();
|
||||
}
|
||||
|
||||
} // namespace ondemand
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
} // namespace simdjson
|
||||
|
@ -230,6 +234,11 @@ template<> simdjson_really_inline error_code simdjson_result<SIMDJSON_IMPLEMENTA
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<json_type> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::type() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.type();
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator SIMDJSON_IMPLEMENTATION::ondemand::array() noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
|
|
|
@ -260,6 +260,17 @@ public:
|
|||
/** @overload simdjson_really_inline simdjson_result<value> find_field_unordered(std::string_view key) noexcept; */
|
||||
simdjson_really_inline simdjson_result<value> operator[](const char *key) noexcept;
|
||||
|
||||
/**
|
||||
* Get the type of this JSON value.
|
||||
*
|
||||
* NOTE: If you're only expecting a value to be one type (a typical case), it's generally
|
||||
* better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just
|
||||
* let it throw an exception).
|
||||
*
|
||||
* @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse".
|
||||
*/
|
||||
simdjson_really_inline simdjson_result<json_type> type() noexcept;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Create a value.
|
||||
|
@ -394,6 +405,15 @@ public:
|
|||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) noexcept;
|
||||
/** @overload simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) noexcept; */
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) noexcept;
|
||||
|
||||
/**
|
||||
* Get the type of this JSON value.
|
||||
*
|
||||
* NOTE: If you're only expecting a value to be one type (a typical case), it's generally
|
||||
* better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just
|
||||
* let it throw an exception).
|
||||
*/
|
||||
simdjson_really_inline simdjson_result<json_type> type() noexcept;
|
||||
};
|
||||
|
||||
} // namespace simdjson
|
||||
|
|
|
@ -568,7 +568,29 @@ simdjson_really_inline void value_iterator::assert_is_valid() const noexcept {
|
|||
}
|
||||
|
||||
simdjson_really_inline bool value_iterator::is_valid() const noexcept {
|
||||
return _json_iter;
|
||||
return _json_iter != nullptr;
|
||||
}
|
||||
|
||||
|
||||
simdjson_really_inline simdjson_result<json_type> value_iterator::type() noexcept {
|
||||
switch (*peek_start()) {
|
||||
case '{':
|
||||
return json_type::object;
|
||||
case '[':
|
||||
return json_type::array;
|
||||
case '"':
|
||||
return json_type::string;
|
||||
case 'n':
|
||||
return json_type::null;
|
||||
case 't': case 'f':
|
||||
return json_type::boolean;
|
||||
case '-':
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
return json_type::number;
|
||||
default:
|
||||
return TAPE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ondemand
|
||||
|
|
|
@ -80,6 +80,13 @@ public:
|
|||
*/
|
||||
simdjson_really_inline depth_t depth() const noexcept;
|
||||
|
||||
/**
|
||||
* Get the JSON type of this value.
|
||||
*
|
||||
* @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse".
|
||||
*/
|
||||
simdjson_really_inline simdjson_result<json_type> type() noexcept;
|
||||
|
||||
/**
|
||||
* @addtogroup object Object iteration
|
||||
*
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef SIMDJSON_JSON_TYPE_INL_H
|
||||
#define SIMDJSON_JSON_TYPE_INL_H
|
||||
|
||||
#include "simdjson/json_type.h"
|
||||
|
||||
namespace simdjson {
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept {
|
||||
switch (type) {
|
||||
case json_type::array: out << "array"; break;
|
||||
case json_type::object: out << "object"; break;
|
||||
case json_type::number: out << "number"; break;
|
||||
case json_type::string: out << "string"; break;
|
||||
case json_type::boolean: out << "boolean"; break;
|
||||
case json_type::null: out << "null"; break;
|
||||
default: SIMDJSON_UNREACHABLE();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
inline std::ostream& operator<<(std::ostream& out, simdjson_result<json_type> &type) noexcept(false) {
|
||||
return out << type.value();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace simdjson
|
||||
|
||||
#endif // SIMDJSON_JSON_TYPE_INL_H
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef SIMDJSON_JSON_TYPE_H
|
||||
#define SIMDJSON_JSON_TYPE_H
|
||||
|
||||
#include "simdjson/common_defs.h"
|
||||
|
||||
namespace simdjson {
|
||||
|
||||
/**
|
||||
* The type of a JSON value.
|
||||
*/
|
||||
enum class json_type {
|
||||
// Start at 1 to catch uninitialized / default values more easily
|
||||
array=1, ///< A JSON array ( [ 1, 2, 3 ... ] )
|
||||
object, ///< A JSON object ( { "a": 1, "b" 2, ... } )
|
||||
number, ///< A JSON number ( 1 or -2.3 or 4.5e6 ...)
|
||||
string, ///< A JSON string ( "a" or "å" or "hello world\n" ...)
|
||||
boolean, ///< A JSON boolean (true or false)
|
||||
null ///< A JSON null (null)
|
||||
};
|
||||
|
||||
/**
|
||||
* Write the JSON type to the output stream
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param type The json_type.
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
/**
|
||||
* Send JSON type to an output stream.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param type The json_type.
|
||||
* @throw simdjson_error if the result being printed has an error. If there is an error with the
|
||||
* underlying output stream, that error will be propagated (simdjson_error will not be
|
||||
* thrown).
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& out, simdjson_result<json_type> &type) noexcept(false);
|
||||
#endif
|
||||
|
||||
} // namespace simdjson
|
||||
|
||||
#endif // SIMDJSON_JSON_TYPE_H
|
|
@ -6,13 +6,14 @@ using namespace simdjson;
|
|||
namespace array_tests {
|
||||
using namespace std;
|
||||
|
||||
bool iterate_array() {
|
||||
bool iterate_document_array() {
|
||||
TEST_START();
|
||||
const auto json = R"([ 1, 10, 100 ])"_padded;
|
||||
const uint64_t expected_value[] = { 1, 10, 100 };
|
||||
|
||||
SUBTEST("ondemand::array", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
ondemand::array array;
|
||||
ASSERT_RESULT( doc_result.type(), json_type::array );
|
||||
ASSERT_SUCCESS( doc_result.get(array) );
|
||||
|
||||
size_t i=0;
|
||||
|
@ -25,16 +26,20 @@ namespace array_tests {
|
|||
ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
|
||||
return true;
|
||||
}));
|
||||
|
||||
SUBTEST("simdjson_result<ondemand::array>", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
simdjson_result<ondemand::array> array = doc_result.get_array();
|
||||
ASSERT_RESULT( doc_result.type(), json_type::array );
|
||||
size_t i=0;
|
||||
for (simdjson_unused auto value : array) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
|
||||
ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
|
||||
return true;
|
||||
}));
|
||||
|
||||
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
ondemand::document doc;
|
||||
ASSERT_SUCCESS( std::move(doc_result).get(doc) );
|
||||
ASSERT_RESULT( doc.type(), json_type::array );
|
||||
size_t i=0;
|
||||
for (simdjson_unused auto value : doc) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
|
||||
ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
|
||||
|
@ -42,6 +47,7 @@ namespace array_tests {
|
|||
}));
|
||||
SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
size_t i=0;
|
||||
ASSERT_RESULT( doc_result.type(), json_type::array );
|
||||
for (simdjson_unused auto value : doc_result) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
|
||||
ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
|
||||
return true;
|
||||
|
@ -49,6 +55,81 @@ namespace array_tests {
|
|||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool iterate_array() {
|
||||
TEST_START();
|
||||
const auto json = R"( [ [ 1, 10, 100 ] ] )"_padded;
|
||||
const uint64_t expected_value[] = { 1, 10, 100 };
|
||||
|
||||
SUBTEST("ondemand::array", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
bool found = false;
|
||||
for (simdjson_result<ondemand::value> array_result : doc_result) {
|
||||
ASSERT_TRUE(!found); found = true;
|
||||
|
||||
ondemand::array array;
|
||||
ASSERT_RESULT( array_result.type(), json_type::array );
|
||||
ASSERT_SUCCESS( array_result.get(array) );
|
||||
|
||||
size_t i=0;
|
||||
for (auto value : array) {
|
||||
int64_t actual;
|
||||
ASSERT_SUCCESS( value.get(actual) );
|
||||
ASSERT_EQUAL(actual, expected_value[i]);
|
||||
i++;
|
||||
}
|
||||
ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
|
||||
}
|
||||
ASSERT_TRUE(found);
|
||||
return true;
|
||||
}));
|
||||
|
||||
SUBTEST("simdjson_result<ondemand::array>", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
bool found = false;
|
||||
for (simdjson_result<ondemand::value> array_result : doc_result) {
|
||||
ASSERT_TRUE(!found); found = true;
|
||||
|
||||
ondemand::array array;
|
||||
ASSERT_RESULT( array_result.type(), json_type::array );
|
||||
ASSERT_SUCCESS( array_result.get(array) );
|
||||
|
||||
size_t i=0;
|
||||
for (simdjson_unused auto value : array) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
|
||||
ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
|
||||
}
|
||||
ASSERT_TRUE(found);
|
||||
return true;
|
||||
}));
|
||||
|
||||
SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
bool found = false;
|
||||
for (simdjson_result<ondemand::value> array_result : doc_result) {
|
||||
ASSERT_TRUE(!found); found = true;
|
||||
|
||||
ondemand::value array;
|
||||
ASSERT_SUCCESS( std::move(array_result).get(array) );
|
||||
ASSERT_RESULT( array.type(), json_type::array );
|
||||
size_t i=0;
|
||||
for (simdjson_unused auto value : array) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
|
||||
ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
|
||||
}
|
||||
ASSERT_TRUE(found);
|
||||
return true;
|
||||
}));
|
||||
SUBTEST("simdjson_result<ondemand::value>", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
bool found = false;
|
||||
for (simdjson_result<ondemand::value> array_result : doc_result) {
|
||||
ASSERT_TRUE(!found); found = true;
|
||||
|
||||
size_t i=0;
|
||||
ASSERT_RESULT( array_result.type(), json_type::array );
|
||||
for (simdjson_unused auto value : array_result) { int64_t actual; ASSERT_SUCCESS( value.get(actual) ); ASSERT_EQUAL(actual, expected_value[i]); i++; }
|
||||
ASSERT_EQUAL(i*sizeof(uint64_t), sizeof(expected_value));
|
||||
}
|
||||
ASSERT_TRUE(found);
|
||||
return true;
|
||||
}));
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool iterate_array_partial_children() {
|
||||
TEST_START();
|
||||
auto json = R"(
|
||||
|
@ -260,6 +341,7 @@ namespace array_tests {
|
|||
bool run() {
|
||||
return
|
||||
iterate_array() &&
|
||||
iterate_document_array() &&
|
||||
iterate_empty_array() &&
|
||||
iterate_array_partial_children() &&
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
|
|
@ -181,11 +181,22 @@ namespace error_tests {
|
|||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool invalid_type() {
|
||||
TEST_START();
|
||||
ONDEMAND_SUBTEST("]", "]", doc.type().error() == TAPE_ERROR);
|
||||
ONDEMAND_SUBTEST("}", "}", doc.type().error() == TAPE_ERROR);
|
||||
ONDEMAND_SUBTEST(":", ":", doc.type().error() == TAPE_ERROR);
|
||||
ONDEMAND_SUBTEST(",", ",", doc.type().error() == TAPE_ERROR);
|
||||
ONDEMAND_SUBTEST("+", "+", doc.type().error() == TAPE_ERROR);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool run() {
|
||||
return
|
||||
empty_document_error() &&
|
||||
get_fail_then_succeed_bool() &&
|
||||
get_fail_then_succeed_null() &&
|
||||
invalid_type() &&
|
||||
true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ namespace object_error_tests {
|
|||
TEST_START();
|
||||
ONDEMAND_SUBTEST("missing comma", R"({ "a": 1 "b": 2 })", ([&]() {
|
||||
auto obj = doc.get_object();
|
||||
return assert_result<int64_t>(obj["a"], 1) && assert_error(obj["b"], TAPE_ERROR);
|
||||
return assert_result(obj["a"], int64_t(1)) && assert_error(obj["b"], TAPE_ERROR);
|
||||
})());
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace object_tests {
|
|||
const uint64_t expected_value[] = { 1, 2, 3 };
|
||||
SUBTEST("ondemand::object", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
ondemand::object object;
|
||||
ASSERT_RESULT( doc_result.type(), json_type::object );
|
||||
ASSERT_SUCCESS( doc_result.get(object) );
|
||||
size_t i = 0;
|
||||
for (auto [ field, error ] : object) {
|
||||
|
|
|
@ -5,18 +5,26 @@ using namespace simdjson;
|
|||
|
||||
namespace scalar_tests {
|
||||
using namespace std;
|
||||
template<typename T> json_type expected_json_type();
|
||||
template<> json_type expected_json_type<std::string_view>() { return json_type::string; }
|
||||
template<> json_type expected_json_type<double>() { return json_type::number; }
|
||||
template<> json_type expected_json_type<uint64_t>() { return json_type::number; }
|
||||
template<> json_type expected_json_type<int64_t>() { return json_type::number; }
|
||||
template<> json_type expected_json_type<bool>() { return json_type::boolean; }
|
||||
|
||||
template<typename T>
|
||||
bool test_scalar_value(const padded_string &json, const T &expected, bool test_twice=true) {
|
||||
std::cout << "- JSON: " << json << endl;
|
||||
SUBTEST( "simdjson_result<document>", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
T actual;
|
||||
ASSERT_RESULT( doc_result.type(), expected_json_type<T>() );
|
||||
ASSERT_SUCCESS( doc_result.get(actual) );
|
||||
ASSERT_EQUAL( expected, actual );
|
||||
ASSERT_EQUAL( actual, expected );
|
||||
// Test it twice (scalars can be retrieved more than once)
|
||||
if (test_twice) {
|
||||
ASSERT_SUCCESS( doc_result.get(actual) );
|
||||
ASSERT_EQUAL( expected, actual );
|
||||
ASSERT_EQUAL( actual, expected );
|
||||
ASSERT_RESULT( doc_result.type(), expected_json_type<T>() );
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
@ -24,12 +32,14 @@ namespace scalar_tests {
|
|||
ondemand::document doc;
|
||||
ASSERT_SUCCESS( std::move(doc_result).get(doc) );
|
||||
T actual;
|
||||
ASSERT_RESULT( doc.type(), expected_json_type<T>() );
|
||||
ASSERT_SUCCESS( doc.get(actual) );
|
||||
ASSERT_EQUAL( expected, actual );
|
||||
ASSERT_EQUAL( actual, expected );
|
||||
// Test it twice (scalars can be retrieved more than once)
|
||||
if (test_twice) {
|
||||
ASSERT_SUCCESS( doc.get(actual) );
|
||||
ASSERT_EQUAL( expected, actual );
|
||||
ASSERT_EQUAL( actual, expected );
|
||||
ASSERT_RESULT( doc.type(), expected_json_type<T>() );
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
@ -39,12 +49,14 @@ namespace scalar_tests {
|
|||
std::cout << "- JSON: " << whitespace_json << endl;
|
||||
SUBTEST( "simdjson_result<document>", test_ondemand_doc(whitespace_json, [&](auto doc_result) {
|
||||
T actual;
|
||||
ASSERT_RESULT( doc_result.type(), expected_json_type<T>() );
|
||||
ASSERT_SUCCESS( doc_result.get(actual) );
|
||||
ASSERT_EQUAL( expected, actual );
|
||||
ASSERT_EQUAL( actual, expected );
|
||||
// Test it twice (scalars can be retrieved more than once)
|
||||
if (test_twice) {
|
||||
ASSERT_SUCCESS( doc_result.get(actual) );
|
||||
ASSERT_EQUAL( expected, actual );
|
||||
ASSERT_EQUAL( actual, expected );
|
||||
ASSERT_RESULT( doc_result.type(), expected_json_type<T>() );
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
@ -52,12 +64,14 @@ namespace scalar_tests {
|
|||
ondemand::document doc;
|
||||
ASSERT_SUCCESS( std::move(doc_result).get(doc) );
|
||||
T actual;
|
||||
ASSERT_RESULT( doc.type(), expected_json_type<T>() );
|
||||
ASSERT_SUCCESS( doc.get(actual) );
|
||||
ASSERT_EQUAL( expected, actual );
|
||||
ASSERT_EQUAL( actual, expected );
|
||||
// Test it twice (scalars can be retrieved more than once)
|
||||
if (test_twice) {
|
||||
ASSERT_SUCCESS( doc.get(actual) );
|
||||
ASSERT_EQUAL( expected, actual );
|
||||
ASSERT_EQUAL( actual, expected );
|
||||
ASSERT_RESULT( doc.type(), expected_json_type<T>() );
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
@ -70,12 +84,14 @@ namespace scalar_tests {
|
|||
int count = 0;
|
||||
for (simdjson_result<ondemand::value> val_result : doc_result) {
|
||||
T actual;
|
||||
ASSERT_RESULT( val_result.type(), expected_json_type<T>() );
|
||||
ASSERT_SUCCESS( val_result.get(actual) );
|
||||
ASSERT_EQUAL(expected, actual);
|
||||
ASSERT_EQUAL(actual, expected);
|
||||
// Test it twice (scalars can be retrieved more than once)
|
||||
if (test_twice) {
|
||||
ASSERT_SUCCESS( val_result.get(actual) );
|
||||
ASSERT_EQUAL(expected, actual);
|
||||
ASSERT_EQUAL(actual, expected);
|
||||
ASSERT_RESULT( val_result.type(), expected_json_type<T>() );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
@ -88,12 +104,14 @@ namespace scalar_tests {
|
|||
ondemand::value val;
|
||||
ASSERT_SUCCESS( val_result.get(val) );
|
||||
T actual;
|
||||
ASSERT_RESULT( val.type(), expected_json_type<T>() );
|
||||
ASSERT_SUCCESS( val.get(actual) );
|
||||
ASSERT_EQUAL(expected, actual);
|
||||
ASSERT_EQUAL(actual, expected);
|
||||
// Test it twice (scalars can be retrieved more than once)
|
||||
if (test_twice) {
|
||||
ASSERT_SUCCESS( val.get(actual) );
|
||||
ASSERT_EQUAL(expected, actual);
|
||||
ASSERT_EQUAL(actual, expected);
|
||||
ASSERT_RESULT( val.type(), expected_json_type<T>() );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
@ -105,34 +123,40 @@ namespace scalar_tests {
|
|||
{
|
||||
padded_string whitespace_array_json = std::string("[") + std::string(json) + " ]";
|
||||
std::cout << "- JSON: " << whitespace_array_json << endl;
|
||||
|
||||
SUBTEST( "simdjson_result<value>", test_ondemand_doc(whitespace_array_json, [&](auto doc_result) {
|
||||
int count = 0;
|
||||
for (simdjson_result<ondemand::value> val_result : doc_result) {
|
||||
T actual;
|
||||
ASSERT_RESULT( val_result.type(), expected_json_type<T>() );
|
||||
ASSERT_SUCCESS( val_result.get(actual) );
|
||||
ASSERT_EQUAL(expected, actual);
|
||||
ASSERT_EQUAL(actual, expected);
|
||||
// Test it twice (scalars can be retrieved more than once)
|
||||
if (test_twice) {
|
||||
ASSERT_SUCCESS( val_result.get(actual) );
|
||||
ASSERT_EQUAL(expected, actual);
|
||||
ASSERT_EQUAL(actual, expected);
|
||||
ASSERT_RESULT( val_result.type(), expected_json_type<T>() );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
ASSERT_EQUAL(count, 1);
|
||||
return true;
|
||||
}));
|
||||
|
||||
SUBTEST( "value", test_ondemand_doc(whitespace_array_json, [&](auto doc_result) {
|
||||
int count = 0;
|
||||
for (simdjson_result<ondemand::value> val_result : doc_result) {
|
||||
ondemand::value val;
|
||||
ASSERT_SUCCESS( val_result.get(val) );
|
||||
T actual;
|
||||
ASSERT_RESULT( val.type(), expected_json_type<T>() );
|
||||
ASSERT_SUCCESS( val.get(actual) );
|
||||
ASSERT_EQUAL(expected, actual);
|
||||
ASSERT_EQUAL(actual, expected);
|
||||
// Test it twice (scalars can be retrieved more than once)
|
||||
if (test_twice) {
|
||||
ASSERT_SUCCESS( val.get(actual) );
|
||||
ASSERT_EQUAL(expected, actual);
|
||||
ASSERT_EQUAL(actual, expected);
|
||||
ASSERT_RESULT( val_result.type(), expected_json_type<T>() );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
@ -227,7 +251,7 @@ namespace scalar_tests {
|
|||
SUBTEST( "value", test_ondemand_doc(array_json, [&](auto doc_result) {
|
||||
int count = 0;
|
||||
for (T actual : doc_result) {
|
||||
ASSERT_EQUAL( expected, actual );
|
||||
ASSERT_EQUAL( actual, expected );
|
||||
count++;
|
||||
}
|
||||
ASSERT_EQUAL(count, 1);
|
||||
|
|
|
@ -31,7 +31,7 @@ bool test_ondemand_doc(const simdjson::padded_string &json, const F& f) {
|
|||
|
||||
#define ONDEMAND_SUBTEST(NAME, JSON, TEST) \
|
||||
{ \
|
||||
std::cout << "- Subtest " << (NAME) << " - JSON: " << (JSON) << " ..." << std::endl; \
|
||||
std::cout << "- Subtest " << NAME << " - JSON: " << (JSON) << " ..." << std::endl; \
|
||||
if (!test_ondemand_doc(JSON##_padded, [&](auto doc) { \
|
||||
return (TEST); \
|
||||
})) { \
|
||||
|
|
|
@ -23,9 +23,9 @@ const char *SMALLDEMO_JSON = SIMDJSON_BENCHMARK_SMALLDATA_DIR "smalldemo.json";
|
|||
const char *TRUENULL_JSON = SIMDJSON_BENCHMARK_SMALLDATA_DIR "truenull.json";
|
||||
|
||||
// For the ASSERT_EQUAL macro
|
||||
template<typename T, typename S>
|
||||
simdjson_really_inline bool equals_expected(T actual, S expected) {
|
||||
return actual == T(expected);
|
||||
template<typename A, typename E>
|
||||
simdjson_really_inline bool equals_expected(A actual, E expected) {
|
||||
return actual == A(expected);
|
||||
}
|
||||
template<>
|
||||
simdjson_really_inline bool equals_expected<const char *, const char *>(const char *actual, const char *expected) {
|
||||
|
@ -76,10 +76,11 @@ simdjson_really_inline bool assert_error(const T &actual_result, simdjson::error
|
|||
}
|
||||
return true;
|
||||
}
|
||||
template<typename E, typename A>
|
||||
template<typename A, typename E>
|
||||
simdjson_really_inline bool assert_result(simdjson::simdjson_result<A> &&actual_result, const E &expected, const char *operation = "result") {
|
||||
E actual;
|
||||
return assert_success(actual_result.get(actual), operation) && assert_equal(actual, expected, operation);
|
||||
return assert_success(std::forward<simdjson::simdjson_result<A>>(actual_result).get(actual))
|
||||
&& assert_equal(actual, expected, operation);
|
||||
}
|
||||
simdjson_really_inline bool assert_true(bool value, const char *operation = "result") {
|
||||
if (!value) {
|
||||
|
@ -102,7 +103,7 @@ simdjson_really_inline bool assert_iterate_error(T &arr, simdjson::error_code ex
|
|||
#define TEST_START() do { std::cout << "Running " << __func__ << " ..." << std::endl; } while(0);
|
||||
#define SUBTEST(NAME, TEST) do { std::cout << "- Subtest " << (NAME) << " ..." << std::endl; if (!(TEST)) { return false; } } while (0);
|
||||
#define ASSERT_EQUAL(ACTUAL, EXPECTED) do { if (!::assert_equal ((ACTUAL), (EXPECTED), #ACTUAL)) { return false; } } while (0);
|
||||
#define ASSERT_RESULT(ACTUAL, EXPECTED) do { if (!::assert_equal ((ACTUAL), (EXPECTED), #ACTUAL)) { return false; } } while (0);
|
||||
#define ASSERT_RESULT(ACTUAL, EXPECTED) do { if (!::assert_result ((ACTUAL), (EXPECTED), #ACTUAL)) { return false; } } while (0);
|
||||
#define ASSERT_SUCCESS(ACTUAL) do { if (!::assert_success((ACTUAL), #ACTUAL)) { return false; } } while (0);
|
||||
#define ASSERT_ERROR(ACTUAL, EXPECTED) do { if (!::assert_error ((ACTUAL), (EXPECTED), #ACTUAL)) { return false; } } while (0);
|
||||
#define ASSERT_TRUE(ACTUAL) do { if (!::assert_true ((ACTUAL), #ACTUAL)) { return false; } } while (0);
|
||||
|
|
Loading…
Reference in New Issue