Compare commits

...

6 Commits

Author SHA1 Message Date
John Keiser 2726f4543e Create simd bitmask builder 2024-08-18 14:29:52 -07:00
John Keiser 4c1b0a41d8 Enable SIMDJSON_SINGLEHEADER=OFF in VS Code
With singleheader on, clangd can't find the right
include files.
2024-08-18 14:21:00 -07:00
John Keiser ef563a4b09 Make simdjson compile again 2024-08-18 11:21:26 -07:00
Daniel Lemire 7a9ff93388 [no-ci] Update README.md 2024-08-15 12:52:47 -04:00
Sasha Lopoukhine fc61d7c7ba Fix ndjson spec link (#2234)
* fix ndjson spec link

The link in the readme of parse_many links to a casino spam site

* fix link
2024-08-10 10:11:05 -04:00
Daniel Lemire d506af0a79 fix: add tests related to issue 2227 (#2229)
* fix: add tests related to issue 2227

* avoiding name clash

* pedantic fix

* deprecate rvalue get on document

* selectively deprecating
2024-08-07 20:15:06 -04:00
26 changed files with 431 additions and 170 deletions
+9
View File
@@ -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:
@@ -44,3 +45,11 @@ Diagnostics:
Suppress: Suppress:
- pragma_attribute_no_pop_eof - pragma_attribute_no_pop_eof
- pragma_attribute_stack_mismatch - pragma_attribute_stack_mismatch
---
# clang 18
If:
PathMatch:
- dependencies/.cache/json11/json11.cpp
CompileFlags:
Add:
- -Wno-unqualified-std-cast-call
+5
View File
@@ -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"
} }
} }
+10 -6
View File
@@ -51,6 +51,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 +156,13 @@ endif()
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
include(GNUInstallDirs) include(GNUInstallDirs)
install( if(SIMDJSON_SINGLEHEADER)
FILES singleheader/simdjson.h install(
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" FILES singleheader/simdjson.h
COMPONENT simdjson_Development DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
) COMPONENT simdjson_Development
)
endif()
install( install(
TARGETS simdjson TARGETS simdjson
@@ -286,8 +289,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()
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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)
+65 -17
View File
@@ -412,6 +412,66 @@ namespace {
} }
}; };
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
static const uint8x16_t BITMASK64_BUILDER_MASK = simdjson_make_uint8x16_t(
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
);
#else
static const uint8x16_t BITMASK64_BUILDER_MASK = {
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
};
#endif
template <int N = 0>
struct simd_bitmask64_builder;
template<>
struct simd_bitmask64_builder<4> {
const uint64_t mask;
operator uint64_t() && { return mask; }
}; // struct simd_bitmask64_builder<4>
template<>
struct simd_bitmask64_builder<3> {
const uint8x16_t sum01;
const simd8<bool> val2;
simdjson_inline simd_bitmask64_builder<4> next(simd8<bool> val3) {
// Add each of the elements next to each other, successively, to stuff each 8 byte mask into one.
uint8x16_t sum23 = vpaddq_u8(val2 & BITMASK64_BUILDER_MASK, val3 & BITMASK64_BUILDER_MASK);
uint8x16_t sum0123 = vpaddq_u8(sum01, sum23);
// This algorithm is actually designed to create a 128-bit mask from 8 16-byte simd masks,
// but since we only want 64 bits, we add the mask to itself (creating the final mask twice).
uint8x16_t sum01230123 = vpaddq_u8(sum0123, sum0123);
return { vgetq_lane_u64(vreinterpretq_u64_u8(sum01230123), 0) };
}
}; // struct simd_bitmask64_builder<3>
template<>
struct simd_bitmask64_builder<2> {
const uint8x16_t sum01;
simdjson_inline simd_bitmask64_builder<3> next(simd8<bool> val2) {
return { sum01, val2 };
}
}; // struct simd_bitmask64_builder<2>
template<>
struct simd_bitmask64_builder<1> {
const simd8<bool> val0;
simdjson_inline simd_bitmask64_builder<2> next(simd8<bool> val1) {
return { vpaddq_u8(val0 & BITMASK64_BUILDER_MASK, val1 & BITMASK64_BUILDER_MASK) };
}
}; // struct simd_bitmask64_builder<1>
template<>
struct simd_bitmask64_builder<0> {
simdjson_inline simd_bitmask64_builder<1> next(simd8<bool> val) {
return { val };
}
}; // struct simd_bitmask64_builder<0>
template<typename T> template<typename T>
struct simd8x64 { struct simd8x64 {
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>); static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
@@ -449,23 +509,11 @@ namespace {
} }
simdjson_inline uint64_t to_bitmask() const { simdjson_inline uint64_t to_bitmask() const {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO return simd_bitmask64_builder<0>()
const uint8x16_t bit_mask = simdjson_make_uint8x16_t( .next(this->chunks[0])
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, .next(this->chunks[1])
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 .next(this->chunks[2])
); .next(this->chunks[3]);
#else
const uint8x16_t bit_mask = {
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
};
#endif
// Add each of the elements next to each other, successively, to stuff each 8 byte mask into one.
uint8x16_t sum0 = vpaddq_u8(this->chunks[0] & bit_mask, this->chunks[1] & bit_mask);
uint8x16_t sum1 = vpaddq_u8(this->chunks[2] & bit_mask, this->chunks[3] & bit_mask);
sum0 = vpaddq_u8(sum0, sum1);
sum0 = vpaddq_u8(sum0, sum0);
return vgetq_lane_u64(vreinterpretq_u64_u8(sum0), 0);
} }
simdjson_inline uint64_t eq(const T m) const { simdjson_inline uint64_t eq(const T m) const {
+4
View File
@@ -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))
@@ -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);
} }
+7 -4
View File
@@ -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
+1 -1
View File
@@ -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"
@@ -6,9 +6,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 {
+27 -3
View File
@@ -295,6 +295,30 @@ namespace simd {
simdjson_inline int get_bit() const { return _mm256_movemask_epi8(_mm256_slli_epi16(*this, 7-N)); } simdjson_inline int get_bit() const { return _mm256_movemask_epi8(_mm256_slli_epi16(*this, 7-N)); }
}; };
template <int N = 0>
struct simd_bitmask64_builder;
template<>
struct simd_bitmask64_builder<2> {
const uint64_t bitmask;
operator uint64_t() && { return bitmask; }
}; // struct simd_bitmask64_builder<2>
template<>
struct simd_bitmask64_builder<1> {
const int bitmask;
simdjson_inline simd_bitmask64_builder<2> next(simd8<bool> val) {
uint64_t r_lo = uint32_t(bitmask);
uint64_t r_hi = val.to_bitmask();
return { r_lo | (r_hi << 32) };
}
}; // struct simd_bitmask64_builder<1>
template<>
struct simd_bitmask64_builder<0> {
simdjson_inline simd_bitmask64_builder<1> next(simd8<bool> val) { return { val.to_bitmask() }; }
}; // struct simd_bitmask64_builder<0>
template<typename T> template<typename T>
struct simd8x64 { struct simd8x64 {
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>); static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
@@ -322,9 +346,9 @@ namespace simd {
} }
simdjson_inline uint64_t to_bitmask() const { simdjson_inline uint64_t to_bitmask() const {
uint64_t r_lo = uint32_t(this->chunks[0].to_bitmask()); return simd_bitmask64_builder<0>()
uint64_t r_hi = this->chunks[1].to_bitmask(); .next(this->chunks[0])
return r_lo | (r_hi << 32); .next(this->chunks[1]);
} }
simdjson_inline simd8<T> reduce_or() const { simdjson_inline simd8<T> reduce_or() const {
+14
View File
@@ -314,6 +314,20 @@ namespace simd {
simdjson_inline uint64_t get_bit() const { return _mm512_movepi8_mask(_mm512_slli_epi16(*this, 7-N)); } simdjson_inline uint64_t get_bit() const { return _mm512_movepi8_mask(_mm512_slli_epi16(*this, 7-N)); }
}; };
template <int N = 0>
struct simd_bitmask64_builder;
template<>
struct simd_bitmask64_builder<1> {
const __mmask64 bitmask;
operator __mmask64() && { return bitmask; }
}; // struct simd_bitmask64_builder<2>
template<>
struct simd_bitmask64_builder<0> {
simdjson_inline simd_bitmask64_builder<1> next(simd8<bool> val) { return { _mm512_movepi8_mask(val) }; }
}; // struct simd_bitmask64_builder<0>
template<typename T> template<typename T>
struct simd8x64 { struct simd8x64 {
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>); static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
+32 -7
View File
@@ -298,6 +298,35 @@ namespace simd {
simdjson_inline simd8<uint8_t> shl() const { return simd8<uint8_t>(__lasx_xvslli_b(*this, N)); } simdjson_inline simd8<uint8_t> shl() const { return simd8<uint8_t>(__lasx_xvslli_b(*this, N)); }
}; };
template <int N = 0>
struct simd_bitmask64_builder;
template<>
struct simd_bitmask64_builder<2> {
const unsigned long int mask01;
operator uint64_t() { return mask01; }
}; // struct simd_bitmask64_builder<2>
template<>
struct simd_bitmask64_builder<1> {
const __m256i mask0;
simdjson_inline simd_bitmask64_builder<2> next(simd8<bool> val1) {
__m256i mask1 = __lasx_xvmskltz_b(val1);
__m256i mask_tmp = __lasx_xvpickve_w(mask0, 4);
__m256i tmp = __lasx_xvpickve_w(mask1, 4);
__m256i mask01 = __lasx_xvinsve0_w(mask0, mask1, 1);
__m256i mask01_tmp = __lasx_xvinsve0_w(mask_tmp, tmp, 1);
return { __lasx_xvpickve2gr_du(__lasx_xvpackev_h(mask01_tmp, mask01), 0) };
}
}; // struct simd_bitmask64_builder<1>
template<>
struct simd_bitmask64_builder<0> {
simdjson_inline simd_bitmask64_builder<1> next(simd8<bool> val) {
return { __lasx_xvmskltz_b(val0) };
}
}; // struct simd_bitmask64_builder<0>
template<typename T> template<typename T>
struct simd8x64 { struct simd8x64 {
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>); static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
@@ -331,13 +360,9 @@ namespace simd {
} }
simdjson_inline uint64_t to_bitmask() const { simdjson_inline uint64_t to_bitmask() const {
__m256i mask0 = __lasx_xvmskltz_b(this->chunks[0]); return simd_bitmask64_builder<0>()
__m256i mask1 = __lasx_xvmskltz_b(this->chunks[1]); .next(this->chunks[0])
__m256i mask_tmp = __lasx_xvpickve_w(mask0, 4); .next(this->chunks[1]);
__m256i tmp = __lasx_xvpickve_w(mask1, 4);
mask0 = __lasx_xvinsve0_w(mask0, mask1, 1);
mask_tmp = __lasx_xvinsve0_w(mask_tmp, tmp, 1);
return __lasx_xvpickve2gr_du(__lasx_xvpackev_h(mask_tmp, mask0), 0);
} }
simdjson_inline simd8<T> reduce_or() const { simdjson_inline simd8<T> reduce_or() const {
+49 -7
View File
@@ -255,6 +255,50 @@ namespace simd {
simdjson_inline simd8<uint8_t> shl() const { return simd8<uint8_t>(__lsx_vslli_b(*this, N)); } simdjson_inline simd8<uint8_t> shl() const { return simd8<uint8_t>(__lsx_vslli_b(*this, N)); }
}; };
template <int N = 0>
struct simd_bitmask64_builder;
template<>
struct simd_bitmask64_builder<4> {
const unsigned long int result;
operator uint64_t() { return result; }
}; // struct simd_bitmask64_builder<4>
template<>
struct simd_bitmask64_builder<3> {
const __m128i mask01;
const __m128i mask2;
simdjson_inline simd_bitmask64_builder<4> next(simd8<bool> val3) {
__m128i mask3 = __lsx_vmskltz_b(val3);
__m128i mask23 = __lsx_vilvl_h(mask3, mask2);
return { __lsx_vpickve2gr_du(__lsx_vilvl_w(mask23, mask01), 0) };
}
}; // struct simd_bitmask64_builder<3>
template<>
struct simd_bitmask64_builder<2> {
const __m128i mask01;
simdjson_inline simd_bitmask64_builder<3> next(simd8<bool> val2) {
return { mask01, __lsx_vmskltz_b(val2) };
}
}; // struct simd_bitmask64_builder<2>
template<>
struct simd_bitmask64_builder<1> {
const __m128i mask0;
simdjson_inline simd_bitmask64_builder<2> next(simd8<bool> val1) {
__m128i mask1 = __lsx_vmskltz_b(val1);
return { __lsx_vilvl_h(mask1, mask0) };
}
}; // struct simd_bitmask64_builder<1>
template<>
struct simd_bitmask64_builder<0> {
simdjson_inline simd_bitmask64_builder<1> next(simd8<bool> val0) {
return { __lsx_vmskltz_b(val0) };
}
}; // struct simd_bitmask64_builder<0>
template<typename T> template<typename T>
struct simd8x64 { struct simd8x64 {
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>); static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
@@ -303,13 +347,11 @@ namespace simd {
} }
simdjson_inline uint64_t to_bitmask() const { simdjson_inline uint64_t to_bitmask() const {
__m128i mask1 = __lsx_vmskltz_b(this->chunks[0]); return simd_bitmask64_builder<0>()
__m128i mask2 = __lsx_vmskltz_b(this->chunks[1]); .next(this->chunks[0])
__m128i mask3 = __lsx_vmskltz_b(this->chunks[2]); .next(this->chunks[1])
__m128i mask4 = __lsx_vmskltz_b(this->chunks[3]); .next(this->chunks[2])
mask1 = __lsx_vilvl_h(mask2, mask1); .next(this->chunks[3]);
mask2 = __lsx_vilvl_h(mask4, mask3);
return __lsx_vpickve2gr_du(__lsx_vilvl_w(mask2, mask1), 0);
} }
simdjson_inline simd8<T> reduce_or() const { simdjson_inline simd8<T> reduce_or() const {
+50 -5
View File
@@ -392,6 +392,51 @@ template <> struct simd8<uint8_t> : base8_numeric<uint8_t> {
} }
}; };
template <int N = 0>
struct simd_bitmask64_builder;
template<>
struct simd_bitmask64_builder<4> {
const uint64_t bitmask;
simdjson_inline operator uint64_t() && { return bitmask; }
}; // struct simd_bitmask64_builder<4>
template<>
struct simd_bitmask64_builder<3> {
const int bitmask01;
const int bitmask2;
simdjson_inline simd_bitmask64_builder<4> next(simd8<bool> val) {
return {
uint64_t(this->bitmask01) |
(uint64_t(this->bitmask2) << 32) |
(uint64_t(val.to_bitmask()) << 48)
};
}
}; // struct simd_bitmask64_builder<3>
template<>
struct simd_bitmask64_builder<2> {
const int bitmask01;
simdjson_inline simd_bitmask64_builder<3> next(simd8<bool> val) {
return { bitmask01, val.to_bitmask() };
}
}; // struct simd_bitmask64_builder<2>
template<>
struct simd_bitmask64_builder<1> {
const int bitmask0;
simdjson_inline simd_bitmask64_builder<2> next(simd8<bool> val) {
return { bitmask0 | (val.to_bitmask() << 16) };
}
}; // struct simd_bitmask64_builder<1>
template<>
struct simd_bitmask64_builder<0> {
simdjson_inline simd_bitmask64_builder<1> next(simd8<bool> val) {
return { val.to_bitmask() };
}
}; // struct simd_bitmask64_builder<0>
template <typename T> struct simd8x64 { template <typename T> struct simd8x64 {
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>); static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
static_assert(NUM_CHUNKS == 4, static_assert(NUM_CHUNKS == 4,
@@ -434,11 +479,11 @@ template <typename T> struct simd8x64 {
} }
simdjson_inline uint64_t to_bitmask() const { simdjson_inline uint64_t to_bitmask() const {
uint64_t r0 = uint32_t(this->chunks[0].to_bitmask()); return simd_bitmask64_builder<0>()
uint64_t r1 = this->chunks[1].to_bitmask(); .next(this->chunks[0])
uint64_t r2 = this->chunks[2].to_bitmask(); .next(this->chunks[1])
uint64_t r3 = this->chunks[3].to_bitmask(); .next(this->chunks[2])
return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); .next(this->chunks[3]);
} }
simdjson_inline uint64_t eq(const T m) const { simdjson_inline uint64_t eq(const T m) const {
+50 -5
View File
@@ -260,6 +260,51 @@ namespace simd {
simdjson_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); } simdjson_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); }
}; };
template <int N = 0>
struct simd_bitmask64_builder;
template<>
struct simd_bitmask64_builder<4> {
const uint64_t bitmask;
operator uint64_t() && { return bitmask; }
}; // struct simd_bitmask64_builder<4>
template<>
struct simd_bitmask64_builder<3> {
uint32_t bitmask01;
const int bitmask2;
simdjson_inline simd_bitmask64_builder<4> next(simd8<bool> val3) {
return {
uint64_t(this->bitmask01) |
(uint64_t(this->bitmask2) << 32) |
(uint64_t(val3.to_bitmask()) << 48)
};
}
}; // struct simd_bitmask64_builder<3>
template<>
struct simd_bitmask64_builder<2> {
uint32_t bitmask01;
simdjson_inline simd_bitmask64_builder<3> next(simd8<bool> val2) {
return { bitmask01, val2.to_bitmask() };
}
}; // struct simd_bitmask64_builder<2>
template<>
struct simd_bitmask64_builder<1> {
const int bitmask0;
simdjson_inline simd_bitmask64_builder<2> next(simd8<bool> val1) {
return { uint32_t(bitmask0) | (uint32_t(val1.to_bitmask()) << 16) };
}
}; // struct simd_bitmask64_builder<1>
template<>
struct simd_bitmask64_builder<0> {
simdjson_inline simd_bitmask64_builder<1> next(simd8<bool> val0) {
return { val0.to_bitmask() };
}
}; // struct simd_bitmask64_builder<0>
template<typename T> template<typename T>
struct simd8x64 { struct simd8x64 {
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>); static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
@@ -293,11 +338,11 @@ namespace simd {
} }
simdjson_inline uint64_t to_bitmask() const { simdjson_inline uint64_t to_bitmask() const {
uint64_t r0 = uint32_t(this->chunks[0].to_bitmask() ); return simd_bitmask64_builder<0>()
uint64_t r1 = this->chunks[1].to_bitmask() ; .next(this->chunks[0])
uint64_t r2 = this->chunks[2].to_bitmask() ; .next(this->chunks[1])
uint64_t r3 = this->chunks[3].to_bitmask() ; .next(this->chunks[2])
return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); .next(this->chunks[3]);
} }
simdjson_inline uint64_t eq(const T m) const { simdjson_inline uint64_t eq(const T m) const {
@@ -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) {
@@ -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;