Skip to content

Commit 1e30b6e

Browse files
committed
Compile under C++ 11
1 parent 406240b commit 1e30b6e

22 files changed

+261
-103
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ objs
106106
/perfdiff
107107
/pointercheck
108108
/readme_examples
109+
/readme_examples11
109110
/readme_examples_noexceptions
111+
/readme_examples_noexceptions11
110112
/staticchecks
111113
/statisticalmodel
112114
/stringparsingcheck
@@ -124,7 +126,9 @@ objs
124126
/tests/integer_tests
125127
/tests/parse_many_test
126128
/tests/readme_examples
129+
/tests/readme_examples11
127130
/tests/readme_examples_noexceptions
131+
/tests/readme_examples_noexceptions11
128132
/tests/staticchecks
129133
/tools/json2json
130134
/tools/jsonstats

Makefile

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ JSON_INCLUDE:=dependencies/json/single_include/nlohmann/json.hpp
9191
EXTRAOBJECTS=ujdecode.o
9292

9393
MAINEXECUTABLES=parse minify json2json jsonstats statisticalmodel jsonpointer get_corpus_benchmark
94-
TESTEXECUTABLES=jsoncheck jsoncheck_westmere jsoncheck_fallback integer_tests numberparsingcheck stringparsingcheck pointercheck parse_many_test basictests errortests readme_examples readme_examples_noexceptions
94+
TESTEXECUTABLES=jsoncheck jsoncheck_westmere jsoncheck_fallback integer_tests numberparsingcheck stringparsingcheck pointercheck parse_many_test basictests errortests readme_examples readme_examples11 readme_examples_noexceptions readme_examples_noexceptions11
9595
COMPARISONEXECUTABLES=minifiercompetition parsingcompetition parseandstatcompetition distinctuseridcompetition allparserscheckfile allparsingcompetition
9696
SUPPLEMENTARYEXECUTABLES=parse_noutf8validation parse_nonumberparsing parse_nostringparsing
9797

@@ -141,22 +141,22 @@ run_pointercheck: pointercheck
141141
run_issue150_sh: allparserscheckfile
142142
./scripts/issue150.sh
143143

144-
quickstart: singleheader/simdjson.h singleheader/simdjson.cpp
144+
quickstart: amalgamate
145145
cd examples/quickstart && make quickstart
146146

147-
run_quickstart:
147+
run_quickstart: amalgamate
148148
cd examples/quickstart && make test
149149

150-
quickstart11:
150+
quickstart11: amalgamate
151151
cd examples/quickstart && make quickstart11
152152

153-
run_quickstart11:
153+
run_quickstart11: amalgamate
154154
cd examples/quickstart && make test11
155155

156-
quickstart14:
156+
quickstart14: amalgamate
157157
cd examples/quickstart && make quickstart14
158158

159-
run_quickstart14:
159+
run_quickstart14: amalgamate
160160
cd examples/quickstart && make test14
161161

162162
run_testjson2json_sh: minify json2json
@@ -173,7 +173,7 @@ test: quicktests slowtests
173173

174174
quiettest: quicktests slowtests
175175

176-
quicktests: run_basictests run_quickstart readme_examples readme_examples_noexceptions run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_jsoncheck run_parse_many_test run_pointercheck run_jsoncheck_westmere run_jsoncheck_fallback run_quickstart14
176+
quicktests: run_basictests run_quickstart readme_examples readme_examples_noexceptions run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_jsoncheck run_parse_many_test run_pointercheck run_jsoncheck_westmere run_jsoncheck_fallback run_quickstart14 run_quickstart11
177177

178178
slowtests: run_testjson2json_sh run_issue150_sh
179179

@@ -246,9 +246,15 @@ errortests: tests/errortests.cpp $(HEADERS) $(LIBFILES)
246246
readme_examples: tests/readme_examples.cpp $(HEADERS) $(LIBFILES)
247247
$(CXX) $(CXXFLAGS) -o readme_examples tests/readme_examples.cpp -I. $(LIBFILES) $(LIBFLAGS)
248248

249+
readme_examples11: tests/readme_examples.cpp $(HEADERS) $(LIBFILES)
250+
$(CXX) $(CXXFLAGS) -o readme_examples11 tests/readme_examples.cpp -I. $(LIBFILES) $(LIBFLAGS) -std=c++11
251+
249252
readme_examples_noexceptions: tests/readme_examples_noexceptions.cpp $(HEADERS) $(LIBFILES)
250253
$(CXX) $(CXXFLAGS) -o readme_examples_noexceptions tests/readme_examples_noexceptions.cpp -I. $(LIBFILES) $(LIBFLAGS) -fno-exceptions
251254

255+
readme_examples_noexceptions11: tests/readme_examples_noexceptions.cpp $(HEADERS) $(LIBFILES)
256+
$(CXX) $(CXXFLAGS) -o readme_examples_noexceptions11 tests/readme_examples_noexceptions.cpp -I. $(LIBFILES) $(LIBFLAGS) -fno-exceptions -std=c++11
257+
252258
staticchecks: tests/staticchecks.cpp $(HEADERS) src/simdjson.cpp
253259
$(CXX) $(CXXFLAGS) -o staticchecks tests/staticchecks.cpp -I. $(LIBFLAGS)
254260

@@ -258,8 +264,6 @@ numberparsingcheck: tests/numberparsingcheck.cpp $(HEADERS) src/simdjson.cpp
258264
integer_tests:tests/integer_tests.cpp $(HEADERS) $(LIBFILES)
259265
$(CXX) $(CXXFLAGS) -o integer_tests tests/integer_tests.cpp -I. $(LIBFILES) $(LIBFLAGS)
260266

261-
262-
263267
stringparsingcheck: tests/stringparsingcheck.cpp $(HEADERS) src/simdjson.cpp
264268
$(CXX) $(CXXFLAGS) -o stringparsingcheck tests/stringparsingcheck.cpp -I. $(LIBFLAGS) -DJSON_TEST_STRINGS
265269

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ The simdjson library is easily consumable with a single .h and .cpp file.
5454
std::cout << tweets["search_metadata"]["count"] << " results." << std::endl;
5555
}
5656
```
57-
3. `c++ -o quickstart quickstart.cpp simdjson.cpp -std=c++17`
57+
3. `c++ -o quickstart quickstart.cpp simdjson.cpp`
5858
4. `./quickstart`
5959
```
6060
100 results.
@@ -184,3 +184,5 @@ License
184184
This code is made available under the Apache License 2.0.
185185
186186
Under Windows, we build some tools using the windows/dirent_portable.h file (which is outside our library code): it under the liberal (business-friendly) MIT license.
187+
188+
For compilers that do not support C++17, we bundle the string-view library which is published under the Boost license (http://www.boost.org/LICENSE_1_0.txt). Like the Apache license, the Boost license is a permissive license allowing commercial redistribution.

doc/basics.md

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ using namespace simdjson; // optional
2828
You can compile with:
2929

3030
```
31-
c++ myproject.cpp simdjson.cpp --std=c++17
31+
c++ myproject.cpp simdjson.cpp
3232
```
3333

3434
The Basics: Loading and Parsing JSON Documents
@@ -98,12 +98,42 @@ for (dom::object car : parser.parse(cars_json)) {
9898
cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl;
9999

100100
// Writing out all the information about the car
101-
for (auto [key, value] : car) {
102-
cout << "- " << key << ": " << value << endl;
101+
for (auto field : car) {
102+
cout << "- " << field.key << ": " << field.value << endl;
103103
}
104104
}
105105
```
106106

107+
C++17 Support
108+
-------------
109+
110+
While the simdjson library can be used in any project using C++ 11 and above, it has special support
111+
for C++ 17. The APIs for field iteration and error handling in particular are designed to work
112+
nicely with C++17's destructuring syntax. For example:
113+
114+
```c++
115+
dom::parser parser;
116+
padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded;
117+
auto [object, error] = parser.parse(json).get<dom::object>();
118+
for (auto [key, value] : object) {
119+
cout << key << " = " << value << endl;
120+
}
121+
```
122+
123+
For comparison, here is the C++ 11 version of the same code:
124+
125+
```c++
126+
// C++ 11 version for comparison
127+
dom::parser parser;
128+
padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded;
129+
dom::object object;
130+
simdjson::error_code error;
131+
parser.parse(json).get<dom::object>().tie(object, error);
132+
for (dom::key_value_pair field : object) {
133+
cout << field.key << " = " << field.value << endl;
134+
}
135+
```
136+
107137
JSON Pointer
108138
------------
109139

@@ -159,7 +189,9 @@ auto cars_json = R"( [
159189
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
160190
] )"_padded;
161191
dom::parser parser;
162-
auto [cars, error] = parser.parse(cars_json).get<dom::array>();
192+
dom::array cars;
193+
simdjson::error_code error;
194+
parser.parse(cars_json).get<dom::array>().tie(cars, error);
163195
if (error) { cerr << error << endl; exit(1); }
164196
165197
// Iterating through an array of objects
@@ -196,8 +228,8 @@ for (dom::element tire_pressure_element : tire_pressure_array) {
196228
cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl;
197229
198230
// Writing out all the information about the car
199-
for (auto [key, value] : car) {
200-
cout << "- " << key << ": " << value << endl;
231+
for (auto field : car) {
232+
cout << "- " << field.key << ": " << field.value << endl;
201233
}
202234
```
203235

examples/quickstart/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ JSONEXAMPLES=$(ROOT)/jsonexamples
55
test: quickstart twitter.json
66
./quickstart
77
quickstart: quickstart.cpp simdjson.cpp simdjson.h
8-
c++ -o ./quickstart quickstart.cpp simdjson.cpp -std=c++17
8+
c++ -o ./quickstart quickstart.cpp simdjson.cpp
99
clean:
10-
rm -f simdjson.cpp simdjson.h twitter.json quickstart
10+
rm -f simdjson.cpp simdjson.h twitter.json quickstart quickstart11 quickstart14
1111
simdjson.cpp: $(SINGLEHEADER)/simdjson.cpp
1212
cp $(SINGLEHEADER)/simdjson.cpp .
1313
simdjson.h: $(SINGLEHEADER)/simdjson.h

include/simdjson/common_defs.h

Lines changed: 71 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,20 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
3737
} // namespace simdjson
3838

3939
#if defined(__GNUC__)
40-
// Marks a block with a name so that MCA analysis can see it.
41-
#define BEGIN_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-BEGIN " #name);
42-
#define END_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-END " #name);
43-
#define DEBUG_BLOCK(name, block) BEGIN_DEBUG_BLOCK(name); block; END_DEBUG_BLOCK(name);
40+
// Marks a block with a name so that MCA analysis can see it.
41+
#define BEGIN_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-BEGIN " #name);
42+
#define END_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-END " #name);
43+
#define DEBUG_BLOCK(name, block) BEGIN_DEBUG_BLOCK(name); block; END_DEBUG_BLOCK(name);
4444
#else
45-
#define BEGIN_DEBUG_BLOCK(name)
46-
#define END_DEBUG_BLOCK(name)
47-
#define DEBUG_BLOCK(name, block)
45+
#define BEGIN_DEBUG_BLOCK(name)
46+
#define END_DEBUG_BLOCK(name)
47+
#define DEBUG_BLOCK(name, block)
4848
#endif
4949

5050
#if !defined(_MSC_VER) && !defined(SIMDJSON_NO_COMPUTED_GOTO)
51-
// Implemented using Labels as Values which works in GCC and CLANG (and maybe
52-
// also in Intel's compiler), but won't work in MSVC.
53-
#define SIMDJSON_USE_COMPUTED_GOTO
51+
// Implemented using Labels as Values which works in GCC and CLANG (and maybe
52+
// also in Intel's compiler), but won't work in MSVC.
53+
#define SIMDJSON_USE_COMPUTED_GOTO
5454
#endif
5555

5656
// Align to N-byte boundary
@@ -60,54 +60,76 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
6060
#define ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
6161

6262
#ifdef _MSC_VER
63-
#define really_inline __forceinline
64-
#define never_inline __declspec(noinline)
6563

66-
#define UNUSED
67-
#define WARN_UNUSED
64+
#define really_inline __forceinline
65+
#define never_inline __declspec(noinline)
6866

69-
#ifndef likely
70-
#define likely(x) x
71-
#endif
72-
#ifndef unlikely
73-
#define unlikely(x) x
74-
#endif
67+
#define UNUSED
68+
#define WARN_UNUSED
7569

76-
#define SIMDJSON_PUSH_DISABLE_WARNINGS __pragma(warning( push ))
77-
#define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS __pragma(warning( push, 0 ))
78-
#define SIMDJSON_DISABLE_VS_WARNING(WARNING_NUMBER) __pragma(warning( disable : WARNING_NUMBER ))
79-
#define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_VS_WARNING(4996)
80-
#define SIMDJSON_POP_DISABLE_WARNINGS __pragma(warning( pop ))
70+
#ifndef likely
71+
#define likely(x) x
72+
#endif
73+
#ifndef unlikely
74+
#define unlikely(x) x
75+
#endif
8176

82-
#else // MSC_VER
77+
#define SIMDJSON_PUSH_DISABLE_WARNINGS __pragma(warning( push ))
78+
#define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS __pragma(warning( push, 0 ))
79+
#define SIMDJSON_DISABLE_VS_WARNING(WARNING_NUMBER) __pragma(warning( disable : WARNING_NUMBER ))
80+
#define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_VS_WARNING(4996)
81+
#define SIMDJSON_POP_DISABLE_WARNINGS __pragma(warning( pop ))
8382

83+
#if SIMDJSON_USING_LIBRARY
84+
#define SIMDJSON_DLLIMPORTEXPORT __declspec(dllimport)
85+
#else
86+
#define SIMDJSON_DLLIMPORTEXPORT __declspec(dllexport)
87+
#endif
8488

85-
#define really_inline inline __attribute__((always_inline, unused))
86-
#define never_inline inline __attribute__((noinline, unused))
89+
#else // MSC_VER
8790

88-
#define UNUSED __attribute__((unused))
89-
#define WARN_UNUSED __attribute__((warn_unused_result))
91+
#define really_inline inline __attribute__((always_inline, unused))
92+
#define never_inline inline __attribute__((noinline, unused))
93+
94+
#define UNUSED __attribute__((unused))
95+
#define WARN_UNUSED __attribute__((warn_unused_result))
96+
97+
#ifndef likely
98+
#define likely(x) __builtin_expect(!!(x), 1)
99+
#endif
100+
#ifndef unlikely
101+
#define unlikely(x) __builtin_expect(!!(x), 0)
102+
#endif
103+
104+
#define SIMDJSON_PUSH_DISABLE_WARNINGS _Pragma("GCC diagnostic push")
105+
// gcc doesn't seem to disable all warnings with all and extra, add warnings here as necessary
106+
#define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \
107+
SIMDJSON_DISABLE_GCC_WARNING(-Wall) \
108+
SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \
109+
SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \
110+
SIMDJSON_DISABLE_GCC_WARNING(-Wunused-parameter) \
111+
SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough)
112+
#define SIMDJSON_PRAGMA(P) _Pragma(#P)
113+
#define SIMDJSON_DISABLE_GCC_WARNING(WARNING) SIMDJSON_PRAGMA(GCC diagnostic ignored #WARNING)
114+
#define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wdeprecated-declarations)
115+
#define SIMDJSON_POP_DISABLE_WARNINGS _Pragma("GCC diagnostic pop")
116+
117+
#define SIMDJSON_DLLIMPORTEXPORT
90118

91-
#ifndef likely
92-
#define likely(x) __builtin_expect(!!(x), 1)
93-
#endif
94-
#ifndef unlikely
95-
#define unlikely(x) __builtin_expect(!!(x), 0)
96-
#endif
119+
#endif // MSC_VER
97120

98-
#define SIMDJSON_PUSH_DISABLE_WARNINGS _Pragma("GCC diagnostic push")
99-
// gcc doesn't seem to disable all warnings with all and extra, add warnings here as necessary
100-
#define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \
101-
SIMDJSON_DISABLE_GCC_WARNING(-Wall) \
102-
SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \
103-
SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \
104-
SIMDJSON_DISABLE_GCC_WARNING(-Wunused-parameter) \
105-
SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough)
106-
#define SIMDJSON_PRAGMA(P) _Pragma(#P)
107-
#define SIMDJSON_DISABLE_GCC_WARNING(WARNING) SIMDJSON_PRAGMA(GCC diagnostic ignored #WARNING)
108-
#define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wdeprecated-declarations)
109-
#define SIMDJSON_POP_DISABLE_WARNINGS _Pragma("GCC diagnostic pop")
121+
//
122+
// Backfill std::string_view using nonstd::string_view on C++11
123+
//
124+
#if (!SIMDJSON_CPLUSPLUS17)
110125

111-
#endif // MSC_VER
126+
SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
127+
#include "simdjson/nonstd/string_view.hpp"
128+
SIMDJSON_POP_DISABLE_WARNINGS
129+
130+
namespace std {
131+
using string_view = nonstd::string_view;
132+
}
133+
#endif // if (SIMDJSON_CPLUSPLUS < 201703L)
112134

113135
#endif // SIMDJSON_COMMON_DEFS_H

include/simdjson/compiler_check.h

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,23 @@
1313
#endif
1414
#endif
1515

16-
// Backfill std::string_view using nonstd::string_view on C++11
17-
#ifndef SIMDJSON_INCLUDE_NONSTD_STRING_VIEW
18-
#define SIMDJSON_INCLUDE_NONSTD_STRING_VIEW 1
19-
#endif // SIMDJSON_INCLUDE_NONSTD_STRING_VIEW
20-
#if (SIMDJSON_CPLUSPLUS < 201703L and SIMDJSON_INCLUDE_NONSTD_STRING_VIEW)
21-
// #error simdjson requires a compiler compliant with the C++17 standard
22-
#include "nonstd/string_view.hpp"
23-
namespace std {
24-
using string_view=nonstd::string_view;
25-
}
16+
// C++ 17
17+
#if !defined(SIMDJSON_CPLUSPLUS17) && (SIMDJSON_CPLUSPLUS >= 201703L)
18+
#define SIMDJSON_CPLUSPLUS17 1
19+
#endif
20+
21+
// C++ 14
22+
#if !defined(SIMDJSON_CPLUSPLUS14) && (SIMDJSON_CPLUSPLUS >= 201402L)
23+
#define SIMDJSON_CPLUSPLUS14 1
24+
#endif
25+
26+
// C++ 11
27+
#if !defined(SIMDJSON_CPLUSPLUS11) && (SIMDJSON_CPLUSPLUS >= 201103L)
28+
#define SIMDJSON_CPLUSPLUS11 1
29+
#endif
30+
31+
#ifndef SIMDJSON_CPLUSPLUS11
32+
#error simdjson requires a compiler compliant with the C++11 standard
2633
#endif
2734

2835
#endif // SIMDJSON_COMPILER_CHECK_H

include/simdjson/implementation.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,14 @@ class atomic_ptr {
223223
/**
224224
* The list of available implementations compiled into simdjson.
225225
*/
226-
extern const internal::available_implementation_list available_implementations;
226+
extern SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list available_implementations;
227227

228228
/**
229229
* The active implementation.
230230
*
231231
* Automatically initialized on first use to the most advanced implementation supported by this hardware.
232232
*/
233-
extern internal::atomic_ptr<const implementation> active_implementation;
233+
extern SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr<const implementation> active_implementation;
234234

235235
} // namespace simdjson
236236

0 commit comments

Comments
 (0)