mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a927fb0129 | |||
| c6fbf5bf78 | |||
| cf86e30b71 | |||
| 207b626f5b | |||
| fe6c5401b0 | |||
| d9545b2d6e | |||
| 6f19ccb81a | |||
| f7bf592f13 | |||
| 677674d54a | |||
| 949bc5142c | |||
| b4d72ff70a | |||
| c8bde7cff0 | |||
| a4e3e386a0 | |||
| c343f6979c | |||
| bee5593cb2 | |||
| dfde6d5e44 | |||
| 414c5858ae | |||
| 142c9a93f8 | |||
| b4e7d717fc | |||
| bba20807be | |||
| 70a68da941 | |||
| e341c8b438 | |||
| 0ac0a80e28 | |||
| 6b9117c029 | |||
| dd92151971 | |||
| 0679c247f4 | |||
| 615218a3ad | |||
| 4c1b0a41d8 | |||
| ef563a4b09 | |||
| 7a9ff93388 | |||
| fc61d7c7ba | |||
| d506af0a79 |
@@ -25,6 +25,7 @@ CompileFlags:
|
|||||||
Diagnostics:
|
Diagnostics:
|
||||||
Suppress:
|
Suppress:
|
||||||
- pp_including_mainfile_in_preamble
|
- pp_including_mainfile_in_preamble
|
||||||
|
- unused-includes
|
||||||
---
|
---
|
||||||
# Amalgamated files that require or partly define an implementation
|
# Amalgamated files that require or partly define an implementation
|
||||||
If:
|
If:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jobs:
|
|||||||
fuzz-seconds: 600
|
fuzz-seconds: 600
|
||||||
dry-run: false
|
dry-run: false
|
||||||
- name: Upload Crash
|
- name: Upload Crash
|
||||||
uses: actions/upload-artifact@v1
|
uses: actions/upload-artifact@v3
|
||||||
if: failure() && steps.build.outcome == 'success'
|
if: failure() && steps.build.outcome == 'success'
|
||||||
with:
|
with:
|
||||||
name: artifacts
|
name: artifacts
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
echo "no trailing whitespace found, good!"
|
echo "no trailing whitespace found, good!"
|
||||||
fi
|
fi
|
||||||
- name: Archive whitespace patch
|
- name: Archive whitespace patch
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: whitespace-patch
|
name: whitespace-patch
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- {gen: Visual Studio 17 2022, arch: x64, build_type: Debug}
|
- {gen: Visual Studio 17 2022, arch: x64, build_type: Debug, cxx: 17}
|
||||||
- {gen: Visual Studio 17 2022, arch: x64, build_type: Release}
|
- {gen: Visual Studio 17 2022, arch: x64, build_type: Debug, cxx: 20}
|
||||||
- {gen: Visual Studio 17 2022, arch: x64, build_type: RelWithDebInfo}
|
- {gen: Visual Studio 17 2022, arch: x64, build_type: Release, cxx: 17}
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: |
|
run: |
|
||||||
cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -T ClangCL -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build
|
cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -DSIMDJSON_CXX_STANDARD=${{matrix.cxx}} -T ClangCL -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build build --config ${{matrix.build_type}} --verbose
|
run: cmake --build build --config ${{matrix.build_type}} --verbose
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
|||||||
Vendored
+5
@@ -110,5 +110,10 @@
|
|||||||
"semaphore": "cpp",
|
"semaphore": "cpp",
|
||||||
"stop_token": "cpp",
|
"stop_token": "cpp",
|
||||||
"cfenv": "cpp"
|
"cfenv": "cpp"
|
||||||
|
},
|
||||||
|
"cmake.configureSettings": {
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS": "YES",
|
||||||
|
"SIMDJSON_DEVELOPER_MODE": "ON",
|
||||||
|
"SIMDJSON_SINGLEHEADER": "OFF"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+14
-5
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
|
|||||||
project(
|
project(
|
||||||
simdjson
|
simdjson
|
||||||
# The version number is modified by tools/release.py
|
# The version number is modified by tools/release.py
|
||||||
VERSION 3.10.0
|
VERSION 3.10.1
|
||||||
DESCRIPTION "Parsing gigabytes of JSON per second"
|
DESCRIPTION "Parsing gigabytes of JSON per second"
|
||||||
HOMEPAGE_URL "https://simdjson.org/"
|
HOMEPAGE_URL "https://simdjson.org/"
|
||||||
LANGUAGES CXX C
|
LANGUAGES CXX C
|
||||||
@@ -23,7 +23,11 @@ string(
|
|||||||
set(SIMDJSON_LIB_VERSION "23.0.0" CACHE STRING "simdjson library version")
|
set(SIMDJSON_LIB_VERSION "23.0.0" CACHE STRING "simdjson library version")
|
||||||
set(SIMDJSON_LIB_SOVERSION "23" CACHE STRING "simdjson library soversion")
|
set(SIMDJSON_LIB_SOVERSION "23" CACHE STRING "simdjson library soversion")
|
||||||
|
|
||||||
option(SIMDJSON_BUILD_STATIC_LIB "Build simdjson_static library along with simdjson" OFF)
|
option(SIMDJSON_BUILD_STATIC_LIB "Build simdjson_static library along with simdjson (only makes sense if BUILD_SHARED_LIBS=ON)" OFF)
|
||||||
|
if(SIMDJSON_BUILD_STATIC_LIB AND NOT BUILD_SHARED_LIBS)
|
||||||
|
message(WARNING "SIMDJSON_BUILD_STATIC_LIB only makes sense if BUILD_SHARED_LIBS is set to ON")
|
||||||
|
message(WARNING "You might be building and installing a two identical static libraries.")
|
||||||
|
endif()
|
||||||
|
|
||||||
option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON)
|
option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON)
|
||||||
|
|
||||||
@@ -51,6 +55,7 @@ endif()
|
|||||||
if(is_top_project)
|
if(is_top_project)
|
||||||
option(SIMDJSON_DEVELOPER_MODE "Enable targets for developing simdjson" OFF)
|
option(SIMDJSON_DEVELOPER_MODE "Enable targets for developing simdjson" OFF)
|
||||||
option(BUILD_SHARED_LIBS "Build simdjson as a shared library" OFF)
|
option(BUILD_SHARED_LIBS "Build simdjson as a shared library" OFF)
|
||||||
|
option(SIMDJSON_SINGLEHEADER "Disable singleheader generation" ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(cmake/handle-deprecations.cmake)
|
include(cmake/handle-deprecations.cmake)
|
||||||
@@ -155,11 +160,13 @@ endif()
|
|||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
install(
|
if(SIMDJSON_SINGLEHEADER)
|
||||||
|
install(
|
||||||
FILES singleheader/simdjson.h
|
FILES singleheader/simdjson.h
|
||||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
COMPONENT simdjson_Development
|
COMPONENT simdjson_Development
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS simdjson
|
TARGETS simdjson
|
||||||
@@ -203,6 +210,7 @@ if(SIMDJSON_BUILD_STATIC_LIB)
|
|||||||
TARGETS simdjson_static
|
TARGETS simdjson_static
|
||||||
EXPORT simdjson_staticTargets
|
EXPORT simdjson_staticTargets
|
||||||
ARCHIVE COMPONENT simdjson_Development
|
ARCHIVE COMPONENT simdjson_Development
|
||||||
|
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
)
|
)
|
||||||
install(
|
install(
|
||||||
EXPORT simdjson_staticTargets
|
EXPORT simdjson_staticTargets
|
||||||
@@ -286,8 +294,9 @@ add_subdirectory(tools) ## This needs to be before tests because of cxxopts
|
|||||||
# most of the data has been moved to https://github.com/simdjson/simdjson-data
|
# most of the data has been moved to https://github.com/simdjson/simdjson-data
|
||||||
add_subdirectory(jsonexamples)
|
add_subdirectory(jsonexamples)
|
||||||
|
|
||||||
|
if(SIMDJSON_SINGLEHEADER)
|
||||||
add_subdirectory(singleheader)
|
add_subdirectory(singleheader)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "3.10.0"
|
PROJECT_NUMBER = "3.10.1"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|||||||
@@ -201,8 +201,8 @@ For the video inclined, <br />
|
|||||||
Funding
|
Funding
|
||||||
-------
|
-------
|
||||||
|
|
||||||
The work is supported by the Natural Sciences and Engineering Research Council of Canada under grant
|
The work is supported by the Natural Sciences and Engineering Research Council of Canada under grants
|
||||||
number RGPIN-2017-03910.
|
RGPIN-2017-03910 and RGPIN-2024-03787.
|
||||||
|
|
||||||
[license]: LICENSE
|
[license]: LICENSE
|
||||||
[license img]: https://img.shields.io/badge/License-Apache%202-blue.svg
|
[license img]: https://img.shields.io/badge/License-Apache%202-blue.svg
|
||||||
|
|||||||
@@ -24,6 +24,35 @@ struct simdjson_ondemand {
|
|||||||
|
|
||||||
BENCHMARK_TEMPLATE(kostya, simdjson_ondemand)->UseManualTime();
|
BENCHMARK_TEMPLATE(kostya, simdjson_ondemand)->UseManualTime();
|
||||||
|
|
||||||
|
|
||||||
|
#if SIMDJSON_SUPPORTS_EXTRACT
|
||||||
|
using namespace simdjson::ondemand;
|
||||||
|
|
||||||
|
struct simdjson_ondemand_extract {
|
||||||
|
static constexpr diff_flags DiffFlags = diff_flags::NONE;
|
||||||
|
|
||||||
|
ondemand::parser parser{};
|
||||||
|
|
||||||
|
bool run(simdjson::padded_string &json, std::vector<point> &result) {
|
||||||
|
auto doc = parser.iterate(json);
|
||||||
|
for (ondemand::object object_point : doc.find_field("coordinates")) {
|
||||||
|
point p;
|
||||||
|
auto error = object_point.extract(
|
||||||
|
to{"x", p.x},
|
||||||
|
to{"y", p.y},
|
||||||
|
to{"z", p.z}
|
||||||
|
);
|
||||||
|
if(error) { return false; }
|
||||||
|
result.push_back(p);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(kostya, simdjson_ondemand_extract)->UseManualTime();
|
||||||
|
|
||||||
|
#endif // SIMDJSON_SUPPORTS_EXTRACT
|
||||||
|
|
||||||
} // namespace kostya
|
} // namespace kostya
|
||||||
|
|
||||||
#endif // SIMDJSON_EXCEPTIONS
|
#endif // SIMDJSON_EXCEPTIONS
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace partial_tweets {
|
|||||||
using namespace simdjson;
|
using namespace simdjson;
|
||||||
|
|
||||||
struct simdjson_ondemand {
|
struct simdjson_ondemand {
|
||||||
using StringType=std::string_view;
|
using StringType = std::string_view;
|
||||||
|
|
||||||
ondemand::parser parser{};
|
ondemand::parser parser{};
|
||||||
|
|
||||||
@@ -43,6 +43,47 @@ struct simdjson_ondemand {
|
|||||||
|
|
||||||
BENCHMARK_TEMPLATE(partial_tweets, simdjson_ondemand)->UseManualTime();
|
BENCHMARK_TEMPLATE(partial_tweets, simdjson_ondemand)->UseManualTime();
|
||||||
|
|
||||||
|
|
||||||
|
#if SIMDJSON_SUPPORTS_EXTRACT
|
||||||
|
using namespace simdjson::ondemand;
|
||||||
|
|
||||||
|
struct simdjson_ondemand_extract {
|
||||||
|
using StringType = std::string_view;
|
||||||
|
ondemand::parser parser{};
|
||||||
|
bool run(simdjson::padded_string &json, std::vector<tweet<std::string_view>> &result) {
|
||||||
|
// Walk the document, parsing the tweets as we go
|
||||||
|
auto doc = parser.iterate(json);
|
||||||
|
for (ondemand::object tweet_object : doc.find_field("statuses")) {
|
||||||
|
tweet<std::string_view> t;
|
||||||
|
auto error = tweet_object.extract(
|
||||||
|
to{"created_at", t.created_at},
|
||||||
|
to{"id", t.id},
|
||||||
|
to{"text", t.result},
|
||||||
|
to{"in_reply_to_status_id", [&t](auto val) {
|
||||||
|
if(val.is_null()) {
|
||||||
|
t.in_reply_to_status_id = 0;
|
||||||
|
} else {
|
||||||
|
t.in_reply_to_status_id = val;
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
to{"user", sub{
|
||||||
|
to{"id", t.user.id},
|
||||||
|
to{"screen_name", t.user.screen_name},
|
||||||
|
}},
|
||||||
|
to{"retweet_count", t.retweet_count},
|
||||||
|
to{"favorite_count", t.favorite_count});
|
||||||
|
if(error) { return false; }
|
||||||
|
result.push_back(t);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(partial_tweets, simdjson_ondemand_extract)->UseManualTime();
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace partial_tweets
|
} // namespace partial_tweets
|
||||||
|
|
||||||
#endif // SIMDJSON_EXCEPTIONS
|
#endif // SIMDJSON_EXCEPTIONS
|
||||||
|
|||||||
+1
-1
@@ -125,7 +125,7 @@ Whitespace Characters:
|
|||||||
- **Nothing**
|
- **Nothing**
|
||||||
|
|
||||||
Some official formats **(non-exhaustive list)**:
|
Some official formats **(non-exhaustive list)**:
|
||||||
- [Newline-Delimited JSON (NDJSON)](http://ndjson.org/)
|
- [Newline-Delimited JSON (NDJSON)](https://github.com/ndjson/ndjson-spec)
|
||||||
- [JSON lines (JSONL)](http://jsonlines.org/)
|
- [JSON lines (JSONL)](http://jsonlines.org/)
|
||||||
- [Record separator-delimited JSON (RFC 7464)](https://tools.ietf.org/html/rfc7464) <- Not supported by JsonStream!
|
- [Record separator-delimited JSON (RFC 7464)](https://tools.ietf.org/html/rfc7464) <- Not supported by JsonStream!
|
||||||
- [More on Wikipedia...](https://en.wikipedia.org/wiki/JSON_streaming)
|
- [More on Wikipedia...](https://en.wikipedia.org/wiki/JSON_streaming)
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ double from_chars(const char *first, const char* end) noexcept;
|
|||||||
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
|
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
|
||||||
|
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
|
// We could use [[deprecated]] but it requires C++14
|
||||||
|
#define simdjson_deprecated __declspec(deprecated)
|
||||||
|
|
||||||
#define simdjson_really_inline __forceinline
|
#define simdjson_really_inline __forceinline
|
||||||
#define simdjson_never_inline __declspec(noinline)
|
#define simdjson_never_inline __declspec(noinline)
|
||||||
@@ -88,6 +90,8 @@ double from_chars(const char *first, const char* end) noexcept;
|
|||||||
#define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS
|
#define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS
|
||||||
|
|
||||||
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
|
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
|
// We could use [[deprecated]] but it requires C++14
|
||||||
|
#define simdjson_deprecated __attribute__((deprecated))
|
||||||
|
|
||||||
#define simdjson_really_inline inline __attribute__((always_inline))
|
#define simdjson_really_inline inline __attribute__((always_inline))
|
||||||
#define simdjson_never_inline inline __attribute__((noinline))
|
#define simdjson_never_inline inline __attribute__((noinline))
|
||||||
|
|||||||
@@ -50,4 +50,18 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include(<version>)
|
||||||
|
#include <version>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__cpp_concepts)
|
||||||
|
#define SIMDJSON_SUPPORTS_EXTRACT 1
|
||||||
|
#else
|
||||||
|
#define SIMDJSON_SUPPORTS_EXTRACT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // SIMDJSON_COMPILER_CHECK_H
|
#endif // SIMDJSON_COMPILER_CHECK_H
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace simdjson {
|
|||||||
namespace fallback {
|
namespace fallback {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(_M_ARM64) && !defined(_M_X64)
|
#if SIMDJSON_REGULAR_VISUAL_STUDIO && !defined(_M_ARM64) && !defined(_M_X64)
|
||||||
static inline unsigned char _BitScanForward64(unsigned long* ret, uint64_t x) {
|
static inline unsigned char _BitScanForward64(unsigned long* ret, uint64_t x) {
|
||||||
unsigned long x0 = (unsigned long)x, top, bottom;
|
unsigned long x0 = (unsigned long)x, top, bottom;
|
||||||
_BitScanForward(&top, (unsigned long)(x >> 32));
|
_BitScanForward(&top, (unsigned long)(x >> 32));
|
||||||
@@ -28,7 +28,7 @@ static unsigned char _BitScanReverse64(unsigned long* ret, uint64_t x) {
|
|||||||
|
|
||||||
/* result might be undefined when input_num is zero */
|
/* result might be undefined when input_num is zero */
|
||||||
simdjson_inline int leading_zeroes(uint64_t input_num) {
|
simdjson_inline int leading_zeroes(uint64_t input_num) {
|
||||||
#ifdef _MSC_VER
|
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
unsigned long leading_zero = 0;
|
unsigned long leading_zero = 0;
|
||||||
// Search the mask data from most significant bit (MSB)
|
// Search the mask data from most significant bit (MSB)
|
||||||
// to least significant bit (LSB) for a set bit (1).
|
// to least significant bit (LSB) for a set bit (1).
|
||||||
@@ -38,7 +38,7 @@ simdjson_inline int leading_zeroes(uint64_t input_num) {
|
|||||||
return 64;
|
return 64;
|
||||||
#else
|
#else
|
||||||
return __builtin_clzll(input_num);
|
return __builtin_clzll(input_num);
|
||||||
#endif// _MSC_VER
|
#endif// SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|||||||
@@ -3,16 +3,14 @@
|
|||||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
#define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H
|
#define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H
|
||||||
#include "simdjson/generic/ondemand/base.h"
|
#include "simdjson/generic/ondemand/base.h"
|
||||||
#include "simdjson/generic/ondemand/array-inl.h"
|
|
||||||
#include "simdjson/generic/ondemand/array_iterator.h"
|
#include "simdjson/generic/ondemand/array_iterator.h"
|
||||||
#include "simdjson/generic/ondemand/document.h"
|
#include "simdjson/generic/ondemand/document.h"
|
||||||
#include "simdjson/generic/ondemand/json_iterator-inl.h"
|
|
||||||
#include "simdjson/generic/ondemand/json_path_to_pointer_conversion.h"
|
|
||||||
#include "simdjson/generic/ondemand/json_path_to_pointer_conversion-inl.h"
|
|
||||||
#include "simdjson/generic/ondemand/json_type.h"
|
#include "simdjson/generic/ondemand/json_type.h"
|
||||||
#include "simdjson/generic/ondemand/object-inl.h"
|
|
||||||
#include "simdjson/generic/ondemand/raw_json_string.h"
|
#include "simdjson/generic/ondemand/raw_json_string.h"
|
||||||
#include "simdjson/generic/ondemand/value.h"
|
#include "simdjson/generic/ondemand/value.h"
|
||||||
|
#include "simdjson/generic/ondemand/array-inl.h"
|
||||||
|
#include "simdjson/generic/ondemand/json_iterator-inl.h"
|
||||||
|
#include "simdjson/generic/ondemand/object-inl.h"
|
||||||
#include "simdjson/generic/ondemand/value_iterator-inl.h"
|
#include "simdjson/generic/ondemand/value_iterator-inl.h"
|
||||||
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
@@ -167,24 +165,26 @@ template<> simdjson_inline simdjson_result<int64_t> document::get() & noexcept {
|
|||||||
template<> simdjson_inline simdjson_result<bool> document::get() & noexcept { return get_bool(); }
|
template<> simdjson_inline simdjson_result<bool> document::get() & noexcept { return get_bool(); }
|
||||||
template<> simdjson_inline simdjson_result<value> document::get() & noexcept { return get_value(); }
|
template<> simdjson_inline simdjson_result<value> document::get() & noexcept { return get_value(); }
|
||||||
|
|
||||||
template<> simdjson_inline simdjson_result<raw_json_string> document::get() && noexcept { return get_raw_json_string(); }
|
template<> simdjson_deprecated simdjson_inline simdjson_result<raw_json_string> document::get() && noexcept { return get_raw_json_string(); }
|
||||||
template<> simdjson_inline simdjson_result<std::string_view> document::get() && noexcept { return get_string(false); }
|
template<> simdjson_deprecated simdjson_inline simdjson_result<std::string_view> document::get() && noexcept { return get_string(false); }
|
||||||
template<> simdjson_inline simdjson_result<double> document::get() && noexcept { return std::forward<document>(*this).get_double(); }
|
template<> simdjson_deprecated simdjson_inline simdjson_result<double> document::get() && noexcept { return std::forward<document>(*this).get_double(); }
|
||||||
template<> simdjson_inline simdjson_result<uint64_t> document::get() && noexcept { return std::forward<document>(*this).get_uint64(); }
|
template<> simdjson_deprecated simdjson_inline simdjson_result<uint64_t> document::get() && noexcept { return std::forward<document>(*this).get_uint64(); }
|
||||||
template<> simdjson_inline simdjson_result<int64_t> document::get() && noexcept { return std::forward<document>(*this).get_int64(); }
|
template<> simdjson_deprecated simdjson_inline simdjson_result<int64_t> document::get() && noexcept { return std::forward<document>(*this).get_int64(); }
|
||||||
template<> simdjson_inline simdjson_result<bool> document::get() && noexcept { return std::forward<document>(*this).get_bool(); }
|
template<> simdjson_deprecated simdjson_inline simdjson_result<bool> document::get() && noexcept { return std::forward<document>(*this).get_bool(); }
|
||||||
template<> simdjson_inline simdjson_result<value> document::get() && noexcept { return get_value(); }
|
template<> simdjson_deprecated simdjson_inline simdjson_result<value> document::get() && noexcept { return get_value(); }
|
||||||
|
|
||||||
template<typename T> simdjson_inline error_code document::get(T &out) & noexcept {
|
template<typename T> simdjson_inline error_code document::get(T &out) & noexcept {
|
||||||
return get<T>().get(out);
|
return get<T>().get(out);
|
||||||
}
|
}
|
||||||
template<typename T> simdjson_inline error_code document::get(T &out) && noexcept {
|
template<typename T> simdjson_deprecated simdjson_inline error_code document::get(T &out) && noexcept {
|
||||||
return std::forward<document>(*this).get<T>().get(out);
|
return std::forward<document>(*this).get<T>().get(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SIMDJSON_EXCEPTIONS
|
#if SIMDJSON_EXCEPTIONS
|
||||||
template <class T>
|
template <class T>
|
||||||
simdjson_inline document::operator T() noexcept(false) { return get<T>(); }
|
simdjson_deprecated simdjson_inline document::operator T() && noexcept(false) { return get<T>(); }
|
||||||
|
template <class T>
|
||||||
|
simdjson_inline document::operator T() & noexcept(false) { return get<T>(); }
|
||||||
simdjson_inline document::operator array() & noexcept(false) { return get_array(); }
|
simdjson_inline document::operator array() & noexcept(false) { return get_array(); }
|
||||||
simdjson_inline document::operator object() & noexcept(false) { return get_object(); }
|
simdjson_inline document::operator object() & noexcept(false) { return get_object(); }
|
||||||
simdjson_inline document::operator uint64_t() noexcept(false) { return get_uint64(); }
|
simdjson_inline document::operator uint64_t() noexcept(false) { return get_uint64(); }
|
||||||
@@ -471,7 +471,7 @@ simdjson_inline simdjson_result<T> simdjson_result<SIMDJSON_IMPLEMENTATION::onde
|
|||||||
return first.get<T>();
|
return first.get<T>();
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
simdjson_inline simdjson_result<T> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get() && noexcept {
|
simdjson_deprecated simdjson_inline simdjson_result<T> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get() && noexcept {
|
||||||
if (error()) { return error(); }
|
if (error()) { return error(); }
|
||||||
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::document>(first).get<T>();
|
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::document>(first).get<T>();
|
||||||
}
|
}
|
||||||
@@ -487,7 +487,7 @@ simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::do
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<> simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get<SIMDJSON_IMPLEMENTATION::ondemand::document>() & noexcept = delete;
|
template<> simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get<SIMDJSON_IMPLEMENTATION::ondemand::document>() & noexcept = delete;
|
||||||
template<> simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get<SIMDJSON_IMPLEMENTATION::ondemand::document>() && noexcept {
|
template<> simdjson_deprecated simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get<SIMDJSON_IMPLEMENTATION::ondemand::document>() && noexcept {
|
||||||
if (error()) { return error(); }
|
if (error()) { return error(); }
|
||||||
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::document>(first);
|
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::document>(first);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ public:
|
|||||||
" You may also add support for custom types, see our documentation.");
|
" You may also add support for custom types, see our documentation.");
|
||||||
}
|
}
|
||||||
/** @overload template<typename T> simdjson_result<T> get() & noexcept */
|
/** @overload template<typename T> simdjson_result<T> get() & noexcept */
|
||||||
template<typename T> simdjson_inline simdjson_result<T> get() && noexcept {
|
template<typename T> simdjson_deprecated simdjson_inline simdjson_result<T> get() && noexcept {
|
||||||
// Unless the simdjson library or the user provides an inline implementation, calling this method should
|
// Unless the simdjson library or the user provides an inline implementation, calling this method should
|
||||||
// immediately fail.
|
// immediately fail.
|
||||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
|
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
|
||||||
@@ -211,7 +211,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
template<typename T> simdjson_inline error_code get(T &out) & noexcept;
|
template<typename T> simdjson_inline error_code get(T &out) & noexcept;
|
||||||
/** @overload template<typename T> error_code get(T &out) & noexcept */
|
/** @overload template<typename T> error_code get(T &out) & noexcept */
|
||||||
template<typename T> simdjson_inline error_code get(T &out) && noexcept;
|
template<typename T> simdjson_deprecated simdjson_inline error_code get(T &out) && noexcept;
|
||||||
|
|
||||||
#if SIMDJSON_EXCEPTIONS
|
#if SIMDJSON_EXCEPTIONS
|
||||||
/**
|
/**
|
||||||
@@ -224,7 +224,10 @@ public:
|
|||||||
* @returns An instance of type T
|
* @returns An instance of type T
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
explicit simdjson_inline operator T() noexcept(false);
|
explicit simdjson_inline operator T() & noexcept(false);
|
||||||
|
template <class T>
|
||||||
|
explicit simdjson_deprecated simdjson_inline operator T() && noexcept(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast this JSON value to an array.
|
* Cast this JSON value to an array.
|
||||||
*
|
*
|
||||||
@@ -790,7 +793,7 @@ public:
|
|||||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||||
|
|
||||||
template<typename T> simdjson_inline simdjson_result<T> get() & noexcept;
|
template<typename T> simdjson_inline simdjson_result<T> get() & noexcept;
|
||||||
template<typename T> simdjson_inline simdjson_result<T> get() && noexcept;
|
template<typename T> simdjson_deprecated simdjson_inline simdjson_result<T> get() && noexcept;
|
||||||
|
|
||||||
template<typename T> simdjson_inline error_code get(T &out) & noexcept;
|
template<typename T> simdjson_inline error_code get(T &out) & noexcept;
|
||||||
template<typename T> simdjson_inline error_code get(T &out) && noexcept;
|
template<typename T> simdjson_inline error_code get(T &out) && noexcept;
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ private:
|
|||||||
friend class document;
|
friend class document;
|
||||||
friend class json_iterator;
|
friend class json_iterator;
|
||||||
friend struct simdjson_result<ondemand::document_stream>;
|
friend struct simdjson_result<ondemand::document_stream>;
|
||||||
friend struct internal::simdjson_result_base<ondemand::document_stream>;
|
friend struct simdjson::internal::simdjson_result_base<ondemand::document_stream>;
|
||||||
}; // document_stream
|
}; // document_stream
|
||||||
|
|
||||||
} // namespace ondemand
|
} // namespace ondemand
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef SIMDJSON_ONDEMAND_GENERIC_JSON_PATH_TO_POINTER_CONVERSION_INL_H
|
|
||||||
#define SIMDJSON_ONDEMAND_GENERIC_JSON_PATH_TO_POINTER_CONVERSION_INL_H
|
|
||||||
|
|
||||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
|
||||||
#define SIMDJSON_GENERIC_ONDEMAND_JSON_PATH_TO_POINTER_CONVERSION_INL_H
|
|
||||||
#include "simdjson/generic/ondemand/json_path_to_pointer_conversion.h"
|
|
||||||
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
|
||||||
|
|
||||||
namespace simdjson {
|
|
||||||
namespace SIMDJSON_IMPLEMENTATION {}
|
|
||||||
namespace ondemand {
|
|
||||||
|
|
||||||
simdjson_inline std::string json_path_to_pointer_conversion(std::string_view json_path) {
|
|
||||||
if (json_path.empty() || (json_path.front() != '.' && json_path.front() != '[') {
|
|
||||||
return "-1"; // Sentinel value to be handled as an error by the caller.
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string result;
|
|
||||||
// Reserve space to reduce allocations, adjusting for potential increases due
|
|
||||||
// to escaping.
|
|
||||||
result.reserve(json_path.size() * 2);
|
|
||||||
|
|
||||||
// Skip the initial '.' as it's assumed every path starts with it.
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
while (i < json_path.length()) {
|
|
||||||
if (json_path[i] == '.') {
|
|
||||||
result += '/';
|
|
||||||
} else if (json_path[i] == '[') {
|
|
||||||
result += '/';
|
|
||||||
++i; // Move past the '['
|
|
||||||
while (i < json_path.length() && json_path[i] != ']') {
|
|
||||||
if (json_path[i] == '~') {
|
|
||||||
result += "~0";
|
|
||||||
} else if (json_path[i] == '/') {
|
|
||||||
result += "~1";
|
|
||||||
} else {
|
|
||||||
result += json_path[i];
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
if (i == json_path.length() || json_path[i] != ']') {
|
|
||||||
return "-1"; // Returning sentinel value that will be handled as an error by the caller
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (json_path[i] == '~') {
|
|
||||||
result += "~0";
|
|
||||||
} else if (json_path[i] == '/') {
|
|
||||||
result += "~1";
|
|
||||||
} else {
|
|
||||||
result += json_path[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return simdjson_result<std::string>(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace ondemand
|
|
||||||
} // namespace SIMDJSON_IMPLEMENTATION
|
|
||||||
} // namespace simdjson
|
|
||||||
|
|
||||||
#endif // SIMDJSON_ONDEMAND_GENERIC_JSON_PATH_TO_POINTER_CONVERSION_INL_H
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef SIMDJSON_ONDEMAND_GENERIC_JSON_PATH_TO_POINTER_CONVERSION_H
|
|
||||||
#define SIMDJSON_ONDEMAND_GENERIC_JSON_PATH_TO_POINTER_CONVERSION_H
|
|
||||||
|
|
||||||
namespace simdjson {
|
|
||||||
namespace SIMDJSON_IMPLEMENTATION {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts JSONPath to JSON Pointer.
|
|
||||||
* @param json_path The JSONPath string to be converted.
|
|
||||||
* @return A string containing the equivalent JSON Pointer.
|
|
||||||
* @throws simdjson_error If the conversion fails.
|
|
||||||
*/
|
|
||||||
simdjson_inline std::string json_path_to_pointer_conversion(std::string_view json_path);
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace SIMDJSON_IMPLEMENTATION
|
|
||||||
} // namespace simdjson
|
|
||||||
|
|
||||||
#endif // SIMDJSON_JSON_PATH_TO_POINTER_CONVERSION_H
|
|
||||||
@@ -15,6 +15,141 @@ namespace simdjson {
|
|||||||
namespace SIMDJSON_IMPLEMENTATION {
|
namespace SIMDJSON_IMPLEMENTATION {
|
||||||
namespace ondemand {
|
namespace ondemand {
|
||||||
|
|
||||||
|
|
||||||
|
#if SIMDJSON_SUPPORTS_EXTRACT
|
||||||
|
|
||||||
|
|
||||||
|
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
|
template <endpoint ...Funcs>
|
||||||
|
simdjson_inline error_code object::extract(Funcs&&... endpoints) {
|
||||||
|
return iter.on_field_raw([&, eps = std::make_tuple(std::forward<Funcs>(endpoints)...)](auto field_key, error_code& error) mutable {
|
||||||
|
std::apply([&](auto &...endpoints) {
|
||||||
|
std::ignore = ((field_key.unsafe_is_equal(endpoints.key()) ? (error = endpoints(value(iter.child()))) == SUCCESS : true) && ...);
|
||||||
|
}, eps);
|
||||||
|
if (error) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <endpoint ...Funcs>
|
||||||
|
simdjson_inline error_code object::extract(Funcs&&... endpoints) noexcept((nothrow_endpoint<Funcs> && ...)) {
|
||||||
|
return iter.on_field_raw([&](auto field_key, error_code& error) noexcept((nothrow_endpoint<Funcs> && ...)) {
|
||||||
|
std::ignore = ((field_key.unsafe_is_equal(endpoints.key()) ? (error = endpoints(value(iter.child()))) == SUCCESS : true) && ...);
|
||||||
|
if (error) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct to {
|
||||||
|
private:
|
||||||
|
T *pointer;
|
||||||
|
std::string_view m_key;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr explicit(false)
|
||||||
|
to(std::string_view const inp_key, T &obj_ref) noexcept
|
||||||
|
: pointer{std::addressof(obj_ref)}, m_key{inp_key} {}
|
||||||
|
|
||||||
|
constexpr to(to const &) = default;
|
||||||
|
constexpr to(to &&) noexcept = default;
|
||||||
|
constexpr to &operator=(to const &) = default;
|
||||||
|
constexpr to &operator=(to &&) noexcept = default;
|
||||||
|
constexpr ~to() = default;
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr std::string_view key() const noexcept {
|
||||||
|
return m_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr error_code operator()(simdjson_result<value> val) noexcept(
|
||||||
|
std::is_nothrow_assignable_v<T, simdjson_result<value>>) {
|
||||||
|
return val.get<T>(*pointer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
requires(std::is_invocable_v<Func, simdjson_result<value>>)
|
||||||
|
struct to<Func> {
|
||||||
|
private:
|
||||||
|
Func func;
|
||||||
|
std::string_view m_key;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr explicit(false)
|
||||||
|
to(std::string_view const inp_key,
|
||||||
|
Func &&inp_func) noexcept(std::is_nothrow_copy_assignable_v<Func>)
|
||||||
|
: func{std::forward<Func>(inp_func)}, m_key{inp_key} {}
|
||||||
|
|
||||||
|
constexpr to(to const &) = default;
|
||||||
|
constexpr to(to &&) noexcept = default;
|
||||||
|
constexpr to& operator=(to const &) = default;
|
||||||
|
constexpr to& operator=(to &&) noexcept = default;
|
||||||
|
constexpr ~to() = default;
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr std::string_view key() const noexcept {
|
||||||
|
return m_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr error_code operator()(simdjson_result<value> val) noexcept(
|
||||||
|
std::is_nothrow_invocable_v<Func, simdjson_result<value>>) {
|
||||||
|
if constexpr (std::is_invocable_r_v<error_code, Func, simdjson_result<value>>) {
|
||||||
|
return func(val);
|
||||||
|
} else {
|
||||||
|
static_cast<void>(func(val));
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
requires(std::is_invocable_v<Func, simdjson_result<value>>)
|
||||||
|
to(std::string_view, Func &&) -> to<Func>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
to(std::string_view, T&) -> to<T>;
|
||||||
|
|
||||||
|
template <endpoint... Tos>
|
||||||
|
struct sub {
|
||||||
|
private:
|
||||||
|
using tuple_type = std::tuple<Tos...>;
|
||||||
|
tuple_type tos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// double templating to make perfect forwarding work
|
||||||
|
template <typename ...T>
|
||||||
|
requires ((std::same_as<T, Tos> && ...))
|
||||||
|
explicit constexpr sub(T&&...inp_tos) noexcept(std::is_nothrow_constructible_v<tuple_type, T...>)
|
||||||
|
: tos{std::forward<T>(inp_tos)...} {}
|
||||||
|
|
||||||
|
constexpr sub(sub const &) = default;
|
||||||
|
constexpr sub(sub &&) noexcept = default;
|
||||||
|
constexpr sub &operator=(sub const &) = default;
|
||||||
|
constexpr sub &operator=(sub &&) = default;
|
||||||
|
constexpr ~sub() = default;
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr error_code operator()(simdjson_result<value> val) noexcept((nothrow_endpoint<Tos> && ...)) {
|
||||||
|
object obj;
|
||||||
|
if (auto const err = val.get_object().get(obj); err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return std::apply([&obj]<typename... T>(T &&...app_tos) {
|
||||||
|
return obj.extract(std::forward<T>(app_tos)...);
|
||||||
|
}, tos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <endpoint... Tos>
|
||||||
|
sub(Tos&&...) -> sub<Tos...>;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
simdjson_inline simdjson_result<value> object::find_field_unordered(const std::string_view key) & noexcept {
|
simdjson_inline simdjson_result<value> object::find_field_unordered(const std::string_view key) & noexcept {
|
||||||
bool has_value;
|
bool has_value;
|
||||||
SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) );
|
SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) );
|
||||||
|
|||||||
@@ -11,6 +11,19 @@ namespace simdjson {
|
|||||||
namespace SIMDJSON_IMPLEMENTATION {
|
namespace SIMDJSON_IMPLEMENTATION {
|
||||||
namespace ondemand {
|
namespace ondemand {
|
||||||
|
|
||||||
|
#if SIMDJSON_SUPPORTS_EXTRACT
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept endpoint = std::is_invocable_r_v<error_code, T, simdjson_result<value>> &&
|
||||||
|
std::is_copy_constructible_v<T> && requires(T to) {
|
||||||
|
{ to.key() } noexcept -> std::convertible_to<std::string_view>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept nothrow_endpoint = endpoint<T> && std::is_nothrow_invocable_r_v<error_code, T, simdjson_result<value>>;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A forward-only JSON object field iterator.
|
* A forward-only JSON object field iterator.
|
||||||
*/
|
*/
|
||||||
@@ -65,6 +78,21 @@ public:
|
|||||||
/** @overload simdjson_inline simdjson_result<value> find_field(std::string_view key) & noexcept; */
|
/** @overload simdjson_inline simdjson_result<value> find_field(std::string_view key) & noexcept; */
|
||||||
simdjson_inline simdjson_result<value> find_field(std::string_view key) && noexcept;
|
simdjson_inline simdjson_result<value> find_field(std::string_view key) && noexcept;
|
||||||
|
|
||||||
|
#if SIMDJSON_SUPPORTS_EXTRACT
|
||||||
|
/**
|
||||||
|
* Extract all the fields in one go
|
||||||
|
* Funcs are invocables that take a simdjson_result<value> as input.
|
||||||
|
*/
|
||||||
|
template <endpoint ...Funcs>
|
||||||
|
simdjson_inline error_code extract(Funcs&&... endpoints)
|
||||||
|
#ifndef SIMDJSON_REGULAR_VISUAL_STUDIO // msvc thinks noexcept is not the same in definition
|
||||||
|
noexcept((nothrow_endpoint<Funcs> && ...))
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up a field by name on an object, without regard to key order.
|
* Look up a field by name on an object, without regard to key order.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/** @private [for benchmarking access] The implementation to use */
|
/** @private [for benchmarking access] The implementation to use */
|
||||||
std::unique_ptr<internal::dom_parser_implementation> implementation{};
|
std::unique_ptr<simdjson::internal::dom_parser_implementation> implementation{};
|
||||||
size_t _capacity{0};
|
size_t _capacity{0};
|
||||||
size_t _max_capacity;
|
size_t _max_capacity;
|
||||||
size_t _max_depth{DEFAULT_MAX_DEPTH};
|
size_t _max_depth{DEFAULT_MAX_DEPTH};
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
#include "simdjson/generic/ondemand/array.h"
|
#include "simdjson/generic/ondemand/array.h"
|
||||||
#include "simdjson/generic/ondemand/array_iterator.h"
|
#include "simdjson/generic/ondemand/array_iterator.h"
|
||||||
#include "simdjson/generic/ondemand/json_iterator.h"
|
#include "simdjson/generic/ondemand/json_iterator.h"
|
||||||
#include "simdjson/generic/ondemand/json_path_to_pointer_conversion.h"
|
|
||||||
#include "simdjson/generic/ondemand/json_path_to_pointer_conversion-inl.h"
|
|
||||||
#include "simdjson/generic/ondemand/json_type.h"
|
#include "simdjson/generic/ondemand/json_type.h"
|
||||||
#include "simdjson/generic/ondemand/object.h"
|
#include "simdjson/generic/ondemand/object.h"
|
||||||
#include "simdjson/generic/ondemand/raw_json_string.h"
|
#include "simdjson/generic/ondemand/raw_json_string.h"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <type_traits>
|
||||||
#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H
|
#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H
|
||||||
|
|
||||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
@@ -6,9 +7,9 @@
|
|||||||
#include "simdjson/generic/atomparsing.h"
|
#include "simdjson/generic/atomparsing.h"
|
||||||
#include "simdjson/generic/numberparsing.h"
|
#include "simdjson/generic/numberparsing.h"
|
||||||
#include "simdjson/generic/ondemand/json_iterator.h"
|
#include "simdjson/generic/ondemand/json_iterator.h"
|
||||||
|
#include "simdjson/generic/ondemand/value_iterator.h"
|
||||||
#include "simdjson/generic/ondemand/json_type-inl.h"
|
#include "simdjson/generic/ondemand/json_type-inl.h"
|
||||||
#include "simdjson/generic/ondemand/raw_json_string-inl.h"
|
#include "simdjson/generic/ondemand/raw_json_string-inl.h"
|
||||||
#include "simdjson/generic/ondemand/value_iterator.h"
|
|
||||||
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
@@ -109,6 +110,108 @@ simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::has_n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
simdjson_warn_unused simdjson_inline error_code value_iterator::on_field_raw(Func&& func)
|
||||||
|
#ifdef __cpp_lib_is_invocable
|
||||||
|
noexcept(std::is_nothrow_invocable_r_v<bool, Func, raw_json_string, error_code&>)
|
||||||
|
#else
|
||||||
|
noexcept(false)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifdef __cpp_lib_is_invocable
|
||||||
|
static_assert(std::is_invocable_r_v<bool, Func, raw_json_string, error_code&>, "Invalid function provided.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
error_code error = SUCCESS;
|
||||||
|
bool has_value;
|
||||||
|
//
|
||||||
|
// Initially, the object can be in one of a few different places:
|
||||||
|
//
|
||||||
|
// 1. The start of the object, at the first field:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// { "a": [ 1, 2 ], "b": [ 3, 4 ] }
|
||||||
|
// ^ (depth 2, index 1)
|
||||||
|
// ```
|
||||||
|
if (at_first_field()) {
|
||||||
|
has_value = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 2. When a previous search did not yield a value or the object is empty:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// { "a": [ 1, 2 ], "b": [ 3, 4 ] }
|
||||||
|
// ^ (depth 0)
|
||||||
|
// { }
|
||||||
|
// ^ (depth 0, index 2)
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
} else if (!is_open()) {
|
||||||
|
#if SIMDJSON_DEVELOPMENT_CHECKS
|
||||||
|
// If we're past the end of the object, we're being iterated out of order.
|
||||||
|
// Note: this is not perfect detection. It's possible the user is inside some other object; if so,
|
||||||
|
// this object iterator will blithely scan that object for fields.
|
||||||
|
if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; }
|
||||||
|
#endif
|
||||||
|
return EMPTY;
|
||||||
|
|
||||||
|
// 3. When a previous search found a field or an iterator yielded a value:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// // When a field was not fully consumed (or not even touched at all)
|
||||||
|
// { "a": [ 1, 2 ], "b": [ 3, 4 ] }
|
||||||
|
// ^ (depth 2)
|
||||||
|
// // When a field was fully consumed
|
||||||
|
// { "a": [ 1, 2 ], "b": [ 3, 4 ] }
|
||||||
|
// ^ (depth 1)
|
||||||
|
// // When the last field was fully consumed
|
||||||
|
// { "a": [ 1, 2 ], "b": [ 3, 4 ] }
|
||||||
|
// ^ (depth 1)
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
} else {
|
||||||
|
if ((error = skip_child() )) { abandon(); return error; }
|
||||||
|
if ((error = has_next_field().get(has_value) )) { abandon(); return error; }
|
||||||
|
#if SIMDJSON_DEVELOPMENT_CHECKS
|
||||||
|
if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
while (has_value) {
|
||||||
|
// Get the key and colon, stopping at the value.
|
||||||
|
raw_json_string actual_key;
|
||||||
|
// size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes
|
||||||
|
// Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2.
|
||||||
|
// field_key() advances the pointer and checks that '"' is found (corresponding to a key).
|
||||||
|
// The depth is left unchanged by field_key().
|
||||||
|
if ((error = field_key().get(actual_key) )) { abandon(); return error; };
|
||||||
|
// field_value() will advance and check that we find a ':' separating the
|
||||||
|
// key and the value. It will also increment the depth by one.
|
||||||
|
if ((error = field_value() )) { abandon(); return error; }
|
||||||
|
// If it matches, stop and return
|
||||||
|
// We could do it this way if we wanted to allow arbitrary
|
||||||
|
// key content (including escaped quotes).
|
||||||
|
//if (actual_key.unsafe_is_equal(max_key_length, key)) {
|
||||||
|
// Instead we do the following which may trigger buffer overruns if the
|
||||||
|
// user provides an adversarial key (containing a well placed unescaped quote
|
||||||
|
// character and being longer than the number of bytes remaining in the JSON
|
||||||
|
// input).
|
||||||
|
if (func(actual_key, error)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The call to skip_child is meant to skip over the value corresponding to the key.
|
||||||
|
// After skip_child(), we are right before the next comma (',') or the final brace ('}').
|
||||||
|
SIMDJSON_TRY( skip_child() ); // Skip the value entirely
|
||||||
|
// The has_next_field() advances the pointer and check that either ',' or '}' is found.
|
||||||
|
// It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found,
|
||||||
|
// then we are in error and we abort.
|
||||||
|
if ((error = has_next_field().get(has_value) )) { abandon(); return error; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the loop ended, we're out of fields to look at.
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::find_field_raw(const std::string_view key) noexcept {
|
simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::find_field_raw(const std::string_view key) noexcept {
|
||||||
error_code error;
|
error_code error;
|
||||||
bool has_value;
|
bool has_value;
|
||||||
|
|||||||
@@ -6,6 +6,12 @@
|
|||||||
#include "simdjson/generic/implementation_simdjson_result_base.h"
|
#include "simdjson/generic/implementation_simdjson_result_base.h"
|
||||||
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
#ifdef __has_include
|
||||||
|
#if __has_include (<version>)
|
||||||
|
#include <version>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
namespace SIMDJSON_IMPLEMENTATION {
|
namespace SIMDJSON_IMPLEMENTATION {
|
||||||
namespace ondemand {
|
namespace ondemand {
|
||||||
@@ -198,6 +204,22 @@ public:
|
|||||||
*/
|
*/
|
||||||
simdjson_warn_unused simdjson_inline simdjson_result<bool> find_field_raw(const std::string_view key) noexcept;
|
simdjson_warn_unused simdjson_inline simdjson_result<bool> find_field_raw(const std::string_view key) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs Func on each key found.
|
||||||
|
* Almost same as `find_field_raw` but it runs `func` instead of checking the key ourselves.
|
||||||
|
*
|
||||||
|
* @param Func func(raw_json_string key, error_code& error) noexcept
|
||||||
|
*/
|
||||||
|
template <typename Func>
|
||||||
|
simdjson_warn_unused simdjson_inline error_code on_field_raw(Func&& func)
|
||||||
|
#ifdef __cpp_lib_is_invocable
|
||||||
|
noexcept(std::is_nothrow_invocable_r_v<bool, Func, raw_json_string, error_code&>)
|
||||||
|
#else
|
||||||
|
noexcept(false)
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the field with the given key without regard to order, and *without* unescaping.
|
* Find the field with the given key without regard to order, and *without* unescaping.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ inline padded_string::padded_string(const char *data, size_t length) noexcept
|
|||||||
if ((data != nullptr) && (data_ptr != nullptr)) {
|
if ((data != nullptr) && (data_ptr != nullptr)) {
|
||||||
std::memcpy(data_ptr, data, length);
|
std::memcpy(data_ptr, data, length);
|
||||||
}
|
}
|
||||||
|
if (data_ptr == nullptr) {
|
||||||
|
viable_size = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef __cpp_char8_t
|
#ifdef __cpp_char8_t
|
||||||
inline padded_string::padded_string(const char8_t *data, size_t length) noexcept
|
inline padded_string::padded_string(const char8_t *data, size_t length) noexcept
|
||||||
@@ -60,12 +63,17 @@ inline padded_string::padded_string(const char8_t *data, size_t length) noexcept
|
|||||||
if ((data != nullptr) && (data_ptr != nullptr)) {
|
if ((data != nullptr) && (data_ptr != nullptr)) {
|
||||||
std::memcpy(data_ptr, reinterpret_cast<const char *>(data), length);
|
std::memcpy(data_ptr, reinterpret_cast<const char *>(data), length);
|
||||||
}
|
}
|
||||||
|
if (data_ptr == nullptr) {
|
||||||
|
viable_size = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// note: do not pass std::string arguments by value
|
// note: do not pass std::string arguments by value
|
||||||
inline padded_string::padded_string(const std::string & str_ ) noexcept
|
inline padded_string::padded_string(const std::string & str_ ) noexcept
|
||||||
: viable_size(str_.size()), data_ptr(internal::allocate_padded_buffer(str_.size())) {
|
: viable_size(str_.size()), data_ptr(internal::allocate_padded_buffer(str_.size())) {
|
||||||
if (data_ptr != nullptr) {
|
if (data_ptr == nullptr) {
|
||||||
|
viable_size = 0;
|
||||||
|
} else {
|
||||||
std::memcpy(data_ptr, str_.data(), str_.size());
|
std::memcpy(data_ptr, str_.data(), str_.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||||
|
|
||||||
/** The version of simdjson being used (major.minor.revision) */
|
/** The version of simdjson being used (major.minor.revision) */
|
||||||
#define SIMDJSON_VERSION "3.10.0"
|
#define SIMDJSON_VERSION "3.10.1"
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
enum {
|
enum {
|
||||||
@@ -19,7 +19,7 @@ enum {
|
|||||||
/**
|
/**
|
||||||
* The revision (major.minor.REVISION) of simdjson being used.
|
* The revision (major.minor.REVISION) of simdjson being used.
|
||||||
*/
|
*/
|
||||||
SIMDJSON_VERSION_REVISION = 0
|
SIMDJSON_VERSION_REVISION = 1
|
||||||
};
|
};
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* auto-generated on 2024-08-01 09:31:50 -0400. Do not edit! */
|
/* auto-generated on 2024-08-26 09:37:03 -0400. Do not edit! */
|
||||||
/* including simdjson.cpp: */
|
/* including simdjson.cpp: */
|
||||||
/* begin file simdjson.cpp */
|
/* begin file simdjson.cpp */
|
||||||
#define SIMDJSON_SRC_SIMDJSON_CPP
|
#define SIMDJSON_SRC_SIMDJSON_CPP
|
||||||
@@ -332,6 +332,8 @@ double from_chars(const char *first, const char* end) noexcept;
|
|||||||
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
|
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
|
||||||
|
|
||||||
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
#if SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
|
// We could use [[deprecated]] but it requires C++14
|
||||||
|
#define simdjson_deprecated __declspec(deprecated)
|
||||||
|
|
||||||
#define simdjson_really_inline __forceinline
|
#define simdjson_really_inline __forceinline
|
||||||
#define simdjson_never_inline __declspec(noinline)
|
#define simdjson_never_inline __declspec(noinline)
|
||||||
@@ -370,6 +372,8 @@ double from_chars(const char *first, const char* end) noexcept;
|
|||||||
#define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS
|
#define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS
|
||||||
|
|
||||||
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
|
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||||
|
// We could use [[deprecated]] but it requires C++14
|
||||||
|
#define simdjson_deprecated __attribute__((deprecated))
|
||||||
|
|
||||||
#define simdjson_really_inline inline __attribute__((always_inline))
|
#define simdjson_really_inline inline __attribute__((always_inline))
|
||||||
#define simdjson_never_inline inline __attribute__((noinline))
|
#define simdjson_never_inline inline __attribute__((noinline))
|
||||||
|
|||||||
+215
-203
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,7 @@ add_cpp_test(ondemand_to_string LABELS ondemand acceptance per_impl
|
|||||||
add_cpp_test(ondemand_twitter_tests LABELS ondemand acceptance per_implementation)
|
add_cpp_test(ondemand_twitter_tests LABELS ondemand acceptance per_implementation)
|
||||||
add_cpp_test(ondemand_wrong_type_error_tests LABELS ondemand acceptance per_implementation)
|
add_cpp_test(ondemand_wrong_type_error_tests LABELS ondemand acceptance per_implementation)
|
||||||
add_cpp_test(ondemand_iterate_many_csv LABELS ondemand acceptance per_implementation)
|
add_cpp_test(ondemand_iterate_many_csv LABELS ondemand acceptance per_implementation)
|
||||||
|
add_cpp_test(ondemand_extract_tests LABELS ondemand acceptance per_implementation)
|
||||||
if(NOT SIMDJSON_SANITIZE)
|
if(NOT SIMDJSON_SANITIZE)
|
||||||
add_cpp_test(ondemand_cacheline LABELS ondemand acceptance per_implementation)
|
add_cpp_test(ondemand_cacheline LABELS ondemand acceptance per_implementation)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ function(add_dual_compile_test TEST_NAME)
|
|||||||
target_compile_definitions(${TEST_NAME}_should_not_compile PRIVATE COMPILATION_TEST_USE_FAILING_CODE=1)
|
target_compile_definitions(${TEST_NAME}_should_not_compile PRIVATE COMPILATION_TEST_USE_FAILING_CODE=1)
|
||||||
endfunction(add_dual_compile_test)
|
endfunction(add_dual_compile_test)
|
||||||
|
|
||||||
|
add_dual_compile_test(iterate_object)
|
||||||
|
add_dual_compile_test(iterate_array)
|
||||||
add_dual_compile_test(iterate_char_star)
|
add_dual_compile_test(iterate_char_star)
|
||||||
add_dual_compile_test(iterate_string_view)
|
add_dual_compile_test(iterate_string_view)
|
||||||
add_dual_compile_test(iterate_temporary_buffer)
|
add_dual_compile_test(iterate_temporary_buffer)
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "simdjson.h"
|
||||||
|
|
||||||
|
using namespace simdjson;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
auto json = "[1]"_padded;
|
||||||
|
ondemand::parser parser;
|
||||||
|
auto f = [](ondemand::parser& p, simdjson::padded_string& jsons) -> ondemand::document {
|
||||||
|
ondemand::document doc;
|
||||||
|
auto error = p.iterate(jsons).get(doc);
|
||||||
|
if(error) { std::abort(); }
|
||||||
|
return doc;
|
||||||
|
};
|
||||||
|
ondemand::array arrayv;
|
||||||
|
#if COMPILATION_TEST_USE_FAILING_CODE
|
||||||
|
// Not allowed as this would be unsafe, the document must remain alive.
|
||||||
|
auto error = f(parser).get_array().get(arrayv);
|
||||||
|
#else
|
||||||
|
ondemand::document doc = f(parser, json);
|
||||||
|
auto error = doc.get_array().get(arrayv);
|
||||||
|
#endif
|
||||||
|
if(error) {
|
||||||
|
std::cout << "Failure" << std::endl;
|
||||||
|
}
|
||||||
|
int64_t a = 0;
|
||||||
|
error = arrayv.at(0).get_int64().get(a);
|
||||||
|
if(error) {
|
||||||
|
std::cout << "failure" << std::endl;
|
||||||
|
}
|
||||||
|
printf("a = %d\n", (int)a);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "simdjson.h"
|
||||||
|
|
||||||
|
using namespace simdjson;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
auto json = "{\"a\":1}"_padded;
|
||||||
|
ondemand::parser parser;
|
||||||
|
auto f = [](ondemand::parser& p, simdjson::padded_string& jsons) -> ondemand::document {
|
||||||
|
ondemand::document doc;
|
||||||
|
auto error = p.iterate(jsons).get(doc);
|
||||||
|
if(error) { std::abort(); }
|
||||||
|
return doc;
|
||||||
|
};
|
||||||
|
ondemand::object objv;
|
||||||
|
#if COMPILATION_TEST_USE_FAILING_CODE
|
||||||
|
// Not allowed as this would be unsafe, the document must remain alive.
|
||||||
|
auto error = f(parser).get_object().get(objv);
|
||||||
|
#else
|
||||||
|
ondemand::document doc = f(parser, json);
|
||||||
|
auto error = doc.get_object().get(objv);
|
||||||
|
#endif
|
||||||
|
if(error) {
|
||||||
|
std::cout << "Failure" << std::endl;
|
||||||
|
}
|
||||||
|
int64_t a = 0;
|
||||||
|
error = objv["a"].get_int64().get(a);
|
||||||
|
if(error) {
|
||||||
|
std::cout << "failure" << std::endl;
|
||||||
|
}
|
||||||
|
printf("a = %d\n", (int)a);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
@@ -59,6 +59,22 @@ void compilation_test_3() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do not run this, it is only meant to compile
|
||||||
|
void compilation_test_4() {
|
||||||
|
const padded_string bogus = ""_padded;
|
||||||
|
ondemand::parser parser;
|
||||||
|
int64_t x1 = (int64_t)parser.iterate(bogus);
|
||||||
|
double x2 = (double)parser.iterate(bogus);
|
||||||
|
std::string_view x = (std::string_view)parser.iterate(bogus);
|
||||||
|
uint64_t x3 = (uint64_t)parser.iterate(bogus);
|
||||||
|
bool x4 = (bool)parser.iterate(bogus);
|
||||||
|
(void) x1;
|
||||||
|
(void) x2;
|
||||||
|
(void) x3;
|
||||||
|
(void) x4;
|
||||||
|
(void) x;
|
||||||
|
}
|
||||||
#endif // SIMDJSON_EXCEPTIONS
|
#endif // SIMDJSON_EXCEPTIONS
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
#include "simdjson.h"
|
||||||
|
#include "test_ondemand.h"
|
||||||
|
|
||||||
|
using namespace simdjson;
|
||||||
|
|
||||||
|
namespace multi_get_tests {
|
||||||
|
#ifdef __cpp_concepts
|
||||||
|
struct Car {
|
||||||
|
std::string_view make;
|
||||||
|
std::string_view model;
|
||||||
|
std::int64_t year = 0;
|
||||||
|
struct wheel_size_type {
|
||||||
|
std::int64_t front = 0;
|
||||||
|
std::int64_t back = 0;
|
||||||
|
} wheels;
|
||||||
|
|
||||||
|
static simdjson_result<Car> create(auto& value) {
|
||||||
|
using ondemand::to;
|
||||||
|
using ondemand::sub;
|
||||||
|
|
||||||
|
simdjson::ondemand::object obj;
|
||||||
|
auto error = value.get_object().get(obj);
|
||||||
|
if (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
Car car{};
|
||||||
|
// Instead of this:
|
||||||
|
// for (auto field : obj) {
|
||||||
|
// simdjson::ondemand::raw_json_string key;
|
||||||
|
// error = field.key().get(key);
|
||||||
|
// if (error) {
|
||||||
|
// return error;
|
||||||
|
// }
|
||||||
|
// if (key == "make") {
|
||||||
|
// error = field.value().get_string(car.make);
|
||||||
|
// if (error) {
|
||||||
|
// return error;
|
||||||
|
// }
|
||||||
|
// } else if (key == "model") {
|
||||||
|
// error = field.value().get_string(car.model);
|
||||||
|
// if (error) {
|
||||||
|
// return error;
|
||||||
|
// }
|
||||||
|
// } else if (key == "year") {
|
||||||
|
// error = field.value().get(car.year);
|
||||||
|
// if (error) {
|
||||||
|
// return error;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// we can do this now:
|
||||||
|
error = obj.extract(
|
||||||
|
to{"wheels", sub{
|
||||||
|
to{"front", car.wheels.front},
|
||||||
|
to{"back", car.wheels.back},
|
||||||
|
}},
|
||||||
|
to{"make", car.make},
|
||||||
|
to{"model", car.model},
|
||||||
|
to{"year", [&car](auto val) {
|
||||||
|
car.year = val;
|
||||||
|
}});
|
||||||
|
if (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return car;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool car_example() {
|
||||||
|
TEST_START();
|
||||||
|
simdjson::padded_string json =
|
||||||
|
R"( [ { "make": "Toyota", "model": "Camry", "year": 2018,
|
||||||
|
"tire_pressure": [ 40.1, 39.9 ], "wheels": { "front": 10, "back": 10 } },
|
||||||
|
{ "make": "Kia", "model": "Soul", "year": 2012,
|
||||||
|
"tire_pressure": [ 30.1, 31.0 ], "wheels": { "front": 10, "back": 10 } },
|
||||||
|
{ "make": "Toyota", "model": "Tercel", "year": 1999,
|
||||||
|
"tire_pressure": [ 29.8, 30.0 ], "wheels": { "front": 10, "back": 10 } }
|
||||||
|
])"_padded;
|
||||||
|
|
||||||
|
simdjson::ondemand::parser parser;
|
||||||
|
simdjson::ondemand::document doc = parser.iterate(json);
|
||||||
|
for (auto val : doc) {
|
||||||
|
auto car = Car::create(val);
|
||||||
|
ASSERT_EQUAL(car.error(), SUCCESS);
|
||||||
|
Car const c(car.value());
|
||||||
|
if (c.make != "Toyota" && c.make != "Kia") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c.model != "Camry" && c.model != "Soul" && c.model != "Tercel") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c.year != 2018 && c.year != 2012 && c.year != 1999) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c.wheels.front != 10 || c.wheels.back != 10) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
bool run() {
|
||||||
|
return
|
||||||
|
#ifdef __cpp_concepts
|
||||||
|
car_example() &&
|
||||||
|
#endif
|
||||||
|
true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace multi_get_tests
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
return test_main(argc, argv, multi_get_tests::run);
|
||||||
|
}
|
||||||
@@ -164,8 +164,7 @@ namespace json_pointer_tests {
|
|||||||
ASSERT_TRUE(is_scalar);
|
ASSERT_TRUE(is_scalar);
|
||||||
ASSERT_ERROR(doc.at_pointer("").get(val), simdjson::SCALAR_DOCUMENT_AS_VALUE);
|
ASSERT_ERROR(doc.at_pointer("").get(val), simdjson::SCALAR_DOCUMENT_AS_VALUE);
|
||||||
std::cout << " checking true"<< std::endl;
|
std::cout << " checking true"<< std::endl;
|
||||||
ASSERT_SUCCESS(parser.iterate(true_json).get(doc));
|
ASSERT_SUCCESS(parser.iterate(true_json).is_scalar().get(is_scalar));
|
||||||
ASSERT_SUCCESS(doc.is_scalar().get(is_scalar));
|
|
||||||
ASSERT_TRUE(is_scalar);
|
ASSERT_TRUE(is_scalar);
|
||||||
ASSERT_ERROR(doc.at_pointer("").get(val), simdjson::SCALAR_DOCUMENT_AS_VALUE);
|
ASSERT_ERROR(doc.at_pointer("").get(val), simdjson::SCALAR_DOCUMENT_AS_VALUE);
|
||||||
std::cout << " checking object"<< std::endl;
|
std::cout << " checking object"<< std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user