Skip to content

Commit 7354e7b

Browse files
committed
Make simdjson_result implementation-specific
1 parent 7a2e6b7 commit 7354e7b

30 files changed

+356
-68
lines changed

benchmark/CMakeLists.txt

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,8 @@ link_libraries(simdjson-windows-headers test-data)
33

44

55
if (TARGET benchmark::benchmark)
6-
add_library(deserialize_benchmark INTERFACE)
7-
target_link_libraries(deserialize_benchmark INTERFACE simdjson-internal-flags simdjson-include-source benchmark::benchmark)
8-
# Don't pass all the compiler options on ARM
9-
CHECK_CXX_COMPILER_FLAG(-mavx2 HAVE_MAVX2_FLAG)
10-
if (HAVE_MAVX2_FLAG)
11-
target_compile_options(deserialize_benchmark INTERFACE -mavx2 -mbmi -mpclmul -mlzcnt)
12-
target_compile_definitions(deserialize_benchmark INTERFACE SIMDJSON_IMPLEMENTATION=haswell)
13-
# Some ARM compilers "support" -mavx2 but don't use it. This makes them not complain.
14-
CHECK_CXX_COMPILER_FLAG(-Qunused-arguments HAVE_QUNUSED_ARGUMENTS_FLAG)
15-
if (HAVE_QUNUSED_ARGUMENTS_FLAG)
16-
target_compile_options(deserialize_benchmark INTERFACE -Qunused-arguments)
17-
endif()
18-
endif()
19-
206
add_executable(bench_sax bench_sax.cpp)
21-
target_link_libraries(bench_sax deserialize_benchmark)
7+
target_link_libraries(bench_sax simdjson simdjson-internal-flags simdjson-include-source benchmark::benchmark)
228
endif (TARGET benchmark::benchmark)
239

2410
link_libraries(simdjson simdjson-flags)

benchmark/bench_sax.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
1-
#define SIMDJSON_IMPLEMENTATION_FALLBACK 0
2-
#define SIMDJSON_IMPLEMENTATION_WESTMERE 0
3-
#define SIMDJSON_IMPLEMENTATION_ARM64 0
4-
5-
#include <iostream>
6-
#include <sstream>
7-
#include <random>
8-
#include <vector>
9-
101
#include "simdjson.h"
112
#include "simdjson.cpp"
123

13-
#if SIMDJSON_IMPLEMENTATION_HASWELL
14-
#define SIMDJSON_IMPLEMENTATION haswell
15-
#endif // SIMDJSON_IMPLEMENTATION_HASWELL
16-
174
SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
185
#include <benchmark/benchmark.h>
196
SIMDJSON_POP_DISABLE_WARNINGS
207

8+
#if SIMDJSON_IMPLEMENTATION_HASWELL
9+
#include "haswell/begin_implementation.h"
10+
#endif // SIMDJSON_IMPLEMENTATION_HASWELL
11+
12+
#include <iostream>
13+
#include <sstream>
14+
#include <random>
15+
#include <vector>
16+
2117
#include "partial_tweets/ondemand.h"
2218
#include "partial_tweets/iter.h"
2319
#include "partial_tweets/sax.h"
@@ -33,3 +29,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
3329
#include "kostya/dom.h"
3430

3531
BENCHMARK_MAIN();
32+
33+
#if SIMDJSON_IMPLEMENTATION_HASWELL
34+
#include "haswell/end_implementation.h"
35+
#endif // SIMDJSON_IMPLEMENTATION_HASWELL

src/generic/dom_parser_implementation.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ class dom_parser_implementation final : public internal::dom_parser_implementati
2525
/** Document passed to stage 2 */
2626
dom::document *doc{};
2727

28-
simdjson_really_inline dom_parser_implementation() noexcept;
29-
dom_parser_implementation(dom_parser_implementation &&other) noexcept;
30-
dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept;
28+
inline dom_parser_implementation() noexcept;
29+
inline dom_parser_implementation(dom_parser_implementation &&other) noexcept;
30+
inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept;
3131
dom_parser_implementation(const dom_parser_implementation &) = delete;
3232
dom_parser_implementation &operator=(const dom_parser_implementation &) = delete;
3333

@@ -49,9 +49,9 @@ class dom_parser_implementation final : public internal::dom_parser_implementati
4949
namespace {
5050
namespace SIMDJSON_IMPLEMENTATION {
5151

52-
simdjson_really_inline dom_parser_implementation::dom_parser_implementation() noexcept = default;
53-
simdjson_really_inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default;
54-
simdjson_really_inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default;
52+
inline dom_parser_implementation::dom_parser_implementation() noexcept = default;
53+
inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default;
54+
inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default;
5555

5656
// Leaving these here so they can be inlined if so desired
5757
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept {
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
namespace {
2+
namespace SIMDJSON_IMPLEMENTATION {
3+
4+
//
5+
// internal::implementation_simdjson_result_base<T> inline implementation
6+
//
7+
8+
/**
9+
* Create a new empty result with error = UNINITIALIZED.
10+
*/
11+
template<typename T>
12+
simdjson_really_inline implementation_simdjson_result_base<T>::~implementation_simdjson_result_base() noexcept {
13+
}
14+
15+
template<typename T>
16+
simdjson_really_inline void implementation_simdjson_result_base<T>::tie(T &value, error_code &error) && noexcept {
17+
// on the clang compiler that comes with current macOS (Apple clang version 11.0.0),
18+
// tie(width, error) = size["w"].get<uint64_t>();
19+
// fails with "error: no viable overloaded '='""
20+
error = this->second;
21+
if (!error) {
22+
value = std::forward<implementation_simdjson_result_base<T>>(*this).first;
23+
}
24+
}
25+
26+
template<typename T>
27+
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code implementation_simdjson_result_base<T>::get(T &value) && noexcept {
28+
error_code error;
29+
std::forward<implementation_simdjson_result_base<T>>(*this).tie(value, error);
30+
return error;
31+
}
32+
33+
template<typename T>
34+
simdjson_really_inline error_code implementation_simdjson_result_base<T>::error() const noexcept {
35+
return this->second;
36+
}
37+
38+
#if SIMDJSON_EXCEPTIONS
39+
40+
template<typename T>
41+
simdjson_really_inline T& implementation_simdjson_result_base<T>::value() & noexcept(false) {
42+
if (error()) { throw simdjson_error(error()); }
43+
return this->first;
44+
}
45+
46+
template<typename T>
47+
simdjson_really_inline T&& implementation_simdjson_result_base<T>::value() && noexcept(false) {
48+
return std::forward<implementation_simdjson_result_base<T>>(*this).take_value();
49+
}
50+
51+
template<typename T>
52+
simdjson_really_inline T&& implementation_simdjson_result_base<T>::take_value() && noexcept(false) {
53+
if (error()) { throw simdjson_error(error()); }
54+
return std::forward<T>(this->first);
55+
}
56+
57+
template<typename T>
58+
simdjson_really_inline implementation_simdjson_result_base<T>::operator T&&() && noexcept(false) {
59+
return std::forward<implementation_simdjson_result_base<T>>(*this).take_value();
60+
}
61+
62+
#endif // SIMDJSON_EXCEPTIONS
63+
64+
template<typename T>
65+
simdjson_really_inline implementation_simdjson_result_base<T>::implementation_simdjson_result_base(T &&value, error_code error) noexcept
66+
: first{std::forward<T>(value)}, second{error} {}
67+
template<typename T>
68+
simdjson_really_inline implementation_simdjson_result_base<T>::implementation_simdjson_result_base(error_code error) noexcept
69+
: implementation_simdjson_result_base(T{}, error) {}
70+
template<typename T>
71+
simdjson_really_inline implementation_simdjson_result_base<T>::implementation_simdjson_result_base(T &&value) noexcept
72+
: implementation_simdjson_result_base(std::forward<T>(value), SUCCESS) {}
73+
template<typename T>
74+
simdjson_really_inline implementation_simdjson_result_base<T>::implementation_simdjson_result_base() noexcept
75+
: implementation_simdjson_result_base(T{}, UNINITIALIZED) {}
76+
77+
} // namespace SIMDJSON_IMPLEMENTATION
78+
} // unnamed namespace
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
namespace {
2+
namespace SIMDJSON_IMPLEMENTATION {
3+
4+
// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair
5+
// so we can avoid inlining errors
6+
// TODO reconcile these!
7+
/**
8+
* The result of a simdjson operation that could fail.
9+
*
10+
* Gives the option of reading error codes, or throwing an exception by casting to the desired result.
11+
*
12+
* This is a base class for implementations that want to add functions to the result type for
13+
* chaining.
14+
*
15+
* Override like:
16+
*
17+
* struct simdjson_result<T> : public internal::implementation_simdjson_result_base<T> {
18+
* simdjson_result() noexcept : internal::implementation_simdjson_result_base<T>() {}
19+
* simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base<T>(error) {}
20+
* simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base<T>(std::forward(value)) {}
21+
* simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base<T>(value, error) {}
22+
* // Your extra methods here
23+
* }
24+
*
25+
* Then any method returning simdjson_result<T> will be chainable with your methods.
26+
*/
27+
template<typename T>
28+
struct implementation_simdjson_result_base {
29+
30+
/**
31+
* Create a new empty result with error = UNINITIALIZED.
32+
*/
33+
simdjson_really_inline implementation_simdjson_result_base() noexcept;
34+
35+
/**
36+
* Create a new error result.
37+
*/
38+
simdjson_really_inline implementation_simdjson_result_base(error_code error) noexcept;
39+
40+
/**
41+
* Create a new successful result.
42+
*/
43+
simdjson_really_inline implementation_simdjson_result_base(T &&value) noexcept;
44+
45+
/**
46+
* Create a new result with both things (use if you don't want to branch when creating the result).
47+
*/
48+
simdjson_really_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept;
49+
50+
/**
51+
* Create a new empty result with error = UNINITIALIZED.
52+
*/
53+
simdjson_really_inline ~implementation_simdjson_result_base() noexcept;
54+
55+
/**
56+
* Move the value and the error to the provided variables.
57+
*
58+
* @param value The variable to assign the value to. May not be set if there is an error.
59+
* @param error The variable to assign the error to. Set to SUCCESS if there is no error.
60+
*/
61+
simdjson_really_inline void tie(T &value, error_code &error) && noexcept;
62+
63+
/**
64+
* Move the value to the provided variable.
65+
*
66+
* @param value The variable to assign the value to. May not be set if there is an error.
67+
*/
68+
simdjson_really_inline error_code get(T &value) && noexcept;
69+
70+
/**
71+
* The error.
72+
*/
73+
simdjson_really_inline error_code error() const noexcept;
74+
75+
#if SIMDJSON_EXCEPTIONS
76+
77+
/**
78+
* Get the result value.
79+
*
80+
* @throw simdjson_error if there was an error.
81+
*/
82+
simdjson_really_inline T& value() & noexcept(false);
83+
84+
/**
85+
* Take the result value (move it).
86+
*
87+
* @throw simdjson_error if there was an error.
88+
*/
89+
simdjson_really_inline T&& value() && noexcept(false);
90+
91+
/**
92+
* Take the result value (move it).
93+
*
94+
* @throw simdjson_error if there was an error.
95+
*/
96+
simdjson_really_inline T&& take_value() && noexcept(false);
97+
98+
/**
99+
* Cast to the value (will throw on error).
100+
*
101+
* @throw simdjson_error if there was an error.
102+
*/
103+
simdjson_really_inline operator T&&() && noexcept(false);
104+
105+
#endif // SIMDJSON_EXCEPTIONS
106+
107+
T first;
108+
error_code second;
109+
}; // struct implementation_simdjson_result_base
110+
111+
} // namespace SIMDJSON_IMPLEMENTATION
112+
} // unnamed namespace

src/generic/ondemand.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// When *declaring* classes, we use host compiler options so it will all link.
22
// When *defining* class methods, we use target compiler options.
33

4-
SIMDJSON_UNTARGET_IMPLEMENTATION
4+
#include "generic/implementation_simdjson_result_base.h"
55
#include "generic/ondemand/logger.h"
66
#include "generic/ondemand/raw_json_string.h"
77
#include "generic/ondemand/token_iterator.h"
@@ -15,7 +15,7 @@ SIMDJSON_UNTARGET_IMPLEMENTATION
1515
#include "generic/ondemand/object.h"
1616
#include "generic/ondemand/parser.h"
1717

18-
SIMDJSON_TARGET_IMPLEMENTATION
18+
#include "generic/implementation_simdjson_result_base-inl.h"
1919
#include "generic/ondemand/logger-inl.h"
2020
#include "generic/ondemand/raw_json_string-inl.h"
2121
#include "generic/ondemand/token_iterator-inl.h"

src/generic/ondemand/array-inl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,15 @@ namespace simdjson {
8080
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array>::simdjson_result(
8181
SIMDJSON_IMPLEMENTATION::ondemand::array &&value
8282
) noexcept
83-
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array>(
83+
: implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array>(
8484
std::forward<SIMDJSON_IMPLEMENTATION::ondemand::array>(value)
8585
)
8686
{
8787
}
8888
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array>::simdjson_result(
8989
error_code error
9090
) noexcept
91-
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array>(error)
91+
: implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array>(error)
9292
{
9393
}
9494

src/generic/ondemand/array.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ class array {
1515
simdjson_really_inline array() noexcept = default;
1616
simdjson_really_inline array(array &&other) noexcept = default;
1717
simdjson_really_inline array &operator=(array &&other) noexcept = default;
18-
1918
array(const array &) = delete;
2019
array &operator=(const array &) = delete;
2120

@@ -67,10 +66,11 @@ class array {
6766
namespace simdjson {
6867

6968
template<>
70-
struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array> : public internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array> {
69+
struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array> : public SIMDJSON_IMPLEMENTATION::implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array> {
7170
public:
7271
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::array &&value) noexcept; ///< @private
7372
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
73+
simdjson_really_inline ~simdjson_result() noexcept = default; ///< @private
7474

7575
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> begin() & noexcept;
7676
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> end() & noexcept;

src/generic/ondemand/array_iterator-inl.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,25 @@ simdjson_really_inline array_iterator &array_iterator::operator++() noexcept {
2828
namespace simdjson {
2929

3030
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::simdjson_result() noexcept
31-
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>({}, SUCCESS)
31+
: implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>({}, SUCCESS)
3232
{
3333
}
3434

3535
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::simdjson_result(
3636
SIMDJSON_IMPLEMENTATION::ondemand::array_iterator &&value
3737
) noexcept
38-
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>(std::forward<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>(value))
38+
: implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>(std::forward<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>(value))
3939
{
4040
}
4141
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::simdjson_result(error_code error) noexcept
42-
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>({}, error)
42+
: implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>({}, error)
4343
{
4444
}
4545

4646
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::simdjson_result(
4747
const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &a
4848
) noexcept
49-
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>(a)
49+
: implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>(a)
5050
{
5151
}
5252

src/generic/ondemand/array_iterator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,14 @@ class array_iterator {
5454
namespace simdjson {
5555

5656
template<>
57-
struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> : public internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> {
57+
struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> : public SIMDJSON_IMPLEMENTATION::implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> {
5858
public:
5959
simdjson_really_inline simdjson_result() noexcept;
6060
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::array_iterator &&value) noexcept; ///< @private
6161
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
6262
simdjson_really_inline simdjson_result(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &a) noexcept;
6363
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &operator=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &a) noexcept;
64+
simdjson_really_inline ~simdjson_result() noexcept = default; ///< @private
6465

6566
//
6667
// Iterator interface

0 commit comments

Comments
 (0)