Test get<>(), exception vs. no exception, explicit vs. implicit cast

This commit is contained in:
John Keiser 2020-04-14 12:01:26 -07:00
parent 334a486737
commit a3b508ceff
1 changed files with 423 additions and 396 deletions

View File

@ -23,9 +23,17 @@
const char *TWITTER_JSON = SIMDJSON_BENCHMARK_DATA_DIR "twitter.json";
const char *AMAZON_CELLPHONES_NDJSON = SIMDJSON_BENCHMARK_DATA_DIR "amazon_cellphones.ndjson";
#define ASSERT_EQUAL(ACTUAL, EXPECTED) if ((ACTUAL) != (EXPECTED)) { std::cerr << "Expected " << #ACTUAL << " to be " << (EXPECTED) << ", got " << (ACTUAL) << " instead!" << std::endl; return false; }
#define ASSERT_TRUE(ACTUAL) ASSERT_EQUAL(ACTUAL, true)
#define ASSERT_FALSE(ACTUAL) ASSERT_EQUAL(ACTUAL, false)
template<typename T>
bool equals_expected(T actual, T expected) {
return actual == expected;
}
template<>
bool equals_expected<const char *>(const char *actual, const char *expected) {
return !strcmp(actual, expected);
}
#define ASSERT_EQUAL(ACTUAL, EXPECTED) if (!equals_expected(ACTUAL, EXPECTED)) { std::cerr << "Expected " << #ACTUAL << " to be " << (EXPECTED) << ", got " << (ACTUAL) << " instead!" << std::endl; return false; }
#define ASSERT(RESULT, MESSAGE) if (!(RESULT)) { std::cerr << MESSAGE << std::endl; return false; }
#define ASSERT_SUCCESS(ERROR) if (ERROR) { std::cerr << (ERROR) << std::endl; return false; }
namespace number_tests {
@ -1150,449 +1158,468 @@ namespace type_tests {
}
)"_padded;
bool test_array() {
// test_implicit_cast<T>::with(value, [](T value) { return true; })
// Makes it so we test implicit casts for anything that supports them, but *don't* test them
// for const char *
template<typename T>
class test_implicit_cast {
public:
template<typename A, typename F>
static bool with(A input, F const & test);
template<typename A>
static bool error_with(A input, simdjson::error_code expected_error);
};
template<typename T>
template<typename A, typename F>
bool test_implicit_cast<T>::with(A input, F const & test) {
T actual;
actual = input;
return test(actual);
}
template<>
template<typename A, typename F>
bool test_implicit_cast<const char *>::with(A, F const &) {
return true;
}
template<typename T>
template<typename A>
bool test_implicit_cast<T>::error_with(A input, simdjson::error_code expected_error) {
try {
UNUSED T actual;
actual = input;
return false;
} catch(simdjson_error &e) {
ASSERT_EQUAL(e.error(), expected_error);
return true;
}
}
template<>
template<typename A>
bool test_implicit_cast<const char *>::error_with(A, simdjson::error_code) {
return true;
}
template<typename T>
bool test_cast(simdjson_result<dom::element> result, T expected) {
std::cout << " test_cast<" << typeid(T).name() << "> expecting " << expected << std::endl;
// Grab the element out and check success
dom::element element = result.first;
// get<T>() == expected
T actual;
simdjson::error_code error;
result.get<T>().tie(actual, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(actual, expected);
element.get<T>().tie(actual, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(actual, expected);
// is<T>()
bool actual_is;
result.is<T>().tie(actual_is, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(actual_is, true);
actual_is = element.is<T>();
ASSERT_EQUAL(actual_is, true);
#if SIMDJSON_EXCEPTIONS
try {
// T() == expected
actual = T(result);
ASSERT_EQUAL(actual, expected);
actual = T(element);
ASSERT_EQUAL(actual, expected);
test_implicit_cast<T>::with(result, [&](T a) { ASSERT_EQUAL(a, expected); return false; });
test_implicit_cast<T>::with(element, [&](T a) { ASSERT_EQUAL(a, expected); return false; });
// get<T>() == expected
actual = result.get<T>();
ASSERT_EQUAL(actual, expected);
actual = element.get<T>();
ASSERT_EQUAL(actual, expected);
// is<T>()
actual_is = result.is<T>();
ASSERT_EQUAL(actual_is, true);
} catch(simdjson_error &e) {
std::cerr << e.error() << std::endl;
return false;
}
#endif
return true;
}
template<typename T>
bool test_cast(simdjson_result<dom::element> result) {
std::cout << " test_cast<" << typeid(T).name() << "> expecting success" << std::endl;
// Grab the element out and check success
dom::element element = result.first;
// get<T>() == expected
T actual;
simdjson::error_code error;
result.get<T>().tie(actual, error);
ASSERT_SUCCESS(error);
element.get<T>().tie(actual, error);
ASSERT_SUCCESS(error);
// is<T>()
bool actual_is;
result.is<T>().tie(actual_is, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(actual_is, true);
actual_is = element.is<T>();
ASSERT_EQUAL(actual_is, true);
#if SIMDJSON_EXCEPTIONS
try {
// T()
actual = T(result);
actual = T(element);
test_implicit_cast<T>::with(result, [&](T) { return true; });
test_implicit_cast<T>::with(element, [&](T) { return true; });
// get<T>() == expected
actual = result.get<T>();
actual = element.get<T>();
// is<T>()
actual_is = result.is<T>();
ASSERT_EQUAL(actual_is, true);
} catch(simdjson_error &e) {
std::cerr << e.error() << std::endl;
return false;
}
#endif
return true;
}
template<typename T>
bool test_cast(simdjson_result<dom::element> result, simdjson::error_code expected_error) {
std::cout << " test_cast<" << typeid(T).name() << "> expecting error '" << expected_error << "'" << std::endl;
dom::element element = result.first;
// get<T>() == expected
T actual;
simdjson::error_code error;
result.get<T>().tie(actual, error);
ASSERT_EQUAL(error, expected_error);
element.get<T>().tie(actual, error);
ASSERT_EQUAL(error, expected_error);
// is<T>()
bool actual_is;
result.is<T>().tie(actual_is, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(actual_is, false);
actual_is = element.is<T>();
ASSERT_EQUAL(actual_is, false);
#if SIMDJSON_EXCEPTIONS
// T()
try {
actual = T(result);
return false;
} catch(simdjson_error &e) {
ASSERT_EQUAL(e.error(), expected_error);
}
try {
actual = T(element);
return false;
} catch(simdjson_error &e) {
ASSERT_EQUAL(e.error(), expected_error);
}
if (!test_implicit_cast<T>::error_with(result, expected_error)) { return false; }
if (!test_implicit_cast<T>::error_with(result, expected_error)) { return true; }
try {
// is<T>()
actual_is = result.is<T>();
ASSERT_EQUAL(actual_is, false);
} catch(simdjson_error &e) {
std::cerr << e.error() << std::endl;
return false;
}
#endif
return true;
}
bool test_type(simdjson_result<dom::element> result, dom::element_type expected_type) {
std::cout << " test_type() expecting " << expected_type << std::endl;
dom::element element = result.first;
dom::element_type actual_type;
simdjson::error_code error;
result.type().tie(actual_type, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(actual_type, expected_type);
actual_type = element.type();
ASSERT_SUCCESS(error);
ASSERT_EQUAL(actual_type, expected_type);
#if SIMDJSON_EXCEPTIONS
try {
actual_type = result.type();
ASSERT_EQUAL(actual_type, expected_type);
} catch(simdjson_error &e) {
std::cerr << e.error() << std::endl;
return false;
}
#endif // SIMDJSON_EXCEPTIONS
return true;
}
bool test_is_null(simdjson_result<dom::element> result, bool expected_is_null) {
std::cout << " test_is_null() expecting " << expected_is_null << std::endl;
// Grab the element out and check success
dom::element element = result.first;
bool actual_is_null;
simdjson::error_code error;
result.is_null().tie(actual_is_null, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(actual_is_null, expected_is_null);
actual_is_null = element.is_null();
ASSERT_EQUAL(actual_is_null, expected_is_null);
#if SIMDJSON_EXCEPTIONS
try {
actual_is_null = result.is_null();
ASSERT_EQUAL(actual_is_null, expected_is_null);
} catch(simdjson_error &e) {
std::cerr << e.error() << std::endl;
return false;
}
#endif // SIMDJSON_EXCEPTIONS
return true;
}
bool cast_array() {
std::cout << "Running " << __func__ << std::endl;
const auto key = "array";
const auto expected_type = dom::element_type::ARRAY;
dom::parser parser;
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)[key];
ASSERT_SUCCESS(result.error());
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)["array"];
// Test simdjson_result<element>.is<T>() (error chain)
ASSERT_TRUE(result.is<dom::array>());
ASSERT_FALSE(result.is<dom::object>());
ASSERT_FALSE(result.is<std::string_view>());
ASSERT_FALSE(result.is<const char *>());
ASSERT_FALSE(result.is<int64_t>());
ASSERT_FALSE(result.is<uint64_t>());
ASSERT_FALSE(result.is<double>());
ASSERT_FALSE(result.is<bool>());
ASSERT_FALSE(result.is_null());
// Test simdjson_result<element>.type() (error chain)
simdjson::error_code error;
dom::element_type type;
result.type().tie(type, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(type, expected_type);
// Test element.is<T>()
dom::element element = result.first;
ASSERT_TRUE(element.is<dom::array>());
ASSERT_FALSE(element.is<dom::object>());
ASSERT_FALSE(element.is<std::string_view>());
ASSERT_FALSE(element.is<const char *>());
ASSERT_FALSE(element.is<int64_t>());
ASSERT_FALSE(element.is<uint64_t>());
ASSERT_FALSE(element.is<double>());
ASSERT_FALSE(element.is<bool>());
ASSERT_FALSE(element.is_null());
// Test element.type()
ASSERT_EQUAL(element.type(), expected_type);
// Test element.get<T>()
dom::array value;
result.get<dom::array>().tie(value, error);
ASSERT_SUCCESS(error);
return true;
return true
&& test_type(result, dom::element_type::ARRAY)
&& test_cast<dom::array>(result)
&& test_cast<dom::object>(result, INCORRECT_TYPE)
&& test_cast<std::string_view>(result, INCORRECT_TYPE)
&& test_cast<const char *>(result, INCORRECT_TYPE)
&& test_cast<int64_t>(result, INCORRECT_TYPE)
&& test_cast<uint64_t>(result, INCORRECT_TYPE)
&& test_cast<double>(result, INCORRECT_TYPE)
&& test_cast<bool>(result, INCORRECT_TYPE)
&& test_is_null(result, false);
}
bool test_object() {
bool cast_object() {
std::cout << "Running " << __func__ << std::endl;
const auto key = "object";
const auto expected_type = dom::element_type::OBJECT;
dom::parser parser;
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)[key];
ASSERT_SUCCESS(result.error());
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)["object"];
// Test simdjson_result<element>.is<T>() (error chain)
ASSERT_FALSE(result.is<dom::array>());
ASSERT_TRUE(result.is<dom::object>());
ASSERT_FALSE(result.is<std::string_view>());
ASSERT_FALSE(result.is<const char *>());
ASSERT_FALSE(result.is<int64_t>());
ASSERT_FALSE(result.is<uint64_t>());
ASSERT_FALSE(result.is<double>());
ASSERT_FALSE(result.is<bool>());
ASSERT_FALSE(result.is_null());
// Test simdjson_result<element>.type() (error chain)
simdjson::error_code error;
dom::element_type type;
result.type().tie(type, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(type, expected_type);
// Test element.is<T>()
dom::element element = result.first;
ASSERT_FALSE(element.is<dom::array>());
ASSERT_TRUE(element.is<dom::object>());
ASSERT_FALSE(element.is<std::string_view>());
ASSERT_FALSE(element.is<const char *>());
ASSERT_FALSE(element.is<int64_t>());
ASSERT_FALSE(element.is<uint64_t>());
ASSERT_FALSE(element.is<double>());
ASSERT_FALSE(element.is<bool>());
ASSERT_FALSE(element.is_null());
// Test element.type()
ASSERT_EQUAL(element.type(), expected_type);
// Test element.get<T>()
dom::object value;
result.get<dom::object>().tie(value, error);
ASSERT_SUCCESS(error);
return true;
return true
&& test_type(result, dom::element_type::OBJECT)
&& test_cast<dom::array>(result, INCORRECT_TYPE)
&& test_cast<dom::object>(result)
&& test_cast<std::string_view>(result, INCORRECT_TYPE)
&& test_cast<const char *>(result, INCORRECT_TYPE)
&& test_cast<int64_t>(result, INCORRECT_TYPE)
&& test_cast<uint64_t>(result, INCORRECT_TYPE)
&& test_cast<double>(result, INCORRECT_TYPE)
&& test_cast<bool>(result, INCORRECT_TYPE)
&& test_is_null(result, false);
}
bool test_string() {
bool cast_string() {
std::cout << "Running " << __func__ << std::endl;
const auto key = "string";
const auto expected_type = dom::element_type::STRING;
dom::parser parser;
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)[key];
ASSERT_SUCCESS(result.error());
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)["string"];
// Test simdjson_result<element>.is<T>() (error chain)
ASSERT_FALSE(result.is<dom::array>());
ASSERT_FALSE(result.is<dom::object>());
ASSERT_TRUE(result.is<std::string_view>());
ASSERT_TRUE(result.is<const char *>());
ASSERT_FALSE(result.is<int64_t>());
ASSERT_FALSE(result.is<uint64_t>());
ASSERT_FALSE(result.is<double>());
ASSERT_FALSE(result.is<bool>());
ASSERT_FALSE(result.is_null());
// Test simdjson_result<element>.type() (error chain)
simdjson::error_code error;
dom::element_type type;
result.type().tie(type, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(type, expected_type);
// Test element.is<T>()
dom::element element = result.first;
ASSERT_FALSE(element.is<dom::array>());
ASSERT_FALSE(element.is<dom::object>());
ASSERT_TRUE(element.is<std::string_view>());
ASSERT_TRUE(element.is<const char *>());
ASSERT_FALSE(element.is<int64_t>());
ASSERT_FALSE(element.is<uint64_t>());
ASSERT_FALSE(element.is<double>());
ASSERT_FALSE(element.is<bool>());
ASSERT_FALSE(element.is_null());
// Test element.type()
ASSERT_EQUAL(element.type(), expected_type);
// Test element.get<T>()
std::string_view value;
result.get<std::string_view>().tie(value, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(value, string_view("foo"));
const char *value2;
result.get<const char *>().tie(value2, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(string_view(value2), string_view("foo"));
return true;
return true
&& test_type(result, dom::element_type::STRING)
&& test_cast<dom::array>(result, INCORRECT_TYPE)
&& test_cast<dom::object>(result, INCORRECT_TYPE)
&& test_cast<std::string_view>(result, "foo")
&& test_cast<const char *>(result, "foo")
&& test_cast<int64_t>(result, INCORRECT_TYPE)
&& test_cast<uint64_t>(result, INCORRECT_TYPE)
&& test_cast<double>(result, INCORRECT_TYPE)
&& test_cast<bool>(result, INCORRECT_TYPE)
&& test_is_null(result, false);
}
bool test_int64(const char *key, int64_t expected_value) {
bool cast_int64(const char *key, int64_t expected_value) {
std::cout << "Running " << __func__ << "(" << key << ")" << std::endl;
const auto expected_type = dom::element_type::INT64;
dom::parser parser;
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)[key];
ASSERT_SUCCESS(result.error());
// Test simdjson_result<element>.is<T>() (error chain)
ASSERT_FALSE(result.is<dom::array>());
ASSERT_FALSE(result.is<dom::object>());
ASSERT_FALSE(result.is<std::string_view>());
ASSERT_FALSE(result.is<const char *>());
ASSERT_TRUE(result.is<int64_t>());
if (expected_value < 0) {
ASSERT_FALSE(result.is<uint64_t>());
} else {
ASSERT_TRUE(result.is<uint64_t>());
}
ASSERT_TRUE(result.is<double>());
ASSERT_FALSE(result.is<bool>());
ASSERT_FALSE(result.is_null());
// Test simdjson_result<element>.type() (error chain)
simdjson::error_code error;
dom::element_type type;
result.type().tie(type, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(type, expected_type);
// Test element.is<T>()
dom::element element = result.first;
ASSERT_FALSE(element.is<dom::array>());
ASSERT_FALSE(element.is<dom::object>());
ASSERT_FALSE(element.is<std::string_view>());
ASSERT_FALSE(element.is<const char *>());
ASSERT_TRUE(element.is<int64_t>());
if (expected_value < 0) {
ASSERT_FALSE(element.is<uint64_t>());
} else {
ASSERT_TRUE(element.is<uint64_t>());
}
ASSERT_TRUE(element.is<double>());
ASSERT_FALSE(element.is<bool>());
ASSERT_FALSE(element.is_null());
// Test element.type()
ASSERT_EQUAL(element.type(), expected_type);
// Test element.get<T>()
int64_t value;
result.get<int64_t>().tie(value, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(value, expected_value);
return true;
return true
&& test_type(result, dom::element_type::INT64)
&& test_cast<dom::array>(result, INCORRECT_TYPE)
&& test_cast<dom::object>(result, INCORRECT_TYPE)
&& test_cast<std::string_view>(result, INCORRECT_TYPE)
&& test_cast<const char *>(result, INCORRECT_TYPE)
&& test_cast<int64_t>(result, expected_value)
&& (expected_value >= 0 ?
test_cast<uint64_t>(result, expected_value) :
test_cast<uint64_t>(result, NUMBER_OUT_OF_RANGE))
&& test_cast<double>(result, expected_value)
&& test_cast<bool>(result, INCORRECT_TYPE)
&& test_is_null(result, false);
}
bool test_uint64(const char *key, uint64_t expected_value) {
bool cast_uint64(const char *key, uint64_t expected_value) {
std::cout << "Running " << __func__ << "(" << key << ")" << std::endl;
const auto expected_type = dom::element_type::UINT64;
dom::parser parser;
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)[key];
ASSERT_SUCCESS(result.error());
// Test simdjson_result<element>.is<T>() (error chain)
ASSERT_FALSE(result.is<dom::array>());
ASSERT_FALSE(result.is<dom::object>());
ASSERT_FALSE(result.is<std::string_view>());
ASSERT_FALSE(result.is<const char *>());
ASSERT_FALSE(result.is<int64_t>());
ASSERT_TRUE(result.is<uint64_t>());
ASSERT_TRUE(result.is<double>());
ASSERT_FALSE(result.is<bool>());
ASSERT_FALSE(result.is_null());
// Test simdjson_result<element>.type() (error chain)
simdjson::error_code error;
dom::element_type type;
result.type().tie(type, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(type, expected_type);
// Test element.is<T>()
dom::element element = result.first;
ASSERT_FALSE(element.is<dom::array>());
ASSERT_FALSE(element.is<dom::object>());
ASSERT_FALSE(element.is<std::string_view>());
ASSERT_FALSE(element.is<const char *>());
ASSERT_FALSE(element.is<int64_t>());
ASSERT_TRUE(element.is<uint64_t>());
ASSERT_TRUE(element.is<double>());
ASSERT_FALSE(element.is<bool>());
ASSERT_FALSE(element.is_null());
// Test element.type()
ASSERT_EQUAL(element.type(), expected_type);
// Test element.get<T>()
uint64_t value;
result.get<uint64_t>().tie(value, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(value, expected_value);
return true;
return true
&& test_type(result, dom::element_type::UINT64)
&& test_cast<dom::array>(result, INCORRECT_TYPE)
&& test_cast<dom::object>(result, INCORRECT_TYPE)
&& test_cast<std::string_view>(result, INCORRECT_TYPE)
&& test_cast<const char *>(result, INCORRECT_TYPE)
&& test_cast<int64_t>(result, NUMBER_OUT_OF_RANGE)
&& test_cast<uint64_t>(result, expected_value)
&& test_cast<double>(result, expected_value)
&& test_cast<bool>(result, INCORRECT_TYPE)
&& test_is_null(result, false);
}
bool test_double(const char *key, double expected_value) {
bool cast_double(const char *key, double expected_value) {
std::cout << "Running " << __func__ << "(" << key << ")" << std::endl;
const auto expected_type = dom::element_type::DOUBLE;
dom::parser parser;
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)[key];
ASSERT_SUCCESS(result.error());
// Test simdjson_result<element>.is<T>() (error chain)
ASSERT_FALSE(result.is<dom::array>());
ASSERT_FALSE(result.is<dom::object>());
ASSERT_FALSE(result.is<std::string_view>());
ASSERT_FALSE(result.is<const char *>());
ASSERT_FALSE(result.is<int64_t>());
ASSERT_FALSE(result.is<uint64_t>());
ASSERT_TRUE(result.is<double>());
ASSERT_FALSE(result.is<bool>());
ASSERT_FALSE(result.is_null());
// Test simdjson_result<element>.type() (error chain)
simdjson::error_code error;
dom::element_type type;
result.type().tie(type, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(type, expected_type);
// Test element.is<T>()
dom::element element = result.first;
ASSERT_FALSE(element.is<dom::array>());
ASSERT_FALSE(element.is<dom::object>());
ASSERT_FALSE(element.is<std::string_view>());
ASSERT_FALSE(element.is<const char *>());
ASSERT_FALSE(element.is<int64_t>());
ASSERT_FALSE(element.is<uint64_t>());
ASSERT_TRUE(element.is<double>());
ASSERT_FALSE(element.is<bool>());
ASSERT_FALSE(element.is_null());
// Test element.type()
ASSERT_EQUAL(element.type(), expected_type);
// Test element.get<T>()
double value;
result.get<double>().tie(value, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(value, expected_value);
return true;
return true
&& test_type(result, dom::element_type::DOUBLE)
&& test_cast<dom::array>(result, INCORRECT_TYPE)
&& test_cast<dom::object>(result, INCORRECT_TYPE)
&& test_cast<std::string_view>(result, INCORRECT_TYPE)
&& test_cast<const char *>(result, INCORRECT_TYPE)
&& test_cast<int64_t>(result, INCORRECT_TYPE)
&& test_cast<uint64_t>(result, INCORRECT_TYPE)
&& test_cast<double>(result, expected_value)
&& test_cast<bool>(result, INCORRECT_TYPE)
&& test_is_null(result, false);
}
bool test_bool(const char *key, bool expected_value) {
bool cast_bool(const char *key, bool expected_value) {
std::cout << "Running " << __func__ << "(" << key << ")" << std::endl;
const auto expected_type = dom::element_type::BOOL;
dom::parser parser;
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)[key];
ASSERT_SUCCESS(result.error());
// Test simdjson_result<element>.is<T>() (error chain)
ASSERT_FALSE(result.is<dom::array>());
ASSERT_FALSE(result.is<dom::object>());
ASSERT_FALSE(result.is<std::string_view>());
ASSERT_FALSE(result.is<const char *>());
ASSERT_FALSE(result.is<int64_t>());
ASSERT_FALSE(result.is<uint64_t>());
ASSERT_FALSE(result.is<double>());
ASSERT_TRUE(result.is<bool>());
ASSERT_FALSE(result.is_null());
// Test simdjson_result<element>.type() (error chain)
simdjson::error_code error;
dom::element_type type;
result.type().tie(type, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(type, expected_type);
// Test element.is<T>()
dom::element element = result.first;
ASSERT_FALSE(element.is<dom::array>());
ASSERT_FALSE(element.is<dom::object>());
ASSERT_FALSE(element.is<std::string_view>());
ASSERT_FALSE(element.is<const char *>());
ASSERT_FALSE(element.is<int64_t>());
ASSERT_FALSE(element.is<uint64_t>());
ASSERT_FALSE(element.is<double>());
ASSERT_TRUE(element.is<bool>());
ASSERT_FALSE(element.is_null());
// Test element.type()
ASSERT_EQUAL(element.type(), expected_type);
// Test element.get<T>()
bool value;
result.get<bool>().tie(value, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(value, expected_value);
return true;
return true
&& test_type(result, dom::element_type::BOOL)
&& test_cast<dom::array>(result, INCORRECT_TYPE)
&& test_cast<dom::object>(result, INCORRECT_TYPE)
&& test_cast<std::string_view>(result, INCORRECT_TYPE)
&& test_cast<const char *>(result, INCORRECT_TYPE)
&& test_cast<int64_t>(result, INCORRECT_TYPE)
&& test_cast<uint64_t>(result, INCORRECT_TYPE)
&& test_cast<double>(result, INCORRECT_TYPE)
&& test_cast<bool>(result, expected_value)
&& test_is_null(result, false);
}
bool test_null() {
bool cast_null() {
std::cout << "Running " << __func__ << std::endl;
const auto expected_type = dom::element_type::NULL_VALUE;
dom::parser parser;
simdjson_result<dom::element> result = parser.parse(ALL_TYPES_JSON)["null"];
ASSERT_SUCCESS(result.error());
// Test simdjson_result<element>.is<T>() (error chain)
ASSERT_FALSE(result.is<dom::array>());
ASSERT_FALSE(result.is<dom::object>());
ASSERT_FALSE(result.is<std::string_view>());
ASSERT_FALSE(result.is<const char *>());
ASSERT_FALSE(result.is<int64_t>());
ASSERT_FALSE(result.is<uint64_t>());
ASSERT_FALSE(result.is<double>());
ASSERT_FALSE(result.is<bool>());
ASSERT_TRUE(result.is_null());
// Test simdjson_result<element>.type() (error chain)
simdjson::error_code error;
dom::element_type type;
result.type().tie(type, error);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(type, expected_type);
// Test element.is<T>()
dom::element element = result.first;
ASSERT_FALSE(element.is<dom::array>());
ASSERT_FALSE(element.is<dom::object>());
ASSERT_FALSE(element.is<std::string_view>());
ASSERT_FALSE(element.is<const char *>());
ASSERT_FALSE(element.is<int64_t>());
ASSERT_FALSE(element.is<uint64_t>());
ASSERT_FALSE(element.is<double>());
ASSERT_FALSE(element.is<bool>());
ASSERT_TRUE(element.is_null());
// Test element.type()
ASSERT_EQUAL(element.type(), expected_type);
// Test element.get<T>()
return true;
return true
&& test_type(result, dom::element_type::NULL_VALUE)
&& test_cast<dom::array>(result, INCORRECT_TYPE)
&& test_cast<dom::object>(result, INCORRECT_TYPE)
&& test_cast<std::string_view>(result, INCORRECT_TYPE)
&& test_cast<const char *>(result, INCORRECT_TYPE)
&& test_cast<int64_t>(result, INCORRECT_TYPE)
&& test_cast<uint64_t>(result, INCORRECT_TYPE)
&& test_cast<double>(result, INCORRECT_TYPE)
&& test_cast<bool>(result, INCORRECT_TYPE)
&& test_is_null(result, true);
}
bool run() {
return test_array() &&
return cast_array() &&
test_object() &&
cast_object() &&
test_string() &&
cast_string() &&
test_int64("0", 0) &&
test_int64("1", 1) &&
test_int64("-1", -1) &&
test_int64("9223372036854775807", 9223372036854775807LL) &&
test_int64("-9223372036854775808", -1 - 9223372036854775807LL) &&
cast_int64("0", 0) &&
cast_int64("1", 1) &&
cast_int64("-1", -1) &&
cast_int64("9223372036854775807", 9223372036854775807LL) &&
cast_int64("-9223372036854775808", -1 - 9223372036854775807LL) &&
test_uint64("9223372036854775808", 9223372036854775808ULL) &&
test_uint64("18446744073709551615", 18446744073709551615ULL) &&
cast_uint64("9223372036854775808", 9223372036854775808ULL) &&
cast_uint64("18446744073709551615", 18446744073709551615ULL) &&
test_double("0.0", 0.0) &&
test_double("0.1", 0.1) &&
test_double("1e0", 1e0) &&
test_double("1e100", 1e100) &&
cast_double("0.0", 0.0) &&
cast_double("0.1", 0.1) &&
cast_double("1e0", 1e0) &&
cast_double("1e100", 1e100) &&
test_bool("true", true) &&
test_bool("false", false) &&
cast_bool("true", true) &&
cast_bool("false", false) &&
test_null() &&
cast_null() &&
true;
}