Compare commits

..

523 Commits

Author SHA1 Message Date
Niels Lohmann
51e1564c9e Merge branch 'release/3.6.0' into develop 2019-03-20 00:38:29 +01:00
Niels Lohmann
0abf0f80c9 🔖 set version to 3.6.0 2019-03-20 00:22:12 +01:00
Niels Lohmann
b37392b7ac 🔖 set version to 3.6.0 2019-03-20 00:19:07 +01:00
Niels Lohmann
002addabd8 🚨 fixed a warning 2019-03-19 23:10:21 +01:00
Niels Lohmann
a6f9b4e36d 👥 added contributors 2019-03-19 17:18:33 +01:00
Niels Lohmann
18cc7ddd62 📝 completed documentation index page 2019-03-19 16:03:02 +01:00
Niels Lohmann
e07e8e7912 📝 updated documentation 2019-03-19 15:40:23 +01:00
Niels Lohmann
710f26f95c 📝 added documentation 2019-03-19 10:06:35 +01:00
Niels Lohmann
b224c52376 🎨 cleanup 2019-03-19 09:17:14 +01:00
Niels Lohmann
37a72dac48 💚 forgot two semicolons 2019-03-18 17:23:34 +01:00
Niels Lohmann
8d3f4f21bc 🔨 clean up 2019-03-18 13:53:48 +01:00
Niels Lohmann
9fc093c9e0 👷 added targets for infer and oclint 2019-03-18 00:19:28 +01:00
Niels Lohmann
22c733e6fe 📝 added documentation 2019-03-17 22:25:18 +01:00
Niels Lohmann
56f6d1d68e 💚 fix CI and #1521 2019-03-17 15:20:22 +01:00
Niels Lohmann
df0f7f2b5d 👷 overworked clang-tidy target 2019-03-17 12:02:23 +01:00
Niels Lohmann
9f26dac9b3 ⬆️ updated Doxyfile 2019-03-17 12:02:05 +01:00
Niels Lohmann
b8451c236f 🚨 fixed warnings 2019-03-17 12:01:49 +01:00
Niels Lohmann
d6c4cd3b6d 🚨 adding targets for static analyzers 2019-03-17 00:30:08 +01:00
Niels Lohmann
baf8b4be7c adding cpplint 2019-03-17 00:28:14 +01:00
Niels Lohmann
34f8b4f711 🚨 fixed more warnings 2019-03-17 00:27:44 +01:00
Niels Lohmann
02b3494711 🔥 removing unstable macOS builds on Traivs 2019-03-16 08:28:44 +01:00
Niels Lohmann
b02ee16721 🚨 fixed warnings 2019-03-15 15:55:52 +01:00
Niels Lohmann
8d6c033f80 Merge branch 'develop' of https://github.com/nlohmann/json into develop 2019-03-15 14:55:15 +01:00
Niels Lohmann
27011e3718 🚨 fixed warnings 2019-03-15 14:55:13 +01:00
Niels Lohmann
9dc3552931 Merge pull request #1514 from naszta/macrofix
Change macros to numeric_limits
2019-03-15 12:46:42 +01:00
Ferenc Nasztanovics
0067ea8f9e Change macros to numeric_limits #1483 2019-03-13 23:44:34 +01:00
Niels Lohmann
0c65ba960e Merge branch 'develop' of https://github.com/nlohmann/json into develop 2019-03-13 22:14:57 +01:00
Niels Lohmann
546e2cbf5e 🚨 fixed some warnings 2019-03-13 22:14:53 +01:00
Niels Lohmann
c6fc902184 Merge pull request #1489 from andreas-schwab/develop
Do proper endian conversions
2019-03-13 11:57:58 +01:00
Niels Lohmann
d39842e68f Merge pull request #1330 from ax3l/topic-installEmbed
CMake: Optional Install if Embedded
2019-03-13 11:13:09 +01:00
Niels Lohmann
670f42b561 🔥 removing Xcode 6.4 builder 2019-03-11 22:59:22 +01:00
Niels Lohmann
c983b67112 Merge pull request #1469 from garethsb-sony/json_pointer-append
Add operator/= and operator/ to construct a JSON pointer by appending two JSON pointers
2019-03-11 22:47:08 +01:00
Niels Lohmann
c11bead2ae 👷 removing more retired Travis images 2019-03-11 21:22:30 +01:00
Niels Lohmann
3cd1dac653 🚨 fix MSVC warning #1502 2019-03-11 15:33:23 +01:00
Niels Lohmann
cabe2357b8 Merge pull request #1492 from stac47/fix_gcc9_allocator
Fix gcc9 build error test/src/unit-allocator.cpp (Issue #1472)
2019-03-11 15:21:54 +01:00
Niels Lohmann
16d9cdce45 📝 updated documentation of CI 2019-03-11 15:19:50 +01:00
Niels Lohmann
e3729ba0a5 💚 fix compiler selection 2019-03-11 07:44:40 +01:00
Niels Lohmann
e5c7fd488d 👷 trying new Travis workers 2019-03-10 22:56:14 +01:00
Niels Lohmann
5047c7a217 🐛 added missing include #1500 2019-03-10 22:26:57 +01:00
Niels Lohmann
8eb7db7277 Merge pull request #1441 from iwanders/support-cmake-older-than-3-8-with-if
Use C++11 features supported by CMake 3.1.
2019-03-10 22:08:16 +01:00
Niels Lohmann
393410e61a Merge pull request #1495 from njlr/patch-1
Update Buckaroo instructions in README.md
2019-03-10 22:03:49 +01:00
Niels Lohmann
30edcaab3a Merge pull request #1496 from lieff/develop
fix GCC 7.1.1 - 7.2.1 on CentOS
2019-03-10 22:01:52 +01:00
lieff
7b31e56fbf fix GCC 7.1.1 - 7.2.1 on CentOS
closes https://github.com/nlohmann/json/issues/670
2019-02-25 16:38:22 +03:00
Andreas Schwab
bb22b1003f Do proper endian conversions
This fixes all testsuite failures on big endian hosts.
2019-02-25 12:09:13 +01:00
njlr
8aeee4f7e3 Update README.md
* Updates Buckaroo instructions to v2
2019-02-25 09:44:38 +00:00
garethsb-sony
d183bd0456 Tests for json_pointer::empty and json_pointer::parent_pointer 2019-02-25 09:26:08 +00:00
garethsb-sony
08de9eeaca Add json_pointer::parent_pointer (cf. std::filesystem::path::parent_path) 2019-02-25 09:26:08 +00:00
garethsb-sony
164e0e54d9 Rename private json_pointer::is_root as public json_pointer::empty for consistency with std::filesystem::path 2019-02-25 09:26:07 +00:00
Laurent Stacul
ddc9f201f4 Fix gcc9 build error test/src/unit-allocator.cpp (Issue #1472) 2019-02-22 16:05:41 +00:00
Niels Lohmann
21516f2bae Merge pull request #1491 from nickaein/patch-1
Fix typo in README.md
2019-02-22 09:50:45 +01:00
Isaac Nickaein
088a245218 Fix typo in README.ME
Fixes https://github.com/nlohmann/json/issues/1486.
2019-02-22 01:05:00 +03:30
Niels Lohmann
e326df211b Merge pull request #1474 from nickaein/develop
Implement contains() member function
2019-02-13 13:05:21 +01:00
Niels Lohmann
c55cacee1e Merge pull request #1477 from nickaein/fix-doc
Fix documentation
2019-02-13 13:03:46 +01:00
Isaac Nickaein
e93f305494 Add unit-test for contains() member function 2019-02-13 13:21:54 +03:30
Isaac Nickaein
6a5db00951 Implement contains() to check existence of a key 2019-02-13 13:21:54 +03:30
Isaac Nickaein
fb5ceb26ac Fix documentation
Remove two instance of duplicate paragraphs.
2019-02-11 17:00:48 +03:30
Niels Lohmann
46ff13d39e Merge pull request #1468 from past-due/disable_Wmismatched_tags_on_tuple
Disable Clang -Wmismatched-tags warning on tuple_size / tuple_element
2019-02-10 21:50:12 +01:00
Niels Lohmann
eee3bc0c79 Merge pull request #1464 from elvisoric/update_meson_install_step
Disable installation when used as meson subproject. #1463
2019-02-10 21:48:20 +01:00
garethsb-sony
5da757bbb3 Attempt to satisfy Coveralls by adding a test for (unchanged) operator std::string 2019-01-31 23:39:57 +00:00
garethsb-sony
c850e9d82d Add operator/= and operator/ to construct a JSON pointer by appending two JSON pointers, as well as convenience op/= and op= to append a single unescaped token or array index; inspired by std::filesystem::path 2019-01-31 19:15:50 +00:00
past-due
45819dce54 Disable -Wmismatched-tags warning on tuple_size / tuple_element 2019-01-30 12:59:50 -05:00
Elvis Oric
77d1d37290 Disable installation when used as meson subproject. #1463 2019-01-30 11:40:14 +01:00
Niels Lohmann
68ec3eb8d6 Merge pull request #1451 from Afforix/Afforix-fix-extra-semicolon
remove extra semicolon from readme
2019-01-25 13:36:18 +01:00
Niels Lohmann
de14b5ee2f Merge pull request #1455 from wythe/patch-2
docs: README typo
2019-01-25 13:36:07 +01:00
Mark Beckwith
cca6d0dbae docs: README type
Just another small typo I found in the README.
2019-01-24 10:49:45 -06:00
Patrick Boettcher
a06e7f5d80 JSON-pointer: add operator+() returning a new json_pointer 2019-01-24 16:46:51 +01:00
Matěj Plch
dc21cbb751 remove extra semicolon
in example of NLOHMANN_JSON_SERIALIZE_ENUM
2019-01-22 10:13:12 +01:00
Niels Lohmann
e89c946451 Merge branch 'feature/nodiscard' into develop 2019-01-20 15:41:30 +01:00
Niels Lohmann
6de4df23e4 🐛 fixed integer overflow in dump function #1447
Closes #1447.
2019-01-20 12:26:01 +01:00
Niels Lohmann
e17e0d031f Merge pull request #1446 from scinart/develop
attempt to fix #1445, flush buffer in serializer::dump_escaped in UTF8_REJECT case.
2019-01-20 12:18:02 +01:00
Niels Lohmann
e36593e960 🔨 trying code from https://godbolt.org/z/-tLO1K 2019-01-20 11:12:20 +01:00
scinart
20db020c1f move newly-added tests in unit-regression.cpp 2019-01-19 11:36:50 -05:00
Niels Lohmann
d359fd3a8d 🚧 trying nodiscard attribute #1433 2019-01-19 17:32:23 +01:00
Niels Lohmann
b9a39b38bf Merge pull request #1434 from pboettch/develop
allow push_back() and pop_back() calls on json_pointer
2019-01-19 17:07:36 +01:00
scinart
83e84446d6 fix typo 2019-01-18 20:55:01 -05:00
scinart
899bd94b43 flush buffer in serializer::dump_escaped case UTF8_REJECT
serializer use fixed buffer. Whenever it is nearly full, it is flushed to `output_adapter_t<char> o`
But the code forgets to flush when there is a invalid utf8 code point
So there will be buffer overflow.
2019-01-18 20:35:48 -05:00
Ivor Wanders
4fd9b52fc2 Use C++11 features supported by CMake 3.1. 2019-01-16 08:50:58 -05:00
Niels Lohmann
dffae1082f Merge pull request #1435 from pboettch/warning-fix
🚨 fixed unused variable warning
2019-01-15 22:18:13 +01:00
Niels Lohmann
851fe8a5ef Merge pull request #1430 from nicoddemus/conda-docs
Add instructions about using nlohmann/json with the conda package manager
2019-01-15 22:16:49 +01:00
Patrick Boettcher
d0c0d16110 🚨 fixed unused variable warning
Since 6503e83e74 "Improve dump_integer performance by implementing a more efficient int2ascii"
an unused variable and thus a warning existed.
2019-01-15 15:21:02 +01:00
Patrick Boettcher
9225cf2f57 allow push_back() and pop_back() calls on json_pointer
Putting pop_back() to public and creating a trivial push_back()
method allows users of nlohmann::json_pointer to manipulate an
existing json-pointer by adding or removing keys at the end.

This is useful for traversing a JSON-instance and keeping track
of its "absolute path" at any moment.

In my case for a schema-validator error-handler.
2019-01-15 14:43:46 +01:00
Bruno Oliveira
b025d66eb5 Add instructions about using nlohmann/json with the conda package manager 2019-01-15 11:06:26 -02:00
Niels Lohmann
e5753b14a8 🚨 fixed another linter warning #1400
Closes #1400.
2019-01-13 15:40:49 +01:00
Niels Lohmann
5c04cc1009 🔨 fixed includes 2019-01-13 15:31:22 +01:00
Niels Lohmann
8e9ad346d9 🚨 fixed another linter warning 2019-01-13 13:00:54 +01:00
Niels Lohmann
ad01736d55 💡 improved documentation for parsing without exceptions #1405
Closes #1405
2019-01-13 11:46:05 +01:00
Niels Lohmann
06731b14d7 ⬆️ upgraded Catch and Google Benchmark
- Catch 1.12.0 -> 1.12.2
- Google Benchmark 1.3.0 -> 1.4.1
2019-01-13 11:29:39 +01:00
Niels Lohmann
daeb48b01a Merge pull request #1411 from nickaein/develop
Improve dump_integer performance
2019-01-13 11:11:51 +01:00
Niels Lohmann
29a03f465e Merge pull request #1414 from nickaein/mydevel-appveyor-x64
Fix x64 target platform for appveyor
2019-01-12 23:09:19 +01:00
Isaac Nickaein
c9dd260a4c Add unit tests for dump_integer
Add some unit tests for formatting integers
to keep code coverage as before.
2019-01-12 08:58:30 -08:00
Isaac Nickaein
be9b4cbd60 Add benchmark for small integers
This benchmark is a sample of 1 million "small" integers
in range [-1000000 1000000) sampled from uniform distribution.
2019-01-12 08:58:30 -08:00
Isaac Nickaein
6503e83e74 Improve dump_integer performance by implementing a more efficient int2ascii
This commits implements a faster int2ascii inspired by "Fastware" talk given
by Andrei Alexandrescu.
See: https://www.youtube.com/watch?v=o4-CwDo2zpg
2019-01-12 08:58:30 -08:00
Isaac Nickaein
f16432832c Increase stack size for VS2017 Win x64 on Appveyor 2019-01-12 19:27:26 +03:30
Niels Lohmann
b39f34e046 Merge pull request #1425 from hijxf/patch-1
Updated year in README.md
2019-01-12 10:23:31 +01:00
Jef LeCompte
7f73915d4f Updated year in README.md 2019-01-11 08:54:03 -05:00
Niels Lohmann
df460c96cf Merge pull request #1423 from skypjack/patch-1
Fixed broken links in the README file
2019-01-10 13:52:52 +01:00
Michele Caini
6546cad7bf Fixed broken links in the README file 2019-01-10 08:54:53 +01:00
Niels Lohmann
847dd2a954 Merge pull request #1420 from skypjack/patch-1
Fixed broken links in the README file
2019-01-09 22:33:40 +01:00
Niels Lohmann
937b642e0e 📝 added description on how to use NuGet package #1132
Closes #1132.
2019-01-09 21:08:06 +01:00
Niels Lohmann
975dc970d1 Merge pull request #1417 from wythe/patch-1
docs: typo in README
2019-01-09 20:35:49 +01:00
Michele Caini
b8be0f64ae Fixed broken links to operator[]() and at() 2019-01-09 15:11:54 +01:00
Michele Caini
619bf9c20d Fixed broke links to RFC7159 2019-01-09 15:05:09 +01:00
Mark Beckwith
a559ff8fc6 typo in README
inintended -> unintended
2019-01-08 13:24:07 -06:00
Isaac Nickaein
2c0c2ca698 Specify target platform in generator name 2019-01-05 14:15:33 -08:00
Niels Lohmann
676c847c55 Merge pull request #1409 from yann-morin-1998/yem/cmake-version
buildsystem: relax requirement on cmake version
2019-01-01 17:17:38 +01:00
Yann E. MORIN
e8b6b7adc1 buildsystem: relax requirement on cmake version
Commit 73cc5089 (Using target_compile_features to specify C++ 11
standard) bumped the required cmake version, from 3.0 to 3.8, so
as to get the definition of target_compile_features().

However, target_compile_features() was introduced in cmake-3.1:
    https://cmake.org/cmake/help/v3.1/command/target_compile_features.html

And using cmake-3.1 is indeed sufficient to properly build.

As such, relax the minimum required version down to cmake-3.1,
so we can build on oldish, entreprise-grade distributions that
only have cmake-3.1 (or at least, don't have up to cmake-3.8).

Reported-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
2018-12-31 18:52:04 +01:00
Niels Lohmann
c682b9879b 🚨 fixed PVS V567 warning
"V567 The modification of the 'position.chars_read_current_line' variable is unsequenced relative to another operation on the same variable. This may lead to undefined behavior."
2018-12-30 23:00:15 +01:00
Niels Lohmann
6f89613acd 🚨 fixed some warnings 2018-12-23 13:56:18 +01:00
Niels Lohmann
db53bdac19 Merge branch 'release/3.5.0' into develop 2018-12-22 00:01:28 +01:00
Niels Lohmann
78348afeb6 🔖 set version to 3.5.0 2018-12-21 23:52:29 +01:00
Niels Lohmann
1107f8cd82 📝 updated documentation for items() function 2018-12-21 22:51:12 +01:00
Niels Lohmann
98f4e31c3e 📝 formatted picture 2018-12-21 18:33:46 +01:00
Niels Lohmann
58c269b039 📝 updated documentation 2018-12-21 18:27:56 +01:00
Niels Lohmann
2182157dc1 📝 update documentation 2018-12-21 09:32:35 +01:00
Niels Lohmann
45f5611d9b 🚨 fixed two warnings 2018-12-20 22:41:48 +01:00
Niels Lohmann
117c1d14fb 📝 added contributors to 3.5.0 2018-12-20 22:20:47 +01:00
Niels Lohmann
d584ab269a 🎨 fixed header 2018-12-20 21:58:16 +01:00
Niels Lohmann
45a8a093d7 🚨 fixed a warning 2018-12-20 21:40:47 +01:00
Niels Lohmann
85849940ba Merge pull request #1391 from pratikpc/develop
Added Support for Structured Bindings
2018-12-20 08:58:08 +01:00
Pratik Chowdhury
ebd3f45808 Added Support for Structured Bindings
For further details, read https://github.com/nlohmann/json/issues/1388 and https://blog.tartanllama.xyz/structured-bindings/
2018-12-19 20:17:52 +05:30
Niels Lohmann
4f270e38cc Merge pull request #1342 from davedissian/bugfix/sfinae-iterator-traits
Add a SFINAE friendly iterator_traits and use that instead.
2018-12-19 08:24:18 +01:00
David Avedissian
f1080d7c39 Code review. 2018-12-18 20:44:37 +00:00
Niels Lohmann
5d390e91ff Merge pull request #1392 from mtalliance/feature/addFileInputAdapter
Feature/add file input adapter
2018-12-16 22:10:03 +01:00
Jonathan Dumaresq
c1c85b025c Forget one std::FILE 2018-12-14 07:33:28 -05:00
Jonathan Dumaresq
635a4fc344 use namespace std when possible. Change the name of private variable. 2018-12-12 16:33:25 -05:00
Jonathan Dumaresq
cf31193de2 create single json.hpp file 2018-12-12 14:46:52 -05:00
Jonathan Dumaresq
a794cfdba3 refactor unit test in case of throw, the fclose will not be called. using unique_ptr with custom destructor will ensure that 2018-12-12 14:46:17 -05:00
Jonathan Dumaresq
91ff96a737 remove the const attribute 2018-12-12 14:16:12 -05:00
Jonathan Dumaresq
b7a2642fba remove comment 2018-12-12 14:15:49 -05:00
Jonathan Dumaresq
fa7f1a524e new unified json.hpp generated with make amalgamate 2018-12-12 10:19:22 -05:00
Jonathan Dumaresq
ef283e0cf8 add tests to cover the new input adapter 2018-12-12 10:18:37 -05:00
Jonathan Dumaresq
3335da622a remove non usefull code. 2018-12-12 09:32:52 -05:00
Jonathan Dumaresq
ae48acbb23 remove non usefull code. Add small description 2018-12-12 09:28:42 -05:00
Jonathan Dumaresq
52f6fd1d91 Add the possibility of using FILE * from cstdio library to read a file. This enable the possibility of using low eand device with this library. 2018-12-11 13:17:13 -05:00
Jonathan Dumaresq
67b0daf27b Add the possibility of using FILE * from cstdio library to read a file. This enable the possibility of using low eand device with this library. 2018-12-11 09:33:30 -05:00
David Avedissian
2c23f0a346 Changes requested from code review. 2018-12-08 15:46:33 +00:00
Niels Lohmann
e73dfef6e5 Merge pull request #1382 from kjpus/patch-1
Link to issue #958 broken
2018-12-04 20:02:38 +01:00
kjpus
767a3a327d Link to issue #958 broken 2018-12-04 10:03:10 -05:00
Niels Lohmann
d53873a251 Merge pull request #1363 from theodelrieu/doc/implicit_conversions
recommend using explicit from JSON conversions
2018-12-02 17:27:46 +01:00
Niels Lohmann
7a56f5a42b Merge pull request #1380 from manu-chroma/patch-1
readme: fix typo
2018-12-02 17:25:38 +01:00
Manvendra Singh
5de184b8fb readme: fix typo 2018-12-02 01:50:57 +05:30
Niels Lohmann
ef90d62ddf 🚨 fixed warning #1364 2018-11-21 21:17:38 +01:00
Théo DELRIEU
7b961368d5 recommend using explicit from JSON conversions 2018-11-20 14:14:07 +01:00
Niels Lohmann
da81e7be22 🏁 adding parentheses around std::snprintf calls #1337 2018-11-09 21:18:02 +01:00
Niels Lohmann
f80efd3954 💄 cleanup 2018-11-09 21:10:32 +01:00
Niels Lohmann
35829928da Merge pull request #1343 from mefyl/develop
Set eofbit on exhausted input stream.
2018-11-09 21:07:36 +01:00
Niels Lohmann
f86090aafc Merge pull request #1345 from mpoquet/feature/meson-install-pkgconfig
Allow installation via Meson
2018-11-08 18:39:26 +01:00
Niels Lohmann
30e1cbb0df Merge pull request #1346 from ax3l/fix-mergePatchShadowParam
Fix merge_patch shadow warning
2018-11-08 18:38:40 +01:00
mefyl
aa10382629 Set eofbit on exhausted input stream.
Fix issue #1340.

        The eofbit is set manually since we don't go through the
	stream interface. We could maybe use the stream interface
	instead, but there are some assumptions regarding which
	exception go through, so this seems to be the most prudent
	approach for now.
2018-11-08 11:41:17 +01:00
Axel Huebl
798754dfb6 Amalgamate Headers 2018-11-08 10:35:45 +01:00
Axel Huebl
97b81da840 merge_patch: rename parameter
Avoid shadowing a member of `this` by choosing the same name as
parameter (`-Wshadow`). Instead, make name of parameter more
expressive.
2018-11-08 10:31:47 +01:00
Millian Poquet
ffe08983dd :meson: install headers + pkg-config 2018-11-08 00:25:42 +01:00
David Avedissian
f665a92330 Implement SFINAE friendly iterator_traits and use that instead. 2018-11-07 18:39:25 +00:00
Niels Lohmann
d2e6e1bf58 Merge pull request #1329 from ax3l/fix-typosWhitespaces
Fix EOL Whitespaces & CMake Spelling
2018-11-02 18:23:42 +01:00
Axel Huebl
a7567bc596 Remove EOL whitespaces in natvis 2018-11-02 10:42:48 +01:00
Axel Huebl
f049836d68 CMake: Optional Install if Embedded
When adding this library as embedded library with private
"target link", e.g. only used inside private source files, the
library does not need to be installed when the main project gets
installed.

This adds an additional option `JSON_Install` similar to the
test-build control switch in order to skip installing headers and
CMake config files if requested.

Avoids using
```cmake
add_subdirectory(path/to/nlohmann_json EXCLUDE_FROM_ALL)
```

which has further side-effects:
https://cmake.org/cmake/help/v3.0/command/add_subdirectory.html
2018-11-02 10:18:00 +01:00
Axel Huebl
689382a722 Fix EOL Whitespaces & CMake Spelling
Fix little leftover EOL whitespaces in `CMakeLists.txt` and
a spelling of CMake in README.md
2018-11-02 09:35:17 +01:00
Niels Lohmann
2f73a4d1f3 🚨 fixed a linter warning 2018-10-31 20:30:24 +01:00
Niels Lohmann
e3c28afb61 Merge branch 'release/3.4.0' into develop 2018-10-30 22:20:29 +01:00
Niels Lohmann
0f3c74d821 🔖 set version to 3.4.0 2018-10-30 22:18:45 +01:00
Niels Lohmann
7b2f8cce03 🔖 set version to 3.4.0 2018-10-30 21:30:20 +01:00
Niels Lohmann
8cee0e38d9 🚑 fixed #1319 2018-10-30 17:29:05 +01:00
Niels Lohmann
856fc31d0a 💄 fixed indentation 2018-10-29 19:44:19 +01:00
Niels Lohmann
39419cd5c4 🚨 fixed another linter warning 2018-10-29 18:51:30 +01:00
Niels Lohmann
86b5ce953a 📝 added examples for BSON functions 2018-10-28 15:09:26 +01:00
Niels Lohmann
d2e4f0b0d9 ✏️ fixed some typos 2018-10-28 14:20:20 +01:00
Niels Lohmann
f0c1459554 🐛 fixed a bug parsing BSON strings #1320 2018-10-28 09:16:40 +01:00
Niels Lohmann
24946f67f1 🚨 fixed some more linter warnings 2018-10-28 09:15:41 +01:00
Niels Lohmann
7d0dc10169 🚨 fixed a linter warning 2018-10-27 18:34:35 +02:00
Niels Lohmann
45a761bd60 Merge branch 'develop' of https://github.com/nlohmann/json into develop 2018-10-27 18:31:06 +02:00
Niels Lohmann
4e765596f7 🔨 small improvements 2018-10-27 18:31:03 +02:00
Niels Lohmann
1308ea055d Merge pull request #1315 from nlohmann/feature/convert_char
Properly convert constants to CharType
2018-10-27 16:56:00 +02:00
Niels Lohmann
0e7be06bef Merge pull request #1323 from nlohmann/feature/enum_json_mapping
Add macro to define enum/JSON mapping
2018-10-27 16:55:39 +02:00
Niels Lohmann
85aaf91b85 Merge branch 'develop' into feature/enum_json_mapping 2018-10-27 16:52:59 +02:00
Niels Lohmann
5a6bdf5934 Merge branch 'develop' into feature/convert_char 2018-10-27 16:48:48 +02:00
Niels Lohmann
037e93f5c0 Merge pull request #1320 from nlohmann/julian-becker-feature/bson
Add BSON support
2018-10-27 16:37:54 +02:00
Niels Lohmann
9f48bb6937 replaced vector by array #1323 2018-10-27 09:58:23 +02:00
Niels Lohmann
6384fe28db 🚨 fixed another linter warning 2018-10-26 23:12:41 +02:00
Niels Lohmann
ad639ad5e6 added NLOHMANN_JSON_SERIALIZE_ENUM marco #1208 2018-10-26 14:48:20 +02:00
Niels Lohmann
544150d5a5 🚨 fixed another linter warning 2018-10-26 11:10:49 +02:00
Niels Lohmann
c2e175763c 👌 added another conversion function #1315 2018-10-25 22:47:08 +02:00
Niels Lohmann
d97fa30795 👌 fixed comment #1320 2018-10-25 22:29:27 +02:00
Niels Lohmann
7ce720b700 🚨 fixed coverage 2018-10-25 18:21:50 +02:00
Niels Lohmann
19647e083c 🚨 fixed compiler warnings 2018-10-25 14:27:55 +02:00
Niels Lohmann
62126278a6 🔨 added fix for arrays 2018-10-25 13:01:18 +02:00
Niels Lohmann
1968e5c793 🎨 clean up binary formats 2018-10-24 23:39:30 +02:00
Niels Lohmann
4d1eaace8c 🔨 fixed fuzz code to avoid false positives in case of discarded values 2018-10-24 18:55:08 +02:00
Niels Lohmann
e2c5913a50 🚧 some changes to the BSON code
- added fuzz testers
- added some reference files
- made an exception text more clear
2018-10-24 15:43:37 +02:00
Niels Lohmann
bba159121f Merge branch 'feature/bson' of https://github.com/julian-becker/json into julian-becker-feature/bson 2018-10-24 15:03:15 +02:00
Niels Lohmann
f102df3cba 📝 updated documentation #1314 2018-10-24 09:28:57 +02:00
Niels Lohmann
7b501de054 Merge pull request #1314 from nlohmann/feature/codec_errors
Allow to set error handler for decoding errors
2018-10-24 08:40:58 +02:00
Niels Lohmann
20038e2703 📝 added a note to the discussion #1286 2018-10-23 23:00:43 +02:00
Niels Lohmann
87ef3f25f2 ✏️ fixed a typo #1314 2018-10-23 22:56:10 +02:00
Niels Lohmann
b49f76931f 👌 replaced static_cast to CharType by conversion function #1286 2018-10-23 17:49:04 +02:00
Niels Lohmann
2343d9caeb 💚 additional tests from the Unicode spec #1198
Thanks @abolz!
2018-10-23 17:22:13 +02:00
Niels Lohmann
951a7a6455 🚧 fixed test cases #1198 2018-10-22 18:20:45 +02:00
Niels Lohmann
c51b1e6fab 🚧 fixed an issue with ensure_ascii #1198 2018-10-22 15:53:36 +02:00
Niels Lohmann
c7af027cbb 🚧 respect ensure_ascii parameter #1198 2018-10-22 09:18:16 +02:00
Niels Lohmann
e5dce64115 💚 added tests #1198
Test every prefix of Unicode sequences against the different dump functions.
2018-10-21 23:26:25 +02:00
Niels Lohmann
c5821d91e5 🚧 overworked error handlers #1198 2018-10-21 11:49:37 +02:00
Julian Becker
ad11b6c35e BSON: Improved exception-related tests and report location of U+0000 in the key-string as part of out_of_range.409-message 2018-10-18 20:05:46 +02:00
Niels Lohmann
9294e25c98 Merge pull request #1301 from theodelrieu/fix/1299
add new is_constructible_* traits used in from_json
2018-10-18 19:18:48 +02:00
Niels Lohmann
b553a8a93c Merge pull request #1305 from koponomarenko/add-meson-info
Add Meson related info to README
2018-10-18 10:55:25 +02:00
Julian Becker
5ba812d518 BSON: fixed incorrect casting in unit-bson.cpp 2018-10-18 06:38:34 +02:00
Julian Becker
8de10c518b BSON: Hopefully fixing ambiguity (on some compilers) to call to string::find() 2018-10-17 21:47:01 +02:00
Kostiantyn Ponomarenko
f0c55ce0e0 Add Meson related info to README
Add more information about how one can get a Meson wrap file.

Signed-off-by: Kostiantyn Ponomarenko <konstantin.ponomarenko@gmail.com>
2018-10-17 21:46:45 +03:00
Julian Becker
2a63869159 Merge branch 'develop' of https://github.com/nlohmann/json into feature/bson
Conflicts:
	include/nlohmann/detail/input/binary_reader.hpp
	single_include/nlohmann/json.hpp
	src/unit-bson.cpp
2018-10-17 20:26:00 +02:00
Niels Lohmann
4b2a00641c Merge pull request #1303 from nlohmann/feature/binary_errors
Improve diagnostic messages for binary formats
2018-10-17 17:54:14 +02:00
Niels Lohmann
dbb0b63187 improved error messages for binary formats #1288
This commit is the equivalent of #1282 for CBOR, MessagePack, and UBJSON.
2018-10-17 12:15:58 +02:00
Théo DELRIEU
a946dfc19c add a note to maintainers in type_traits.hpp 2018-10-17 12:03:10 +02:00
Julian Becker
978c3c4116 BSON: throw json.exception.out_of_range.409 in case a key to be serialized to BSON contains a U+0000 2018-10-16 20:42:00 +02:00
Niels Lohmann
0671e92ced 🚧 proposal for different error handlers #1198
Proof of concept; currently only as parameter to the internal dump_escaped function; that is, not yet exposed to the dump function.
2018-10-16 20:38:50 +02:00
Julian Becker
daa3ca8a2e BSON: Adjusted documentation of binary_writer::to_bson() 2018-10-16 19:29:42 +02:00
Julian Becker
5bccacda30 BSON: throw json.exception.out_of_range.407 in case a value of type std::uint64_t is serialized to BSON. Also, added a missing EOF-check to binary_reader. 2018-10-16 19:13:07 +02:00
Théo DELRIEU
45c8af2c46 add new is_constructible_* traits used in from_json
is_compatible_* traits were used in from_json, but it made no sense
whatsoever.

It used to work because of non-SFINAE correctness + json_ref
unconstrained variadic template constructor.

SFINAE checks are becoming quite complex, we need a specification of
some sort describing:

* which concepts the library uses
* how the conversion to/from json works in detail

Having such a specification would really help simplifying the current
code (as well as having meaningful checks).

Fixes !1299
2018-10-16 14:00:34 +02:00
Niels Lohmann
dd672939a0 Merge pull request #1294 from theodelrieu/fix/json_ref_ctor
add constraints for variadic json_ref constructors
2018-10-12 17:35:41 +02:00
Théo DELRIEU
11fecc25af add constraints for variadic json_ref constructors
Fixes #1292
2018-10-12 10:54:58 +02:00
Niels Lohmann
e426219256 Merge pull request #1282 from nlohmann/feature/lines_columns
Improve diagnostic messages
2018-10-08 22:17:33 +02:00
Niels Lohmann
adfa961ed0 Merge pull request #1280 from nlohmann/feature/linter
Removed linter warnings
2018-10-08 21:05:33 +02:00
Niels Lohmann
6d34d64bfd 🚑 fixed compilation error 2018-10-08 06:54:51 +02:00
Niels Lohmann
74a31075e3 improved parse error messages 2018-10-07 22:39:17 +02:00
Niels Lohmann
6e49d9f5ff 🚑 fixed compilation error 2018-10-07 21:34:40 +02:00
Niels Lohmann
f8158997b5 📝 fixed documentation 2018-10-07 21:30:58 +02:00
Julian Becker
df0f612d1b BSON: allow and discard values and object entries of type value_t::discarded 2018-10-07 20:08:05 +02:00
Niels Lohmann
3abb788139 🚨 fixed some more clang-tidy warnings 2018-10-07 19:07:58 +02:00
Niels Lohmann
858e75c4df 🚨 fixed some clang-tidy warnings 2018-10-07 18:39:18 +02:00
Julian Becker
062aeaf7b6 BSON: Reworked the binary_writer such that it precomputes the size of the BSON-output.
This way, the output_adapter can work on simple output iterators and no longer requires random access iterators.
2018-10-07 18:02:51 +02:00
Niels Lohmann
6d09cdec34 🐛 fixed a bug in the unget function 2018-10-07 16:48:45 +02:00
Niels Lohmann
011b15dd08 added line positions to error messages
This is a follow-up to #1210.
2018-10-07 12:27:24 +02:00
Julian Becker
81f4b34e06 BSON: Improved documentation and error handling/reporting 2018-10-07 09:57:55 +02:00
Niels Lohmann
ac38e95780 Merge pull request #1277 from performous/fix-clang-detection
Thirdparty benchmark: Fix Clang detection.
2018-10-06 16:29:26 +02:00
Niels Lohmann
fa722d5ac3 🚨 fixed another linter warning 2018-10-06 16:26:47 +02:00
Niels Lohmann
ec95438a59 🚨 fixed some linter warnings 2018-10-06 13:49:02 +02:00
Niels Lohmann
f1768a540a Merge branch 'release/3.3.0' into develop 2018-10-05 12:59:41 +02:00
Niels Lohmann
cdfe6ceda6 🔖 set version to 3.3.0 2018-10-05 11:20:10 +02:00
Niels Lohmann
b968faa882 🔖 set version to 3.3.0 2018-10-05 10:59:33 +02:00
Niels Lohmann
cd518fbbab 📝 small update to pass test suite 2018-10-05 08:58:38 +02:00
Gregorio Litenstein
e8427061a0 Thirdparty benchmark: Fix Clang detection.
CMake 3.0+ refers to macOS’ Clang as AppleClang, which would fail a STREQUAL check. Fixed by changing it to MATCHES.
2018-10-05 02:01:43 -03:00
Niels Lohmann
b911654857 📝 updated contributor list 2018-10-04 22:30:18 +02:00
Niels Lohmann
bb55885215 💄 cleaned code 2018-10-04 20:42:19 +02:00
Niels Lohmann
5c7d27c338 Merge pull request #1272 from antonioborondo/fix_warning
Fix warning C4127: conditional expression is constant
2018-10-04 20:33:26 +02:00
Antonio Borondo
b6fdad9acd Remove anonymous namespace 2018-10-03 13:51:49 +01:00
Antonio Borondo
7c385a4844 Fix error: 'wide_string_input_helper' was not declared in this scope 2018-10-03 12:41:34 +01:00
Antonio Borondo
9ba3f79667 Fix error: explicit specialization in non-namespace scope 2018-10-03 12:26:24 +01:00
Antonio Borondo
8d1585f065 Change implementation to use templates 2018-10-03 11:44:02 +01:00
Antonio Borondo
ad3c216bb5 Generate header 2018-10-03 11:27:53 +01:00
Antonio Borondo
0231059290 Fix warning 2018-10-03 11:27:53 +01:00
Niels Lohmann
9f18e17063 Merge pull request #1270 from chuckatkins/add-more-cmake-docs
docs: Add additional CMake documentation
2018-10-03 10:11:27 +02:00
Niels Lohmann
53ec0a16f3 Merge pull request #1271 from chuckatkins/cleanup-deprecated-warnings
Turn off additional deprecation warnings for GCC.
2018-10-02 22:07:18 +02:00
Chuck Atkins
4c617611e2 docs: Add additional CMake documentation 2018-10-02 14:28:20 -04:00
Chuck Atkins
829571ab5c Turn off additional deprecation warnings for GCC.
In follow up from the conversation in #1269, this adds the
`-Wno-deprecate-declarations` flag to unit tests to allow them to
test deprecated APIs without all the noisy compiler warnings.
This also refactors the setting of build properties for test targets
to use `target_<...>` commands instead of `set_target_properties()`.
2018-10-02 13:01:19 -04:00
Niels Lohmann
c8231eff75 Merge pull request #1260 from chuckatkins/fix-cmake-target-alias
Fix broken cmake imported target alias
2018-10-01 17:44:50 +02:00
Chuck Atkins
02e653bdf7 docs: add a note in the readme about using the CMake imported target 2018-09-30 22:52:54 -04:00
Chuck Atkins
564506a885 cmake: add import config tests 2018-09-30 22:52:47 -04:00
Chuck Atkins
1729db85c1 cmake: fix package config to deal with versioning and namespaces 2018-09-30 09:56:33 -04:00
Niels Lohmann
910a895027 Merge pull request #1238 from theodelrieu/fix/1237
Fix issue #1237
2018-09-29 14:50:54 +02:00
Niels Lohmann
1fae82b7a7 Merge branch 'develop' into fix/1237 2018-09-29 14:50:36 +02:00
Niels Lohmann
22e55349a6 📝 added Wandbox link #1227 2018-09-29 14:33:39 +02:00
Niels Lohmann
70e587c3da 📝 added Wandbox link #1227 2018-09-29 14:33:21 +02:00
Niels Lohmann
d26f39466e Merge pull request #1231 from theodelrieu/feature/get_with_parameter
Add a get overload taking a parameter.
2018-09-29 14:30:04 +02:00
Niels Lohmann
c61a9071ae 🚨 fixed a compilation issue with ICPC #755
Closes #1222
2018-09-29 11:50:14 +02:00
Julian Becker
e8730e5e82 BSON: Reworked binary_reader::get_bson_cstr() 2018-09-29 11:50:01 +02:00
Niels Lohmann
b59a58406e Merge branch 'develop' of https://github.com/nlohmann/json into develop 2018-09-29 11:48:52 +02:00
Niels Lohmann
4e54c9a13d 🚨 fixed a compilation issue with ICPC #755
Closes #1222
2018-09-29 11:48:49 +02:00
Julian Becker
0a09db9cc2 BSON: Extend binary_reader::get_number to be able to hanlde little endian input to get rid of binary_reader::get_number_little_endian 2018-09-29 11:33:01 +02:00
Niels Lohmann
95432c34f9 Merge pull request #1262 from knilch0r/patch-1
unit-testsuites.cpp: fix hangup if file not found
2018-09-29 10:58:10 +02:00
knilch
8c1387cfb3 unit-testsuites.cpp: fix hangup if file not found
If run from the wrong directory, std::ifstream f("test/data/big-list-of-naughty-strings/blns.json"); will not find the file and thus f.eof() will never return true.
Use canonical C++ file reading loop from https://gehrcke.de/2011/06/reading-files-in-c-using-ifstream-dealing-correctly-with-badbit-failbit-eofbit-and-perror/ instead.
2018-09-28 11:33:23 +02:00
Théo DELRIEU
521fe49fec Add basic_json::get_to function.
Takes an lvalue reference, and returns the same reference.

This allows non-default constructible types to be converted without
specializing adl_serializer.
This overload does not require CopyConstructible either.

Implements #1227
2018-09-28 11:25:23 +02:00
Niels Lohmann
680a4ab672 Merge pull request #1257 from henryiii/gcc48
GCC 48
2018-09-28 10:05:17 +02:00
Henry Fredrick Schreiner
7a37ba0c02 Adding 4.8 test to travis 2018-09-27 22:31:39 +02:00
Julian Becker
ef358ae695 BSON: Fixed hangup in case of incomplete bson input and improved test coverage 2018-09-25 20:34:25 +02:00
Chris Harris
99b7c7c8ef Patch nlohmann/json for GCC 4.8
See https://github.com/nlohmann/json/pull/212 for details
2018-09-25 18:10:20 +02:00
Julian Becker
bce4816275 BSON: Added test case for the different input/output_adapters 2018-09-24 23:35:19 +02:00
Julian Becker
763705c2a7 Fix: Add missing begin() and end() member functions to alt_string 2018-09-24 19:50:28 +02:00
Niels Lohmann
e184b6ecf2 Merge pull request #1252 from koponomarenko/fix-meson-build
Add version and license to meson.build
2018-09-22 14:49:03 +02:00
Niels Lohmann
88b055c2df Merge pull request #1249 from LEgregius/clang-3.4.2-crash-workaround
#1179 Reordered the code. It seems to stop clang 3.4.2 in RHEL 7 from crash…
2018-09-22 14:14:56 +02:00
Kostiantyn Ponomarenko
8799759b85 Add version and license to meson.build 2018-09-20 21:54:10 +03:00
Théo DELRIEU
4e52277b70 Fix issue #1237
* Make the conversion operator SFINAE correct.
* Workaround a GCC bug with some traits in type_traits.hpp

The first bullet-point implies that every `get`/`get_ptr` be SFINAE
correct as well.
2018-09-20 10:33:14 +02:00
Niels Lohmann
e4bc98d036 Merge pull request #1245 from chuckatkins/fix-target-namespace-backward-compatibility
Use a version check to provide backwards comatible CMake imported target names
2018-09-19 20:46:51 +02:00
David Guthrie
4d780b091b Reordered the code. It seems to stop clang 3.4.2 in RHEL 7 from crashing intermittently. 2018-09-18 16:38:59 -04:00
Chuck Atkins
3b1a5cafad Use a version check to provide backwards comatible imported target names. 2018-09-18 13:59:19 -04:00
Niels Lohmann
99939d6340 📝 added lgtm.com badge
See https://lgtm.com/projects/g/nlohmann/json
2018-09-18 19:27:52 +02:00
Niels Lohmann
4e2f35d4c2 👷 adding Xcode 10 worker
See https://blog.travis-ci.com/2018-09-13-xcode-10-is-now-available?utm_source=twitter&utm_medium=web&utm_campaign=xcode10_gm
2018-09-18 19:22:30 +02:00
Niels Lohmann
7fa3b8865c Merge pull request #1221 from rivertam/better-error-305
Better error 305
2018-09-18 12:49:07 +02:00
Ben Berman
8f07ab6392 Replace "key-style argument" with "string argument" 2018-09-17 15:36:38 -04:00
Julian Becker
df33a90774 BSON: Bugfix for non-empty arrays 2018-09-15 14:08:38 +02:00
Julian Becker
cf485c2907 BSON: Support for arrays 2018-09-15 13:54:08 +02:00
Julian Becker
120d1d77d4 BSON: test case for a more complex document 2018-09-15 13:41:05 +02:00
Julian Becker
5ce7d6bdd7 BSON: support objects with objects as members 2018-09-15 13:03:42 +02:00
Julian Becker
83b427ad67 BSON: unsigned integers 2018-09-15 12:20:30 +02:00
Julian Becker
c0d8921a67 BSON: support objects with int64 members 2018-09-15 12:00:53 +02:00
Julian Becker
7ee361f7ad BSON: support objects with int32 members 2018-09-15 11:54:17 +02:00
Julian Becker
c5ef023171 BSON: support objects with null members 2018-09-15 11:39:12 +02:00
Julian Becker
6c447de076 BSON: Support objects with string members 2018-09-15 11:33:24 +02:00
Julian Becker
0c0f2e44b5 BSON: support doubles 2018-09-15 10:32:03 +02:00
Julian Becker
9a0dddc5d2 BSON: Object with single boolean 2018-09-15 03:08:50 +02:00
Julian Becker
5f5836ce1c BSON: Support empty objects 2018-09-15 00:43:39 +02:00
Julian Becker
f06c8fd8e3 BSON: serialization of non-objects is not supported 2018-09-15 00:20:03 +02:00
Niels Lohmann
186c747a19 Merge pull request #1230 from mandreyel/lambda-unevaluated-context-fix
Move lambda out of unevaluated context
2018-09-10 20:52:11 +02:00
mandreyel
6b5334c167 Move lambda out of unevaluated context 2018-09-10 13:34:59 +02:00
Niels Lohmann
ebb3c03293 🎨 cleanup after #1228 2018-09-09 18:19:33 +02:00
Niels Lohmann
d3428b35c5 Merge pull request #1228 from theodelrieu/remove_static_asserts
Remove static asserts
2018-09-09 18:12:43 +02:00
Théo DELRIEU
aea648bb7a remove now-useless traits. check for is_basic_json where needed 2018-09-07 14:10:39 +02:00
Théo DELRIEU
4b4bbceebf make from_json SFINAE-correct 2018-09-07 14:10:37 +02:00
Théo DELRIEU
f7971f04a5 make to_json SFINAE-correct 2018-09-07 12:18:04 +02:00
Théo DELRIEU
f7c8a2145a refactor from/to_json(CompatibleArrayType) 2018-09-07 12:18:04 +02:00
Théo DELRIEU
628f76729e do not check for compatible_object_type in compatible_array_type 2018-09-07 12:18:03 +02:00
Théo DELRIEU
29f72966c3 refactor is_compatible_type, remove conjunction & co 2018-09-07 12:18:03 +02:00
Théo DELRIEU
77967e6548 refactor is_compatible_integer_type 2018-09-07 12:18:03 +02:00
Théo DELRIEU
13760857ff refactor is_compatible_array_type 2018-09-07 12:18:02 +02:00
Théo DELRIEU
924e95c6e8 refactor is_compatible_string_type 2018-09-07 12:18:02 +02:00
Théo DELRIEU
e84195ab7b refactor is_compatible_object_type 2018-09-07 12:18:02 +02:00
Théo DELRIEU
b59c3367c9 use detected instead of has_* traits 2018-09-07 12:17:59 +02:00
Théo DELRIEU
1ea8cd128c fix void_t for older compilers 2018-09-07 12:17:33 +02:00
Niels Lohmann
eb30ff0615 🚨 fixed a compiler warning #1224 2018-09-06 07:25:19 +02:00
Ben Berman
ad053ef09c Fix tests for improved error 305(hopefully) 2018-08-30 13:21:55 -04:00
Ben Berman
bbdfe7dea6 Improve error messages for error 305
Addresses #1220
2018-08-30 12:35:51 -04:00
Niels Lohmann
d713727f22 Merge pull request #1202 from dennisfischer/develop
Export package to allow builds without installing
2018-08-25 10:56:30 +02:00
Niels Lohmann
04597c3a66 Merge pull request #1214 from devsisters/fix-1213
Fix #1213
2018-08-24 17:54:28 +02:00
Hyeon Kim
aada309f61 Fix #1213 2018-08-24 21:55:13 +09:00
Niels Lohmann
359f98d140 Merge branch 'release/3.2.0' into develop 2018-08-20 19:36:25 +02:00
Dennis Fischer
dfe607c6ff Export package to allow builds without installing 2018-08-20 09:23:12 +02:00
Niels Lohmann
9f3857ef6f 🔖 set version to 3.2.0 2018-08-18 18:46:15 +02:00
Niels Lohmann
7608a64e1e 🔨 fixed amalgamation 2018-08-18 18:14:12 +02:00
Niels Lohmann
a7b02bdce0 🔖 preparing 3.2.0 release 2018-08-18 17:48:49 +02:00
Niels Lohmann
c6a482b16c 📝 added example for sax_parse 2018-08-18 15:42:18 +02:00
Niels Lohmann
5ad52f4167 ⬆️ Catch 1.12.0 2018-08-18 12:02:12 +02:00
Niels Lohmann
3811daa8a3 📝 release preparation 2018-08-18 12:00:14 +02:00
Niels Lohmann
6899fa304c Merge branch 'develop' of https://github.com/nlohmann/json into develop 2018-08-18 08:15:06 +02:00
Niels Lohmann
57faaf42ca 🚨 fixed a compiler warning 2018-08-18 08:15:03 +02:00
Niels Lohmann
f78ac4fbd3 Merge pull request #1200 from thyu/develop
Fix -Wno-sometimes-uninitialized by initializing "result" in parse_sax
2018-08-18 08:14:04 +02:00
Tsz-Ho Yu
3004a73951 Fix -Wno-sometimes-uninitialized by initializing "result" in parse_sax
The function parse_sax() returns sometimes-uninitialized warnings in
some compilers. This commit fixes that.
2018-08-18 01:12:19 +01:00
Niels Lohmann
e33b31e6aa 🐛 fixed callback-related issue (https://github.com/nlohmann/json/issues/971#issuecomment-413678360) 2018-08-17 23:09:45 +02:00
Niels Lohmann
b5c54b41fd 📝 overworked documentation 2018-08-16 21:53:47 +02:00
Niels Lohmann
07494e06d7 🚨 fixed some compiler warnings 2018-08-16 18:20:30 +02:00
Niels Lohmann
d5b21b051c Merge pull request #1153 from theodelrieu/refactor/no_virtual_sax
Refactor/no virtual sax
2018-08-16 17:47:55 +02:00
Théo DELRIEU
0cc3db4f15 add static_asserts on SAX interface 2018-08-16 11:59:57 +02:00
Théo DELRIEU
38f8a51a8f use abstract sax class in parser tests 2018-08-16 11:59:49 +02:00
Théo DELRIEU
9bbb133094 remove no_limit constant and default values 2018-08-16 11:59:05 +02:00
Théo DELRIEU
442886d040 use templates in the sax interface instead of virtuals 2018-08-16 11:58:52 +02:00
Théo DELRIEU
f6febbe359 split meta.hpp, add detected_t (used to define concepts) 2018-08-16 11:58:42 +02:00
Niels Lohmann
3ac2d81a95 🔨 fixed a MinGW error #1193 2018-08-14 22:13:56 +02:00
Niels Lohmann
be2065dce9 🚨 fixing a MinGW warning #1192 2018-08-14 22:11:47 +02:00
Niels Lohmann
fed70f6bff 🎨 reindented code 2018-08-14 22:11:08 +02:00
Niels Lohmann
0e748f2f8c Merge pull request #1187 from devsisters/json-internal-catch
[RFC] Introduce a new macro function: JSON_INTERNAL_CATCH
2018-08-14 21:56:29 +02:00
Niels Lohmann
861ee400cc Merge pull request #1176 from grembo/develop
Fix unit tests that were silently skipped or crashed (depending on the compiler)
2018-08-14 21:48:49 +02:00
Niels Lohmann
3ce4325350 📝 updated documentation of used compilers 2018-08-01 22:31:51 +02:00
Niels Lohmann
ba4a19d4af 👷 added more CI workers 2018-08-01 20:59:58 +02:00
Niels Lohmann
043eff5ba8 👷 added more CI workers 2018-07-31 21:18:33 +02:00
Michael Gmelin
05b27e83b7 Exclude bytewise comparison in certain tests.
These tests never worked - they weren't run before
d5aaeb4.

Note that these tests would fail because of this library
ordering dictionary keys (which is legal). So changing the
input files (or modifying stored cbor/msgpack/ubjson files)
would make the tests work and they could get removed from
"exclude_packaged".

Also move parsing of files in these unit tests to within
the inner sections, so that they're only parsed
number_of_files * number_of_sections instead of
number_of_files * number_of_files * number_of_sections
(so, instead of close to 100k parses about 700).
2018-07-29 14:52:52 +02:00
Michael Gmelin
d5aaeb4cce Make section names unique in loops, as catch doesn't support duplicate
sections, see also https://github.com/catchorg/Catch2/issues/816#issuecomment-278268122

As a result, when built with gcc, loop iterations were skipped. When
built with clang, the test aborted with an assertion in catch.hpp
line 6222.

This also addresses the issues discussed here:
https://github.com/nlohmann/json/issues/1032#issuecomment-378707696

and here:
https://github.com/catchorg/Catch2/issues/1241

Please note that this introduces new problems, as some of
the unit tests fail now - the library stores keys in
lexographical order, while the cbor/msgpack/ubjson examples
store them in original order.
2018-07-29 10:44:36 +02:00
Niels Lohmann
3760a38b7e 🏁 implicit conversion is not allowed with MSVC 2018-07-21 11:47:05 +02:00
Niels Lohmann
5b14411669 🏁 trying to fix C2440 error
Error in AppVeyor:

unit-conversions.cpp(441): error C2440: 'initializing': cannot convert from 'nlohmann::json' to 'std::nullptr_t'

(https://ci.appveyor.com/project/nlohmann/json/build/2838/job/wo7im01sq6tvhe9m)
2018-07-21 10:59:00 +02:00
Niels Lohmann
347e77bdc1 🚑 fix for #1169 2018-07-21 10:31:55 +02:00
Niels Lohmann
04372a8c56 🏁 fix for #1168 2018-07-19 17:31:50 +02:00
Hyeon Kim
d0e60de433 Add new JSON_INTERNAL_CATCH macro function 2018-07-19 15:43:41 +09:00
Niels Lohmann
7bfc406ded 📝 added note about CocoaPods #1148 2018-07-05 21:18:46 +02:00
Niels Lohmann
d456a2d777 Merge pull request #1151 from sonulohani/bigObjFix
Fixed compiler error in VS 2015 for debug mode
2018-06-29 09:03:43 +02:00
Sonu Lohani
b8ad3388ec Fixed compiler error in VS 2015 for debug mode
https://github.com/nlohmann/json/issues/1114
2018-06-29 09:34:41 +05:30
Niels Lohmann
39dd775e38 🔨 cleanup after #1134 2018-06-28 21:32:32 +02:00
Niels Lohmann
86a96b059d Merge pull request #1134 from Daniel599/feature/items_iterator
fixed compile error for #1045
2018-06-28 21:21:17 +02:00
Niels Lohmann
396a914f9e 🔨 added macro to disable compiler check #1128 2018-06-26 22:47:40 +02:00
Niels Lohmann
bab5826504 Merge pull request #1144 from jrakow/cppreference-link-fix
Fix links to cppreference named requirements (formerly concepts)
2018-06-26 07:58:45 +02:00
Niels Lohmann
515cfc2d89 Merge pull request #1142 from jrakow/develop
meson: fix include directory
2018-06-24 23:33:30 +02:00
Julius Rakow
963d06a13c 📝 fix links to cppreference named requirements
"Concepts" have been renamed to "named requirements".
This is because P0898R3 Standard Library Concepts has been merged into
C++20.
Cppreference have moved their links accordingly.
2018-06-24 22:36:19 +02:00
Julius Rakow
9f00db48d9 📝 link to cppreference via HTTPS 2018-06-24 22:34:47 +02:00
Julius Rakow
ec2ebd5ec9 meson: add multiple headers target 2018-06-24 18:07:30 +02:00
Julius Rakow
0bb36bb140 meson: fix include directory 2018-06-24 18:07:30 +02:00
Niels Lohmann
62457729e8 📝 mentioned MinGW in README 2018-06-24 18:03:59 +02:00
Niels Lohmann
09c0df4a21 👷 choosing correct image 2018-06-24 17:40:16 +02:00
Niels Lohmann
1bbc4a0859 👷 using Ninja to speed up build 2018-06-24 17:10:13 +02:00
Niels Lohmann
d8fe13fc83 🔨 fixed escaping for MinGW 2018-06-24 16:57:53 +02:00
Niels Lohmann
e59b930927 👷 trying a more recent compiler 2018-06-24 16:40:47 +02:00
Niels Lohmann
937d68e2e5 👷 forgot old PATH 2018-06-24 16:37:02 +02:00
Niels Lohmann
989ad9b759 👷 using help from https://stackoverflow.com/a/48509334/266378 2018-06-24 16:35:16 +02:00
Niels Lohmann
067e288289 👷 set build type 2018-06-24 16:29:03 +02:00
Niels Lohmann
7bbc06b487 👷 forgot quotes 2018-06-24 16:18:44 +02:00
Niels Lohmann
441e5d87e6 👷 experimenting with AppVeyor and MinGW 2018-06-24 16:17:06 +02:00
Niels Lohmann
7fa4ddf93e 💄 fixed indentation 2018-06-23 17:27:40 +02:00
Niels Lohmann
bf348ca8a4 Merge pull request #1028 from gracicot/develop
Added support for string_view in C++17
2018-06-23 17:10:04 +02:00
Niels Lohmann
ed6a0686df 🔨 small refactoring to improve branch coverage
The branch coverage reported by lcov is weird. The code before and after has the same Godbolt assembler, but the code with the lambda has a better branch coverage.
2018-06-23 17:05:04 +02:00
Niels Lohmann
c8bfdfd961 👷 tryping different platforms for AppVeyor 2018-06-23 11:12:32 +02:00
Niels Lohmann
c02de445bf 🚨 fixed more compiler warnings 2018-06-23 11:00:42 +02:00
Niels Lohmann
66dd1a846d 🚨 fixed more compiler warnings 2018-06-23 10:47:55 +02:00
Niels Lohmann
850922269d 🚨 removed compiler warnings 2018-06-23 10:28:04 +02:00
Niels Lohmann
0460b90977 📝 fix for #1052 #1139 2018-06-22 22:35:48 +02:00
Niels Lohmann
85f35a1d59 📝 documentation fix 2018-06-22 22:34:42 +02:00
Niels Lohmann
e7c1638d11 💄 cleanup 2018-06-18 22:03:46 +02:00
Niels Lohmann
1c81e9f5ae Merge pull request #1130 from agrianius/develop
test (non)equality for alt_string implementation
2018-06-18 22:01:53 +02:00
Niels Lohmann
d505ed7b31 Merge pull request #1138 from theodelrieu/feature/unordered_map_conversion
Feature/unordered map conversion
2018-06-18 21:59:46 +02:00
Théo DELRIEU
2c920a1032 run make amalgamate 2018-06-18 15:14:10 +02:00
Théo DELRIEU
2b37d7ed86 from_json: add overload for std::unordered_map
Fixes #1133
2018-06-18 15:14:10 +02:00
Théo DELRIEU
299469cfd5 from_json: add missing template arguments for std::map 2018-06-18 10:52:11 +02:00
Danielc
1566ad4053 fixed compile error for #1045; to_json for iternation_proxy_internal was needed 2018-06-16 12:01:49 +03:00
Vitaliy
f574d7e084 simplify templates for operators, add more checks 2018-06-14 15:07:06 +03:00
Vitaliy
cd28d872e7 forward declarations to make new compilers happy 2018-06-11 20:50:39 +03:00
Vitaliy
3d3055909c define global operator< for const char* and alt_string 2018-06-11 19:09:57 +03:00
Vitaliy
4feb8211ca test (non)equality for alt_string implementation 2018-06-11 18:03:46 +03:00
Guillaume Racicot
14e6278c2f Merge branch 'develop' of github.com:gracicot/json into develop 2018-06-04 11:18:25 -04:00
Guillaume Racicot
7acd90b651 Fixed check for compatible string type 2018-06-04 11:18:19 -04:00
Guillaume Racicot
5676a2a076 Aligned template declaration 2018-06-03 23:51:07 -04:00
Guillaume Racicot
e0e7fa39e7 Re-added external_constructor with string compatible types 2018-06-03 23:49:13 -04:00
Guillaume Racicot
4778c02ab5 Set MSVC version from 1514 and older 2018-06-01 14:42:25 -04:00
Guillaume Racicot
714c592680 Disabled implicit conversion to string_view on MSVC 15.13 and older 2018-06-01 14:22:57 -04:00
Niels Lohmann
e830bc502f Merge pull request #1117 from TinyTinni/develop
remove stringstream dependency
2018-06-01 08:05:45 +02:00
Matthias Möller
ecadcdb593 added char cast
should fix the GCC unittest
2018-05-31 16:36:16 +02:00
Matthias Möller
48656a49f5 typo 2018-05-31 15:32:21 +02:00
Matthias Möller
64acb42aa7 remove stringstream dependency 2018-05-31 13:45:58 +02:00
Niels Lohmann
8efbf8d7bb 📝 documentation to avoid future issues like #1108 2018-05-28 18:14:44 +02:00
Niels Lohmann
e5a67fc3f8 Merge branch 'develop' of https://github.com/nlohmann/json into develop 2018-05-28 17:57:46 +02:00
Niels Lohmann
a49644ab74 🚑 adjusted Fuzzer to new parser
out_of_range exceptions where unexpected before - the parser used to crash in these situations...
2018-05-28 17:57:22 +02:00
Niels Lohmann
0efaf891e5 Merge pull request #1089 from theodelrieu/feature/map_conversion
Provide a from_json overload for std::map
2018-05-28 14:53:23 +02:00
Théo DELRIEU
c5e63fd684 Provide a from_json overload for std::map
This overload is chosen only when BasicJsonType::string_t
is not constructible from std::map::key_type.

Currently, converting a map to json treats it as an array of pairs.

fixes #1079
2018-05-28 11:06:24 +02:00
Niels Lohmann
db03d09312 Merge branch 'feature/key_ref' into develop (fixes #1098) 2018-05-27 22:26:00 +02:00
Niels Lohmann
cf9299d222 Merge branch 'feature/sax2' into develop #971 2018-05-27 18:12:59 +02:00
Niels Lohmann
3cdc4d784b 📝 added documentation 2018-05-27 18:07:53 +02:00
Niels Lohmann
adf09726b0 Merge branch 'develop' into feature/sax2 2018-05-27 14:26:13 +02:00
Niels Lohmann
481ace65c4 🔨 only calculate array index string when needed #1098 2018-05-27 12:04:22 +02:00
Niels Lohmann
1c6b332dcd 👌 mitigating cppcheck bug #1101 2018-05-26 14:10:13 +02:00
Niels Lohmann
90eb0a91e0 keys are now returned as const reference #1098 2018-05-26 13:26:40 +02:00
Niels Lohmann
1f84cc2c88 adjusted test cases 2018-05-17 16:50:37 +02:00
Niels Lohmann
717301d1bc Merge branch 'testsuite' into feature/sax2 2018-05-17 16:36:43 +02:00
Niels Lohmann
4639bb2c8f added more tests from recent nst's JSONTestSuite 2018-05-17 10:10:01 +02:00
Niels Lohmann
e94862a649 🚑 fixed error in callback logic 2018-05-06 19:00:49 +02:00
Niels Lohmann
ae213721b1 🔨 removed unget function for wstring parsers 2018-05-06 14:05:29 +02:00
Niels Lohmann
5ff2abb90d Merge branch 'develop' into feature/sax2 2018-05-06 13:29:23 +02:00
Niels Lohmann
567fe9b7a0 Merge pull request #1078 from martin-mfg/patch-1
fix typo in README
2018-05-04 17:04:35 +02:00
martin-mfg
377e956655 fix typo in readme
The README says:
> "The library itself contains of a single header file ..."

I guess "consists of a" is the wording that was intended here. Alternatively, "contains a" might also be what was intended. Either way, I think both versions work equally well and thus choose the one that I believe was intended.
2018-05-03 22:42:52 +02:00
Niels Lohmann
5da596385b Update issue templates 2018-05-03 18:35:56 +02:00
Niels Lohmann
7bbe7bb98f 🔥 removed old issue template 2018-05-03 18:35:21 +02:00
Niels Lohmann
14f01e1981 🔧 update issue templates 2018-05-03 18:32:53 +02:00
Niels Lohmann
86b0732a10 📝 added public key used for commits and releases 2018-05-03 18:11:42 +02:00
Niels Lohmann
ed69e50ad2 📄 added SPDX-License-Identifier 2018-05-03 17:41:45 +02:00
Niels Lohmann
5bc4ff9da3 Merge branch 'feature/wstring' into develop 2018-04-29 17:29:57 +02:00
Niels Lohmann
fa3e42f826 Merge branch 'develop' into feature/wstring 2018-04-29 13:16:12 +02:00
Niels Lohmann
b5d1755dfb 🔥 removed commented-out test cases #1060 2018-04-22 15:41:42 +02:00
Niels Lohmann
0ab8fab338 Merge pull request #1058 from dns13/patch-1
Fix typo
2018-04-17 23:26:00 +05:30
Jan Schöppach
65b4d8251b Fix typo in single_include, too 2018-04-17 13:02:36 +02:00
Jan Schöppach
53fb230098 Fix typo 2018-04-17 12:08:44 +02:00
Niels Lohmann
46ec2fddf8 📝 updated THANKS list 2018-04-10 18:13:37 +02:00
Niels Lohmann
b8bfd1140d Merge pull request #1048 from chuckatkins/misc-cmake-packaging-enhancements
Misc cmake packaging enhancements
2018-04-10 17:57:21 +02:00
Chuck Atkins
33a2154f8d Enable target namespaces and build dir project config
CMake convention is to use a project namespace, i.e. Foo::, for imported
targets.  When multiple targets are imported from a project, this looks
like Foo::Bar1 Foo::Bar2, etc.  This adds the nlohmann_json:: namespace to
the exported target names.

This also allows the generated project config files to be used from the
build directory instead of just the install directory.
2018-04-10 09:08:38 -04:00
Niels Lohmann
29362c6ace Merge pull request #1047 from jammehcow/patch-1
Fixed incorrect LLVM version number in README
2018-04-10 08:39:58 +02:00
Niels Lohmann
c02a3155d4 👷 added Xcode 9.3 builder
See https://blog.travis-ci.com/2018-04-09-say-bonjour-to-xcode-93-and-macos-high-sierra.
2018-04-10 08:39:28 +02:00
Niels Lohmann
8d8f890771 💩 first try on #1045 2018-04-10 08:29:07 +02:00
James Upjohn
7f20e9ddc7 Fixed incorrect version number in README
clang-900.0.39.2 is from LLVM 9.0.0, not 8.1.0
2018-04-10 17:16:44 +12:00
Chuck Atkins
031b88d315 Make the CMake install dir user-configurable 2018-04-09 11:31:25 -04:00
Guillaume Racicot
aaee18ce90 Added test for string conversion with string_view 2018-04-09 11:15:33 -04:00
Niels Lohmann
7c503c64b7 Merge pull request #1043 from coryan/patch-1
Fix trivial typo in comment.
2018-04-09 08:19:56 +02:00
Carlos O'Ryan
4286b16b71 Fix trivial typo in comment.
Not really important, but since I saw it.
2018-04-08 15:46:25 -04:00
Niels Lohmann
cf91b4f2bb Merge branch 'develop' into feature/wstring 2018-04-08 11:36:58 +02:00
Niels Lohmann
f924df1835 Merge branch 'develop' into feature/sax2 2018-04-08 11:36:44 +02:00
Niels Lohmann
acf10d9af7 Merge pull request #1041 from ax3l/topic-spack
Package Manager: Spack
2018-04-08 11:32:35 +02:00
Niels Lohmann
e1ea8369ad Merge branch 'develop' into feature/sax2 2018-04-08 09:31:59 +02:00
Niels Lohmann
40f279c59d Merge branch 'feature/issue1021' into develop 2018-04-08 09:28:37 +02:00
Niels Lohmann
18a0271a95 Merge branch 'develop' into feature/issue1021 2018-04-08 09:21:43 +02:00
Axel Huebl
1ae9896387 Package Manager: Spack
I contributed a package to the Spack package manager.

Spack is a flexible package manager that supports multiple versions,
configurations, platforms, and compilers. It is popular in
high-performance computing.
2018-04-08 01:12:49 +02:00
Niels Lohmann
83b143382e Merge pull request #1040 from ax3l/topic-debugViewMSVCcmakeMin
CMake: 3.8+ is Sufficient
2018-04-07 15:14:59 +02:00
Axel Huebl
e439a1a9a7 CMake: 3.8+ is Sufficient
The current CMake scripts depend on CMake 3.8+.
This allows us to remove previous work-arounds.
2018-04-07 13:15:44 +02:00
Niels Lohmann
495436a5d5 Merge pull request #1026 from ktonon/develop
Added public target_compile_features for auto and constexpr
2018-04-03 17:34:42 +02:00
Kevin Tonon
a35d414c39 Update CMake to latest on Travis 2018-04-03 08:28:07 -04:00
Niels Lohmann
08a7233d1b 🚑 fixed commit 1e08654 2018-04-02 22:38:44 +02:00
Niels Lohmann
1e08654f99 🔨 cleanup 2018-04-02 22:25:17 +02:00
Niels Lohmann
aa89c5e048 🔨 removing unget_character() function from input adapters #834 2018-04-02 21:10:48 +02:00
Niels Lohmann
6678eb2b4a improved test coverage #1031 2018-04-02 15:38:49 +02:00
Niels Lohmann
16c5bfeaad 👌 fixed compiler warnings #1031 2018-04-02 13:01:56 +02:00
Niels Lohmann
727dd4664b 🔨 trying to make tests run with MSVC #1031 2018-04-02 12:27:07 +02:00
Niels Lohmann
ab89ae4e50 🔨 trying to make tests run with MSVC #1031 2018-04-02 11:34:36 +02:00
Niels Lohmann
eb06d0531a 🚧 added input adapter for wide strings #1031 2018-04-01 19:12:36 +02:00
Niels Lohmann
ba6edd5634 🔨 cleanup 2018-03-30 00:38:18 +02:00
Niels Lohmann
850671b9f1 🔨 using a vector<bool> for the parser hierarchy 2018-03-29 18:45:43 +02:00
Niels Lohmann
4efa8cdb4c 💚 fixed Valgrind options #1030 2018-03-29 17:19:21 +02:00
Niels Lohmann
830c93fd09 📝 fixed example for operator> #1029 2018-03-29 17:07:55 +02:00
Guillaume Racicot
c78dbc366c Added test for conversion to string_view 2018-03-29 01:03:57 -04:00
Guillaume Racicot
53d8d57921 Amalgamate single include 2018-03-29 01:03:36 -04:00
Niels Lohmann
5f723bbec6 🔨 realized callback parser wirh SAX interface #971 2018-03-28 23:39:39 +02:00
Niels Lohmann
896a9db461 🔨 improved code #1021 2018-03-28 19:37:21 +02:00
Kevin Tonon
73cc5089e3 Using target_compile_features to specify C++ 11 standard 2018-03-28 13:11:49 -04:00
Niels Lohmann
a9baab76c2 🚑 fix for #1021 2018-03-28 18:20:55 +02:00
Niels Lohmann
4f6b2b6429 🔨 changed SAX interface 2018-03-21 20:12:06 +01:00
Niels Lohmann
2537677e4c improved test coverage 2018-03-20 23:40:01 +01:00
Niels Lohmann
9e1abb4842 improved coverage 2018-03-20 22:39:08 +01:00
Niels Lohmann
1e38ffc014 more tests 2018-03-20 20:04:11 +01:00
Niels Lohmann
25f56ff207 📝 updated documentation 2018-03-20 19:22:18 +01:00
Niels Lohmann
99ecca55c4 improved test coverage 2018-03-20 18:49:10 +01:00
Niels Lohmann
9e07e9b4ec implemented non-throwing binary reader 2018-03-19 22:48:13 +01:00
Niels Lohmann
a271ee5f16 ♻️ proper use of SAX parser for binary formats 2018-03-18 23:00:45 +01:00
Niels Lohmann
943d641054 🔨 some refactoring 2018-03-18 16:07:21 +01:00
Niels Lohmann
22929fe189 🚧 started a SAX/DOM/callback parser 2018-03-18 15:13:53 +01:00
Niels Lohmann
375b05a17d 🔨 cleanup 2018-03-17 23:31:18 +01:00
Niels Lohmann
606a25195f improved test coverage 2018-03-17 19:15:59 +01:00
Niels Lohmann
c87ffad45c ♻️ implemented a non-recursive parser 2018-03-17 14:46:50 +01:00
Guillaume Racicot
2a5506ed98 Amalgamated headers 2018-03-16 13:16:10 -04:00
Guillaume Racicot
8165707990 basic_json now supports getting many type of strings 2018-03-15 15:35:00 -04:00
Niels Lohmann
27cf05af8d Merge branch 'develop' into feature/sax2 2018-03-14 22:02:19 +01:00
Niels Lohmann
d2dd27dc3b Merge branch 'release/3.1.2' into develop 2018-03-14 21:48:03 +01:00
Niels Lohmann
a52e8355b8 oops 2018-03-14 17:32:48 +01:00
Niels Lohmann
21410d50af 🏁 moved /Wall to CMake 2018-03-14 17:21:31 +01:00
Niels Lohmann
829ed74d66 🏁 experimenting with /Wall 2018-03-14 07:38:22 +01:00
Niels Lohmann
1262d474eb 🏁 fixed an MSVC warning 2018-03-14 07:32:28 +01:00
Niels Lohmann
282bafae4f 🔨 fixed compilation error 2018-03-14 07:18:42 +01:00
Niels Lohmann
abac6a0e84 Merge branch 'develop' into feature/sax2 2018-03-13 23:58:17 +01:00
Niels Lohmann
3d4f6a2940 🔨 cleaner exception interface 2018-03-11 22:47:25 +01:00
Niels Lohmann
ad47b0fbde ♻️ refactored binary readers to use a SAX parser 2018-03-11 18:47:38 +01:00
Niels Lohmann
149d2fd09c 💚 improved test coverage 2018-03-10 11:24:00 +01:00
Niels Lohmann
6399cd3039 Merge branch 'develop' into feature/sax2 2018-03-10 11:07:36 +01:00
Niels Lohmann
35e43df625 Merge branch 'develop' into feature/sax2 2018-03-09 21:56:30 +01:00
Niels Lohmann
7c1a788893 Merge branch 'develop' into feature/sax2 2018-03-08 07:39:37 +01:00
Niels Lohmann
8b379948d0 🔥 replaced acceptor with SAX parser 2018-03-07 22:40:48 +01:00
Niels Lohmann
303a0c5843 Merge branch 'develop' into feature/sax2 2018-03-07 22:26:01 +01:00
Niels Lohmann
5beab80553 🔨 using the SAX-DOM parser 2018-03-06 18:17:07 +01:00
Niels Lohmann
faf2546a15 🔨 simplified SAX-DOM parser 2018-03-06 07:19:05 +01:00
Niels Lohmann
5b9d03cfdb 🔨 added SAX-DOM-Parser 2018-03-05 21:06:00 +01:00
Niels Lohmann
9d27429527 🔨 added error messages to SAX interface 2018-03-05 16:46:35 +01:00
Niels Lohmann
86991d5204 Merge branch 'develop' into feature/sax2 2018-03-05 16:16:43 +01:00
Niels Lohmann
3ff9455332 🔨 added a SAX-DOM-Parser 2018-02-26 23:39:23 +01:00
Niels Lohmann
21352c4d8e ♻️ refactored SAX parser 2018-02-26 20:08:12 +01:00
Niels Lohmann
981e226ca2 Merge branch 'develop' into feature/sax2 2018-02-26 20:07:52 +01:00
Niels Lohmann
8d6b3d44d6 👌 fixed some compiler warnings 2018-02-25 18:35:16 +01:00
Niels Lohmann
8c7f46f7d0 🔨 removed a logic error and improved coverage 2018-02-25 17:10:30 +01:00
Niels Lohmann
922f7a3d0e added more tests for SAX parsing 2018-02-25 14:21:30 +01:00
Niels Lohmann
ac230e8b4b 🔨 fixed test cases to be more robust 2018-02-25 10:44:47 +01:00
Niels Lohmann
374ebacc51 added a SAX parser #971 2018-02-24 18:04:07 +01:00
610 changed files with 1032877 additions and 10219 deletions

23
.clang-tidy Normal file
View File

@@ -0,0 +1,23 @@
Checks: '-*,
bugprone-*,
cert-*,
clang-analyzer-*,
google-*,
-google-runtime-references,
hicpp-*,
-hicpp-no-array-decay,
-hicpp-uppercase-literal-suffix,
misc-*,
-misc-non-private-member-variables-in-classes,
llvm-*,
-llvm-header-guard,
modernize-*,
performance-*,
portability-*,
readability-*,
-readability-magic-numbers,
-readability-uppercase-literal-suffix'
CheckOptions:
- key: hicpp-special-member-functions.AllowSoleDefaultDtor
value: 1

View File

@@ -54,7 +54,7 @@ To make changes, you need to edit the following files:
## Please don't
- The C++11 support varies between different **compilers** and versions. Please note the [list of supported compilers](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers). Some compilers like GCC 4.8 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. Please refrain from proposing changes that work around these compiler's limitations with `#ifdef`s or other means.
- The C++11 support varies between different **compilers** and versions. Please note the [list of supported compilers](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers). Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. Please refrain from proposing changes that work around these compiler's limitations with `#ifdef`s or other means.
- Specifically, I am aware of compilation problems with **Microsoft Visual Studio** (there even is an [issue label](https://github.com/nlohmann/json/issues?utf8=✓&q=label%3A%22visual+studio%22+) for these kind of bugs). I understand that even in 2016, complete C++11 support isn't there yet. But please also understand that I do not want to drop features or uglify the code just to make Microsoft's sub-standard compiler happy. The past has shown that there are ways to express the functionality such that the code compiles with the most recent MSVC - unfortunately, this is not the main objective of the project.
- Please refrain from proposing changes that would **break [JSON](http://json.org) conformance**. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension.
- We shall not extend the library to **support comments**. There is quite some [controversy](https://www.reddit.com/r/programming/comments/4v6chu/why_json_doesnt_support_comments_douglas_crockford/) around this topic, and there were quite some [issues](https://github.com/nlohmann/json/issues/376) on this. We believe that JSON is fine without comments.

View File

@@ -1,22 +1,19 @@
**Bug Report**
- What is the issue you have?
- Please describe the steps to reproduce the issue. Can you provide a small but working code example?
- What is the expected behavior?
- And what is the actual behavior instead?
- Which compiler and operating system are you using? Is it a [supported compiler](https://github.com/nlohmann/json#supported-compilers)?
- Did you use a released version of the library or the version from the `develop` branch?
- If you experience a compilation error: can you [compile and run the unit tests](https://github.com/nlohmann/json#execute-unit-tests)?
**Feature Request**
- Describe the feature in as much detail as possible.
- Include sample usage where appropriate.
---
name: Bug report
about: Create a report to help us improve
---
- What is the issue you have?
- Please describe the steps to reproduce the issue. Can you provide a small but working code example?
- What is the expected behavior?
- And what is the actual behavior instead?
- Which compiler and operating system are you using? Is it a [supported compiler](https://github.com/nlohmann/json#supported-compilers)?
- Did you use a released version of the library or the version from the `develop` branch?
- If you experience a compilation error: can you [compile and run the unit tests](https://github.com/nlohmann/json#execute-unit-tests)?

View File

@@ -0,0 +1,9 @@
---
name: Feature request
about: Suggest an idea for this project
---
- Describe the feature in as much detail as possible.
- Include sample usage where appropriate.

View File

@@ -13,7 +13,7 @@ Read the [Contribution Guidelines](https://github.com/nlohmann/json/blob/develop
## Please don't
- The C++11 support varies between different **compilers** and versions. Please note the [list of supported compilers](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers). Some compilers like GCC 4.8 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. Please refrain from proposing changes that work around these compiler's limitations with `#ifdef`s or other means.
- The C++11 support varies between different **compilers** and versions. Please note the [list of supported compilers](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers). Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. Please refrain from proposing changes that work around these compiler's limitations with `#ifdef`s or other means.
- Specifically, I am aware of compilation problems with **Microsoft Visual Studio** (there even is an [issue label](https://github.com/nlohmann/json/issues?utf8=✓&q=label%3A%22visual+studio%22+) for these kind of bugs). I understand that even in 2016, complete C++11 support isn't there yet. But please also understand that I do not want to drop features or uglify the code just to make Microsoft's sub-standard compiler happy. The past has shown that there are ways to express the functionality such that the code compiles with the most recent MSVC - unfortunately, this is not the main objective of the project.
- Please refrain from proposing changes that would **break [JSON](http://json.org) conformance**. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension.
- Please do not open pull requests that address **multiple issues**.

1
.gitignore vendored
View File

@@ -22,3 +22,4 @@ benchmarks/files/numbers/*.json
cmake-build-debug
test/test-*
/.vs

View File

@@ -128,21 +128,6 @@ matrix:
# OSX / Clang
- os: osx
osx_image: xcode6.4
- os: osx
osx_image: xcode7.3
- os: osx
osx_image: xcode8
- os: osx
osx_image: xcode8.1
- os: osx
osx_image: xcode8.2
- os: osx
osx_image: xcode8.3
@@ -155,11 +140,31 @@ matrix:
- os: osx
osx_image: xcode9.2
- os: osx
osx_image: xcode9.3
- os: osx
osx_image: xcode9.4
- os: osx
osx_image: xcode10
- os: osx
osx_image: xcode10.1
# Linux / GCC
- os: linux
compiler: gcc
env: COMPILER=g++-4.9
env: compiler=g++-4.8
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8', 'ninja-build']
- os: linux
compiler: gcc
env: compiler=g++-4.9
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
@@ -189,15 +194,23 @@ matrix:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-7', 'ninja-build']
- os: linux
compiler: gcc
env: COMPILER=g++-8
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-8', 'ninja-build']
- os: linux
compiler: gcc
env:
- COMPILER=g++-7
- COMPILER=g++-8
- CXXFLAGS=-std=c++17
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-7', 'ninja-build']
packages: ['g++-8', 'ninja-build']
# Linux / Clang
@@ -257,15 +270,31 @@ matrix:
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-5.0']
packages: ['g++-6', 'clang-5.0', 'ninja-build']
- os: linux
compiler: clang
env: COMPILER=clang++-6.0
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-6.0']
packages: ['g++-6', 'clang-6.0', 'ninja-build']
- os: linux
compiler: clang
env: COMPILER=clang++-7
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7']
packages: ['g++-6', 'clang-7', 'ninja-build']
- os: linux
compiler: clang
env:
- COMPILER=clang++-5.0
- COMPILER=clang++-7
- CXXFLAGS=-std=c++1z
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-5.0']
packages: ['g++-6', 'clang-5.0', 'ninja-build']
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7']
packages: ['g++-6', 'clang-7', 'ninja-build']
################
# build script #
@@ -277,6 +306,7 @@ script:
if [[ (-x $(which brew)) ]]; then
brew update
brew install cmake ninja
brew upgrade cmake
cmake --version
fi

View File

@@ -1,10 +1,10 @@
cmake_minimum_required(VERSION 3.0.0)
cmake_minimum_required(VERSION 3.1)
##
## PROJECT
## name and version
##
project(nlohmann_json VERSION 3.1.2 LANGUAGES CXX)
project(nlohmann_json VERSION 3.6.0 LANGUAGES CXX)
##
## INCLUDE
@@ -16,19 +16,22 @@ include(ExternalProject)
## OPTIONS
##
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ON)
option(JSON_Install "Install CMake targets during install step." ON)
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF)
##
## CONFIGURATION
##
set(NLOHMANN_JSON_TARGET_NAME ${PROJECT_NAME})
set(NLOHMANN_JSON_CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
set(NLOHMANN_JSON_CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}"
CACHE INTERNAL "")
set(NLOHMANN_JSON_INCLUDE_INSTALL_DIR "include")
set(NLOHMANN_JSON_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
set(NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE "cmake/config.cmake.in")
set(NLOHMANN_JSON_CMAKE_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/cmake_config")
set(NLOHMANN_JSON_CMAKE_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}")
set(NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE "${NLOHMANN_JSON_CMAKE_CONFIG_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE "${NLOHMANN_JSON_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Config.cmake")
set(NLOHMANN_JSON_CMAKE_PROJECT_TARGETS_FILE "${NLOHMANN_JSON_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Targets.cmake")
if (JSON_MultipleHeaders)
set(NLOHMANN_JSON_INCLUDE_BUILD_DIR "${PROJECT_SOURCE_DIR}/include/")
@@ -43,6 +46,12 @@ endif()
## create target and add include path
##
add_library(${NLOHMANN_JSON_TARGET_NAME} INTERFACE)
add_library(${PROJECT_NAME}::${NLOHMANN_JSON_TARGET_NAME} ALIAS ${NLOHMANN_JSON_TARGET_NAME})
if (${CMAKE_VERSION} VERSION_LESS "3.8.0")
target_compile_features(${NLOHMANN_JSON_TARGET_NAME} INTERFACE cxx_range_for)
else()
target_compile_features(${NLOHMANN_JSON_TARGET_NAME} INTERFACE cxx_std_11)
endif()
target_include_directories(
${NLOHMANN_JSON_TARGET_NAME}
@@ -51,18 +60,18 @@ target_include_directories(
$<INSTALL_INTERFACE:include>
)
## add debug view defintion file for msvc (natvis) [cmake <= 3.2.2 does not support export of source files]
if (MSVC AND CMAKE_VERSION VERSION_GREATER "3.2.2")
## add debug view definition file for msvc (natvis)
if (MSVC)
set(NLOHMANN_ADD_NATVIS TRUE)
set(NLOHMANN_NATVIS_FILE "nlohmann_json.natvis")
target_sources(
${NLOHMANN_JSON_TARGET_NAME}
INTERFACE
${NLOHMANN_JSON_TARGET_NAME}
INTERFACE
$<INSTALL_INTERFACE:${NLOHMANN_NATVIS_FILE}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${NLOHMANN_NATVIS_FILE}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${NLOHMANN_NATVIS_FILE}>
)
endif()
##
## TESTS
## create and configure the unit test target
@@ -82,32 +91,40 @@ include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE} COMPATIBILITY SameMajorVersion
)
configure_package_config_file(
configure_file(
${NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE}
${NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE}
INSTALL_DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR}
@ONLY
)
install(
DIRECTORY ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}
DESTINATION ${NLOHMANN_JSON_INCLUDE_INSTALL_DIR}
)
install(
FILES ${NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE} ${NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE}
DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR}
)
if (NLOHMANN_ADD_NATVIS)
if(JSON_Install)
install(
FILES ${NLOHMANN_NATVIS_FILE}
DESTINATION .
)
DIRECTORY ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}
DESTINATION ${NLOHMANN_JSON_INCLUDE_INSTALL_DIR}
)
install(
FILES ${NLOHMANN_JSON_CMAKE_PROJECT_CONFIG_FILE} ${NLOHMANN_JSON_CMAKE_VERSION_CONFIG_FILE}
DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR}
)
if (NLOHMANN_ADD_NATVIS)
install(
FILES ${NLOHMANN_NATVIS_FILE}
DESTINATION .
)
endif()
export(
TARGETS ${NLOHMANN_JSON_TARGET_NAME}
NAMESPACE ${PROJECT_NAME}::
FILE ${NLOHMANN_JSON_CMAKE_PROJECT_TARGETS_FILE}
)
install(
TARGETS ${NLOHMANN_JSON_TARGET_NAME}
EXPORT ${NLOHMANN_JSON_TARGETS_EXPORT_NAME}
INCLUDES DESTINATION ${NLOHMANN_JSON_INCLUDE_INSTALL_DIR}
)
install(
EXPORT ${NLOHMANN_JSON_TARGETS_EXPORT_NAME}
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR}
)
endif()
install(
TARGETS ${NLOHMANN_JSON_TARGET_NAME}
EXPORT ${NLOHMANN_JSON_TARGETS_EXPORT_NAME}
INCLUDES DESTINATION ${NLOHMANN_JSON_INCLUDE_INSTALL_DIR}
)
install(
EXPORT ${NLOHMANN_JSON_TARGETS_EXPORT_NAME}
DESTINATION ${NLOHMANN_JSON_CONFIG_INSTALL_DIR}
)

View File

@@ -1,6 +1,497 @@
# Change Log
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
## [v3.6.0](https://github.com/nlohmann/json/releases/tag/v3.6.0) (2019-03-20)
[Full Changelog](https://github.com/nlohmann/json/compare/v3.5.0...v3.6.0)
- How can I turn a string of a json array into a json array? [\#1526](https://github.com/nlohmann/json/issues/1526)
- Minor: missing a std:: namespace tag [\#1521](https://github.com/nlohmann/json/issues/1521)
- how to precision to four decimal for double when use to\_json [\#1519](https://github.com/nlohmann/json/issues/1519)
- error parse [\#1518](https://github.com/nlohmann/json/issues/1518)
- Compile error: template argument deduction/substitution failed [\#1515](https://github.com/nlohmann/json/issues/1515)
- Support for Comments [\#1513](https://github.com/nlohmann/json/issues/1513)
- std::complex type [\#1510](https://github.com/nlohmann/json/issues/1510)
- CBOR byte string support [\#1509](https://github.com/nlohmann/json/issues/1509)
- Compilation error getting a std::pair\<\> on latest VS 2017 compiler [\#1506](https://github.com/nlohmann/json/issues/1506)
- "Integration" section of documentation needs update? [\#1505](https://github.com/nlohmann/json/issues/1505)
- Json object from string from a TCP socket [\#1504](https://github.com/nlohmann/json/issues/1504)
- MSVC warning C4946 \("reinterpret\_cast used between related classes"\) compiling json.hpp [\#1502](https://github.com/nlohmann/json/issues/1502)
- How to programmatically fill an n-th dimensional JSON object? [\#1501](https://github.com/nlohmann/json/issues/1501)
- Error compiling with clang and `JSON\_NOEXCEPTION`: need to include `cstdlib` [\#1500](https://github.com/nlohmann/json/issues/1500)
- The code compiles unsuccessfully with android-ndk-r10e [\#1499](https://github.com/nlohmann/json/issues/1499)
- Cmake 3.1 in develop, when is it likely to make it into a stable release? [\#1498](https://github.com/nlohmann/json/issues/1498)
- Repository is almost 450MB [\#1497](https://github.com/nlohmann/json/issues/1497)
- Some Help please object inside array [\#1494](https://github.com/nlohmann/json/issues/1494)
- How to get data into vector of user-defined type from a Json object [\#1493](https://github.com/nlohmann/json/issues/1493)
- how to find subelement without loop [\#1490](https://github.com/nlohmann/json/issues/1490)
- json to std::map [\#1487](https://github.com/nlohmann/json/issues/1487)
- Type in README.md [\#1486](https://github.com/nlohmann/json/issues/1486)
- Error in parsing and reading msgpack-lite [\#1485](https://github.com/nlohmann/json/issues/1485)
- Compiling issues with libc 2.12 [\#1483](https://github.com/nlohmann/json/issues/1483)
- How do I use reference or pointer binding values? [\#1482](https://github.com/nlohmann/json/issues/1482)
- Compilation fails in MSVC with the Microsoft Language Extensions disabled [\#1481](https://github.com/nlohmann/json/issues/1481)
- Functional visit [\#1480](https://github.com/nlohmann/json/issues/1480)
- \[Question\] Unescaped dump [\#1479](https://github.com/nlohmann/json/issues/1479)
- Some Help please [\#1478](https://github.com/nlohmann/json/issues/1478)
- Global variables are stored within the JSON file, how do I declare them as global variables when I read them out in my C++ program? [\#1476](https://github.com/nlohmann/json/issues/1476)
- Unable to modify one of the values within the JSON file, and save it [\#1475](https://github.com/nlohmann/json/issues/1475)
- Documentation of parse function has two identical @pre causes [\#1473](https://github.com/nlohmann/json/issues/1473)
- GCC 9.0 build failure [\#1472](https://github.com/nlohmann/json/issues/1472)
- Can we have an `exists\(\)` method? [\#1471](https://github.com/nlohmann/json/issues/1471)
- How to parse multi object json from file? [\#1470](https://github.com/nlohmann/json/issues/1470)
- How to returns the name of the upper object? [\#1467](https://github.com/nlohmann/json/issues/1467)
- Error: "tuple\_size" has already been declared in the current scope [\#1466](https://github.com/nlohmann/json/issues/1466)
- Checking keys of two jsons against eachother [\#1465](https://github.com/nlohmann/json/issues/1465)
- Disable installation when used as meson subproject [\#1463](https://github.com/nlohmann/json/issues/1463)
- Unpack list of integers to a std::vector\<int\> [\#1460](https://github.com/nlohmann/json/issues/1460)
- Implement DRY definition of JSON representation of a c++ class [\#1459](https://github.com/nlohmann/json/issues/1459)
- json.exception.type\_error.305 with GCC 4.9 when using C++ {} initializer [\#1458](https://github.com/nlohmann/json/issues/1458)
- API to convert an "uninitialized" json into an empty object or empty array [\#1456](https://github.com/nlohmann/json/issues/1456)
- How to parse a vector of objects with const attributes [\#1453](https://github.com/nlohmann/json/issues/1453)
- NLOHMANN\_JSON\_SERIALIZE\_ENUM potentially requires duplicate definitions [\#1450](https://github.com/nlohmann/json/issues/1450)
- Question about making json object from file directory [\#1449](https://github.com/nlohmann/json/issues/1449)
- .get\(\) throws error if used with userdefined structs in unordered\_map [\#1448](https://github.com/nlohmann/json/issues/1448)
- Integer Overflow \(OSS-Fuzz 12506\) [\#1447](https://github.com/nlohmann/json/issues/1447)
- If a string has too many invalid UTF-8 characters, json::dump attempts to index an array out of bounds. [\#1445](https://github.com/nlohmann/json/issues/1445)
- Setting values of .JSON file [\#1444](https://github.com/nlohmann/json/issues/1444)
- alias object\_t::key\_type in basic\_json [\#1442](https://github.com/nlohmann/json/issues/1442)
- Latest Ubuntu package is 2.1.1 [\#1438](https://github.com/nlohmann/json/issues/1438)
- lexer.hpp\(1363\) '\_snprintf': is not a member | Visualstudio 2017 [\#1437](https://github.com/nlohmann/json/issues/1437)
- Static method invites inadvertent logic error. [\#1433](https://github.com/nlohmann/json/issues/1433)
- EOS compilation produces "fatal error: 'nlohmann/json.hpp' file not found" [\#1432](https://github.com/nlohmann/json/issues/1432)
- Support for bad commas [\#1429](https://github.com/nlohmann/json/issues/1429)
- Please have one base exception class for all json exceptions [\#1427](https://github.com/nlohmann/json/issues/1427)
- Compilation warning: 'tuple\_size' defined as a class template here but previously declared as a struct template [\#1426](https://github.com/nlohmann/json/issues/1426)
- Which version can be used with GCC 4.8.2 ? [\#1424](https://github.com/nlohmann/json/issues/1424)
- Ignore nullptr values on constructing json object from a container [\#1422](https://github.com/nlohmann/json/issues/1422)
- Support for custom float precision via unquoted strings [\#1421](https://github.com/nlohmann/json/issues/1421)
- Segmentation fault \(stack overflow\) due to unbounded recursion [\#1419](https://github.com/nlohmann/json/issues/1419)
- It is possible to call `json::find` with a json\_pointer as argument. This causes runtime UB/crash. [\#1418](https://github.com/nlohmann/json/issues/1418)
- Dump throwing exception [\#1416](https://github.com/nlohmann/json/issues/1416)
- Build error [\#1415](https://github.com/nlohmann/json/issues/1415)
- Append version to include.zip [\#1412](https://github.com/nlohmann/json/issues/1412)
- error C2039: '\_snprintf': is not a member of 'std' - Windows [\#1408](https://github.com/nlohmann/json/issues/1408)
- Deserializing to vector [\#1407](https://github.com/nlohmann/json/issues/1407)
- Efficient way to set a `json` object as value into another `json` key [\#1406](https://github.com/nlohmann/json/issues/1406)
- Document return value of parse\(\) when allow\_exceptions == false and parsing fails [\#1405](https://github.com/nlohmann/json/issues/1405)
- Unexpected behaviour with structured binding [\#1404](https://github.com/nlohmann/json/issues/1404)
- Which native types does get\<type\>\(\) allow? [\#1403](https://github.com/nlohmann/json/issues/1403)
- Add something like Json::StaticString [\#1402](https://github.com/nlohmann/json/issues/1402)
- -Wmismatched-tags in 3.5.0? [\#1401](https://github.com/nlohmann/json/issues/1401)
- Coverity Scan reports an UNCAUGHT\_EXCEPT issue [\#1400](https://github.com/nlohmann/json/issues/1400)
- fff [\#1399](https://github.com/nlohmann/json/issues/1399)
- sorry this is not an issue, just a Question, How to change a key value in a file and save it ? [\#1398](https://github.com/nlohmann/json/issues/1398)
- Add library versioning using inline namespaces [\#1394](https://github.com/nlohmann/json/issues/1394)
- appveyor x64 builds appear to be using Win32 toolset [\#1374](https://github.com/nlohmann/json/issues/1374)
- Serializing/Deserializing a Class containing a vector of itself [\#1373](https://github.com/nlohmann/json/issues/1373)
- Retrieving array elements. [\#1369](https://github.com/nlohmann/json/issues/1369)
- Deserialize [\#1366](https://github.com/nlohmann/json/issues/1366)
- call of overloaded for push\_back and operator+= is ambiguous [\#1352](https://github.com/nlohmann/json/issues/1352)
- got an error and cann't figure it out [\#1351](https://github.com/nlohmann/json/issues/1351)
- Improve number-to-string conversion [\#1334](https://github.com/nlohmann/json/issues/1334)
- Implicit type conversion error on MSVC [\#1333](https://github.com/nlohmann/json/issues/1333)
- NuGet Package [\#1132](https://github.com/nlohmann/json/issues/1132)
- Change macros to numeric\_limits [\#1514](https://github.com/nlohmann/json/pull/1514) ([naszta](https://github.com/naszta))
- fix GCC 7.1.1 - 7.2.1 on CentOS [\#1496](https://github.com/nlohmann/json/pull/1496) ([lieff](https://github.com/lieff))
- Update Buckaroo instructions in README.md [\#1495](https://github.com/nlohmann/json/pull/1495) ([njlr](https://github.com/njlr))
- Fix gcc9 build error test/src/unit-allocator.cpp \(Issue \#1472\) [\#1492](https://github.com/nlohmann/json/pull/1492) ([stac47](https://github.com/stac47))
- Fix typo in README.md [\#1491](https://github.com/nlohmann/json/pull/1491) ([nickaein](https://github.com/nickaein))
- Do proper endian conversions [\#1489](https://github.com/nlohmann/json/pull/1489) ([andreas-schwab](https://github.com/andreas-schwab))
- Fix documentation [\#1477](https://github.com/nlohmann/json/pull/1477) ([nickaein](https://github.com/nickaein))
- Implement contains\(\) member function [\#1474](https://github.com/nlohmann/json/pull/1474) ([nickaein](https://github.com/nickaein))
- Add operator/= and operator/ to construct a JSON pointer by appending two JSON pointers [\#1469](https://github.com/nlohmann/json/pull/1469) ([garethsb-sony](https://github.com/garethsb-sony))
- Disable Clang -Wmismatched-tags warning on tuple\_size / tuple\_element [\#1468](https://github.com/nlohmann/json/pull/1468) ([past-due](https://github.com/past-due))
- Disable installation when used as meson subproject. \#1463 [\#1464](https://github.com/nlohmann/json/pull/1464) ([elvisoric](https://github.com/elvisoric))
- docs: README typo [\#1455](https://github.com/nlohmann/json/pull/1455) ([wythe](https://github.com/wythe))
- remove extra semicolon from readme [\#1451](https://github.com/nlohmann/json/pull/1451) ([Afforix](https://github.com/Afforix))
- attempt to fix \#1445, flush buffer in serializer::dump\_escaped in UTF8\_REJECT case. [\#1446](https://github.com/nlohmann/json/pull/1446) ([scinart](https://github.com/scinart))
- Use C++11 features supported by CMake 3.1. [\#1441](https://github.com/nlohmann/json/pull/1441) ([iwanders](https://github.com/iwanders))
- :rotating\_light: fixed unused variable warning [\#1435](https://github.com/nlohmann/json/pull/1435) ([pboettch](https://github.com/pboettch))
- allow push\_back\(\) and pop\_back\(\) calls on json\_pointer [\#1434](https://github.com/nlohmann/json/pull/1434) ([pboettch](https://github.com/pboettch))
- Add instructions about using nlohmann/json with the conda package manager [\#1430](https://github.com/nlohmann/json/pull/1430) ([nicoddemus](https://github.com/nicoddemus))
- Updated year in README.md [\#1425](https://github.com/nlohmann/json/pull/1425) ([hijxf](https://github.com/hijxf))
- Fixed broken links in the README file [\#1423](https://github.com/nlohmann/json/pull/1423) ([skypjack](https://github.com/skypjack))
- Fixed broken links in the README file [\#1420](https://github.com/nlohmann/json/pull/1420) ([skypjack](https://github.com/skypjack))
- docs: typo in README [\#1417](https://github.com/nlohmann/json/pull/1417) ([wythe](https://github.com/wythe))
- Fix x64 target platform for appveyor [\#1414](https://github.com/nlohmann/json/pull/1414) ([nickaein](https://github.com/nickaein))
- Improve dump\_integer performance [\#1411](https://github.com/nlohmann/json/pull/1411) ([nickaein](https://github.com/nickaein))
- buildsystem: relax requirement on cmake version [\#1409](https://github.com/nlohmann/json/pull/1409) ([yann-morin-1998](https://github.com/yann-morin-1998))
- CMake: Optional Install if Embedded [\#1330](https://github.com/nlohmann/json/pull/1330) ([ax3l](https://github.com/ax3l))
## [v3.5.0](https://github.com/nlohmann/json/releases/tag/v3.5.0) (2018-12-21)
[Full Changelog](https://github.com/nlohmann/json/compare/v3.4.0...v3.5.0)
- Copyconstructor inserts original into array with single element [\#1397](https://github.com/nlohmann/json/issues/1397)
- Get value without explicit typecasting [\#1395](https://github.com/nlohmann/json/issues/1395)
- Big file parsing [\#1393](https://github.com/nlohmann/json/issues/1393)
- some static analysis warning at line 11317 [\#1390](https://github.com/nlohmann/json/issues/1390)
- Adding Structured Binding Support [\#1388](https://github.com/nlohmann/json/issues/1388)
- map\<json::value\_t, string\> exhibits unexpected behavior [\#1387](https://github.com/nlohmann/json/issues/1387)
- Error Code Return [\#1386](https://github.com/nlohmann/json/issues/1386)
- using unordered\_map as object type [\#1385](https://github.com/nlohmann/json/issues/1385)
- float precision [\#1384](https://github.com/nlohmann/json/issues/1384)
- \[json.exception.type\_error.316\] invalid UTF-8 byte at index 1: 0xC3 [\#1383](https://github.com/nlohmann/json/issues/1383)
- Inconsistent Constructor \(GCC vs. Clang\) [\#1381](https://github.com/nlohmann/json/issues/1381)
- \#define or || [\#1379](https://github.com/nlohmann/json/issues/1379)
- How to iterate inside the values ? [\#1377](https://github.com/nlohmann/json/issues/1377)
- items\(\) unable to get the elements [\#1375](https://github.com/nlohmann/json/issues/1375)
- conversion json to std::map doesn't work for types \<int, double\> [\#1372](https://github.com/nlohmann/json/issues/1372)
- A minor issue in the build instructions [\#1371](https://github.com/nlohmann/json/issues/1371)
- Using this library without stream ? [\#1370](https://github.com/nlohmann/json/issues/1370)
- Writing and reading BSON data [\#1368](https://github.com/nlohmann/json/issues/1368)
- Retrieving array elements from object type iterator. [\#1367](https://github.com/nlohmann/json/issues/1367)
- json::dump\(\) silently crashes if items contain accented letters [\#1365](https://github.com/nlohmann/json/issues/1365)
- warnings in MSVC \(2015\) in 3.4.0 related to bool... [\#1364](https://github.com/nlohmann/json/issues/1364)
- Cant compile with -C++17 and beyond compiler options [\#1362](https://github.com/nlohmann/json/issues/1362)
- json to concrete type conversion through reference or pointer fails [\#1361](https://github.com/nlohmann/json/issues/1361)
- the first attributes of JSON string is misplaced [\#1360](https://github.com/nlohmann/json/issues/1360)
- Copy-construct using initializer-list converts objects to arrays [\#1359](https://github.com/nlohmann/json/issues/1359)
- About value\(key, default\_value\) and operator\[\]\(key\) [\#1358](https://github.com/nlohmann/json/issues/1358)
- Problem with printing json response object [\#1356](https://github.com/nlohmann/json/issues/1356)
- Serializing pointer segfaults [\#1355](https://github.com/nlohmann/json/issues/1355)
- Read `long long int` data as a number. [\#1354](https://github.com/nlohmann/json/issues/1354)
- eclipse oxygen in ubuntu get\<size\_t\> is ambiguous [\#1353](https://github.com/nlohmann/json/issues/1353)
- Can't build on Visual Studio 2017 v15.8.9 [\#1350](https://github.com/nlohmann/json/issues/1350)
- cannot parse from string? [\#1349](https://github.com/nlohmann/json/issues/1349)
- Error: out\_of\_range [\#1348](https://github.com/nlohmann/json/issues/1348)
- expansion pattern 'CompatibleObjectType' contains no argument packs, with CUDA 10 [\#1347](https://github.com/nlohmann/json/issues/1347)
- Unable to update a value for a nested\(multi-level\) json file [\#1344](https://github.com/nlohmann/json/issues/1344)
- Fails to compile when std::iterator\_traits is not SFINAE friendly. [\#1341](https://github.com/nlohmann/json/issues/1341)
- EOF flag not set on exhausted input streams. [\#1340](https://github.com/nlohmann/json/issues/1340)
- Shadowed Member in merge\_patch [\#1339](https://github.com/nlohmann/json/issues/1339)
- Periods/literal dots in keys? [\#1338](https://github.com/nlohmann/json/issues/1338)
- Protect macro expansion of commonly defined macros [\#1337](https://github.com/nlohmann/json/issues/1337)
- How to validate an input before parsing? [\#1336](https://github.com/nlohmann/json/issues/1336)
- Non-verifying dump\(\) alternative for debugging/logging needed [\#1335](https://github.com/nlohmann/json/issues/1335)
- Json Libarary is not responding for me in c++ [\#1332](https://github.com/nlohmann/json/issues/1332)
- Question - how to find an object in an array [\#1331](https://github.com/nlohmann/json/issues/1331)
- Nesting additional data in json object [\#1328](https://github.com/nlohmann/json/issues/1328)
- can to\_json\(\) be defined inside a class? [\#1324](https://github.com/nlohmann/json/issues/1324)
- CodeBlocks IDE can't find `json.hpp` header [\#1318](https://github.com/nlohmann/json/issues/1318)
- Change json\_pointer to provide an iterator begin/end/etc, don't use vectors, and also enable string\_view [\#1312](https://github.com/nlohmann/json/issues/1312)
- Xcode - adding it to library [\#1300](https://github.com/nlohmann/json/issues/1300)
- unicode: accept char16\_t, char32\_t sequences [\#1298](https://github.com/nlohmann/json/issues/1298)
- unicode: char16\_t\* is compiler error, but char16\_t\[\] is accepted [\#1297](https://github.com/nlohmann/json/issues/1297)
- Dockerfile Project Help Needed [\#1296](https://github.com/nlohmann/json/issues/1296)
- Comparisons between large unsigned and negative signed integers [\#1295](https://github.com/nlohmann/json/issues/1295)
- CMake alias to `nlohmann::json` [\#1291](https://github.com/nlohmann/json/issues/1291)
- Release zips without tests [\#1285](https://github.com/nlohmann/json/issues/1285)
- Suggestion to improve value\(\) accessors with respect to move semantics [\#1275](https://github.com/nlohmann/json/issues/1275)
- separate object\_t::key\_type from basic\_json::key\_type, and use an allocator which returns object\_t::key\_type [\#1274](https://github.com/nlohmann/json/issues/1274)
- Is there a nice way to associate external values with json elements? [\#1256](https://github.com/nlohmann/json/issues/1256)
- Delete by json\_pointer [\#1248](https://github.com/nlohmann/json/issues/1248)
- Expose lexer, as a StAX parser [\#1219](https://github.com/nlohmann/json/issues/1219)
- Subclassing json\(\) & error on recursive load [\#1201](https://github.com/nlohmann/json/issues/1201)
- Check value for existence by json\_pointer [\#1194](https://github.com/nlohmann/json/issues/1194)
- Feature/add file input adapter [\#1392](https://github.com/nlohmann/json/pull/1392) ([dumarjo](https://github.com/dumarjo))
- Added Support for Structured Bindings [\#1391](https://github.com/nlohmann/json/pull/1391) ([pratikpc](https://github.com/pratikpc))
- Link to issue \#958 broken [\#1382](https://github.com/nlohmann/json/pull/1382) ([kjpus](https://github.com/kjpus))
- readme: fix typo [\#1380](https://github.com/nlohmann/json/pull/1380) ([manu-chroma](https://github.com/manu-chroma))
- recommend using explicit from JSON conversions [\#1363](https://github.com/nlohmann/json/pull/1363) ([theodelrieu](https://github.com/theodelrieu))
- Fix merge\_patch shadow warning [\#1346](https://github.com/nlohmann/json/pull/1346) ([ax3l](https://github.com/ax3l))
- Allow installation via Meson [\#1345](https://github.com/nlohmann/json/pull/1345) ([mpoquet](https://github.com/mpoquet))
- Set eofbit on exhausted input stream. [\#1343](https://github.com/nlohmann/json/pull/1343) ([mefyl](https://github.com/mefyl))
- Add a SFINAE friendly iterator\_traits and use that instead. [\#1342](https://github.com/nlohmann/json/pull/1342) ([davedissian](https://github.com/davedissian))
- Fix EOL Whitespaces & CMake Spelling [\#1329](https://github.com/nlohmann/json/pull/1329) ([ax3l](https://github.com/ax3l))
## [v3.4.0](https://github.com/nlohmann/json/releases/tag/v3.4.0) (2018-10-30)
[Full Changelog](https://github.com/nlohmann/json/compare/v3.3.0...v3.4.0)
- Big uint64\_t values are serialized wrong [\#1327](https://github.com/nlohmann/json/issues/1327)
- \[Question\] Efficient check for equivalency? [\#1325](https://github.com/nlohmann/json/issues/1325)
- Can't use ifstream and .clear\(\) [\#1321](https://github.com/nlohmann/json/issues/1321)
- \[Warning\] -Wparentheses on line 555 on single\_include [\#1319](https://github.com/nlohmann/json/issues/1319)
- Compilation error using at and find with enum struct [\#1316](https://github.com/nlohmann/json/issues/1316)
- Parsing JSON from a web address [\#1311](https://github.com/nlohmann/json/issues/1311)
- How to convert JSON to Struct with embeded subject [\#1310](https://github.com/nlohmann/json/issues/1310)
- Null safety/coalescing function? [\#1309](https://github.com/nlohmann/json/issues/1309)
- Building fails using single include file: json.hpp [\#1308](https://github.com/nlohmann/json/issues/1308)
- json::parse\(std::string\) Exception inside packaged Lib [\#1306](https://github.com/nlohmann/json/issues/1306)
- Problem in Dockerfile with installation of library [\#1304](https://github.com/nlohmann/json/issues/1304)
- compile error in from\_json converting to container with std::pair [\#1299](https://github.com/nlohmann/json/issues/1299)
- Json that I am trying to parse, and I am lost Structure Array below top level [\#1293](https://github.com/nlohmann/json/issues/1293)
- Serializing std::variant causes stack overflow [\#1292](https://github.com/nlohmann/json/issues/1292)
- How do I go about customising from\_json to support \_\_int128\_t/\_\_uint128\_t? [\#1290](https://github.com/nlohmann/json/issues/1290)
- merge\_patch: inconsistent behaviour merging empty sub-object [\#1289](https://github.com/nlohmann/json/issues/1289)
- Buffer over/underrun using UBJson? [\#1288](https://github.com/nlohmann/json/issues/1288)
- Enable the latest C++ standard with Visual Studio [\#1287](https://github.com/nlohmann/json/issues/1287)
- truncation of constant value in to\_cbor\(\) [\#1286](https://github.com/nlohmann/json/issues/1286)
- eosio.wasmsdk error [\#1284](https://github.com/nlohmann/json/issues/1284)
- use the same interface for writing arrays and non-arrays [\#1283](https://github.com/nlohmann/json/issues/1283)
- How to read json file with optional entries and entries with different types [\#1281](https://github.com/nlohmann/json/issues/1281)
- merge result not as espected [\#1279](https://github.com/nlohmann/json/issues/1279)
- how to get only "name" from below json [\#1278](https://github.com/nlohmann/json/issues/1278)
- syntax error on right json string [\#1276](https://github.com/nlohmann/json/issues/1276)
- Parsing JSON Array where members have no key, using custom types [\#1267](https://github.com/nlohmann/json/issues/1267)
- I get a json exception periodically from json::parse for the same json [\#1263](https://github.com/nlohmann/json/issues/1263)
- serialize std::variant\<...\> [\#1261](https://github.com/nlohmann/json/issues/1261)
- GCC 8.2.1. Compilation error: invalid conversion from... [\#1246](https://github.com/nlohmann/json/issues/1246)
- BSON support [\#1244](https://github.com/nlohmann/json/issues/1244)
- enum to json mapping [\#1208](https://github.com/nlohmann/json/issues/1208)
- Soften the landing when dumping non-UTF8 strings \(type\_error.316 exception\) [\#1198](https://github.com/nlohmann/json/issues/1198)
- CMakeLists.txt in release zips? [\#1184](https://github.com/nlohmann/json/issues/1184)
- Add macro to define enum/JSON mapping [\#1323](https://github.com/nlohmann/json/pull/1323) ([nlohmann](https://github.com/nlohmann))
- Add BSON support [\#1320](https://github.com/nlohmann/json/pull/1320) ([nlohmann](https://github.com/nlohmann))
- Properly convert constants to CharType [\#1315](https://github.com/nlohmann/json/pull/1315) ([nlohmann](https://github.com/nlohmann))
- Allow to set error handler for decoding errors [\#1314](https://github.com/nlohmann/json/pull/1314) ([nlohmann](https://github.com/nlohmann))
- Add Meson related info to README [\#1305](https://github.com/nlohmann/json/pull/1305) ([koponomarenko](https://github.com/koponomarenko))
- Improve diagnostic messages for binary formats [\#1303](https://github.com/nlohmann/json/pull/1303) ([nlohmann](https://github.com/nlohmann))
- add new is\_constructible\_\* traits used in from\_json [\#1301](https://github.com/nlohmann/json/pull/1301) ([theodelrieu](https://github.com/theodelrieu))
- add constraints for variadic json\_ref constructors [\#1294](https://github.com/nlohmann/json/pull/1294) ([theodelrieu](https://github.com/theodelrieu))
- Improve diagnostic messages [\#1282](https://github.com/nlohmann/json/pull/1282) ([nlohmann](https://github.com/nlohmann))
- Removed linter warnings [\#1280](https://github.com/nlohmann/json/pull/1280) ([nlohmann](https://github.com/nlohmann))
- Thirdparty benchmark: Fix Clang detection. [\#1277](https://github.com/nlohmann/json/pull/1277) ([Lord-Kamina](https://github.com/Lord-Kamina))
## [v3.3.0](https://github.com/nlohmann/json/releases/tag/v3.3.0) (2018-10-05)
[Full Changelog](https://github.com/nlohmann/json/compare/v3.2.0...v3.3.0)
- When key is not found print the key name into error too [\#1273](https://github.com/nlohmann/json/issues/1273)
- Visual Studio 2017 15.8.5 "conditional expression is constant" warning on Line 1851 in json.hpp [\#1268](https://github.com/nlohmann/json/issues/1268)
- how can we get this working on WSL? [\#1264](https://github.com/nlohmann/json/issues/1264)
- Help needed [\#1259](https://github.com/nlohmann/json/issues/1259)
- A way to get to a JSON values "key" [\#1258](https://github.com/nlohmann/json/issues/1258)
- While compiling got 76 errors [\#1255](https://github.com/nlohmann/json/issues/1255)
- Two blackslashes on json output file [\#1253](https://github.com/nlohmann/json/issues/1253)
- Including nlohmann the badwrong way. [\#1250](https://github.com/nlohmann/json/issues/1250)
- how to build with clang? [\#1247](https://github.com/nlohmann/json/issues/1247)
- Cmake target\_link\_libraries unable to find nlohmann\_json since version 3.2.0 [\#1243](https://github.com/nlohmann/json/issues/1243)
- \[Question\] Access to end\(\) iterator reference [\#1242](https://github.com/nlohmann/json/issues/1242)
- Parsing different json format [\#1241](https://github.com/nlohmann/json/issues/1241)
- Parsing Multiple JSON Files [\#1240](https://github.com/nlohmann/json/issues/1240)
- Doesn't compile under C++17 [\#1239](https://github.com/nlohmann/json/issues/1239)
- Conversion operator for nlohmann::json is not SFINAE friendly [\#1237](https://github.com/nlohmann/json/issues/1237)
- Custom deserialization of number\_float\_t [\#1236](https://github.com/nlohmann/json/issues/1236)
- Move tests to a separate repo [\#1235](https://github.com/nlohmann/json/issues/1235)
- deprecated-declarations warnings when compiling tests with GCC 8.2.1. [\#1233](https://github.com/nlohmann/json/issues/1233)
- Incomplete type with json\_fwd.hpp [\#1232](https://github.com/nlohmann/json/issues/1232)
- Parse Error [\#1229](https://github.com/nlohmann/json/issues/1229)
- json::get function with argument [\#1227](https://github.com/nlohmann/json/issues/1227)
- questions regarding from\_json [\#1226](https://github.com/nlohmann/json/issues/1226)
- Lambda in unevaluated context [\#1225](https://github.com/nlohmann/json/issues/1225)
- NLohmann doesn't compile when enabling strict warning policies [\#1224](https://github.com/nlohmann/json/issues/1224)
- Creating array of objects [\#1223](https://github.com/nlohmann/json/issues/1223)
- Somewhat unhelpful error message "cannot use operator\[\] with object" [\#1220](https://github.com/nlohmann/json/issues/1220)
- single\_include json.hpp [\#1218](https://github.com/nlohmann/json/issues/1218)
- Maps with enum class keys which are convertible to JSON strings should be converted to JSON dictionaries [\#1217](https://github.com/nlohmann/json/issues/1217)
- Adding JSON Array to the Array [\#1216](https://github.com/nlohmann/json/issues/1216)
- Best way to output a vector of a given type to json [\#1215](https://github.com/nlohmann/json/issues/1215)
- compiler warning: double definition of macro JSON\_INTERNAL\_CATCH [\#1213](https://github.com/nlohmann/json/issues/1213)
- Compilation error when using MOCK\_METHOD1 from GMock and nlohmann::json [\#1212](https://github.com/nlohmann/json/issues/1212)
- Issues parsing a previously encoded binary \(non-UTF8\) string. [\#1211](https://github.com/nlohmann/json/issues/1211)
- Yet another ordering question: char \* and parse\(\) [\#1209](https://github.com/nlohmann/json/issues/1209)
- Error using gcc 8.1.0 on Ubuntu 14.04 [\#1207](https://github.com/nlohmann/json/issues/1207)
- "type must be string, but is " std::string\(j.type\_name\(\) [\#1206](https://github.com/nlohmann/json/issues/1206)
- Returning empty json object from a function of type const json& ? [\#1205](https://github.com/nlohmann/json/issues/1205)
- VS2017 compiler suggests using constexpr if [\#1204](https://github.com/nlohmann/json/issues/1204)
- Template instatiation error on compiling [\#1203](https://github.com/nlohmann/json/issues/1203)
- BUG - json dump field with unicode -\> array of ints \(instead of string\) [\#1197](https://github.com/nlohmann/json/issues/1197)
- Compile error using Code::Blocks // mingw-w64 GCC 8.1.0 - "Incomplete Type" [\#1193](https://github.com/nlohmann/json/issues/1193)
- SEGFAULT on arm target [\#1190](https://github.com/nlohmann/json/issues/1190)
- Compiler crash with old Clang [\#1179](https://github.com/nlohmann/json/issues/1179)
- Custom Precision on floating point numbers [\#1170](https://github.com/nlohmann/json/issues/1170)
- Can we have a json\_view class like std::string\_view? [\#1158](https://github.com/nlohmann/json/issues/1158)
- improve error handling [\#1152](https://github.com/nlohmann/json/issues/1152)
- We should remove static\_asserts [\#960](https://github.com/nlohmann/json/issues/960)
- Fix warning C4127: conditional expression is constant [\#1272](https://github.com/nlohmann/json/pull/1272) ([antonioborondo](https://github.com/antonioborondo))
- Turn off additional deprecation warnings for GCC. [\#1271](https://github.com/nlohmann/json/pull/1271) ([chuckatkins](https://github.com/chuckatkins))
- docs: Add additional CMake documentation [\#1270](https://github.com/nlohmann/json/pull/1270) ([chuckatkins](https://github.com/chuckatkins))
- unit-testsuites.cpp: fix hangup if file not found [\#1262](https://github.com/nlohmann/json/pull/1262) ([knilch0r](https://github.com/knilch0r))
- Fix broken cmake imported target alias [\#1260](https://github.com/nlohmann/json/pull/1260) ([chuckatkins](https://github.com/chuckatkins))
- GCC 48 [\#1257](https://github.com/nlohmann/json/pull/1257) ([henryiii](https://github.com/henryiii))
- Add version and license to meson.build [\#1252](https://github.com/nlohmann/json/pull/1252) ([koponomarenko](https://github.com/koponomarenko))
- \#1179 Reordered the code. It seems to stop clang 3.4.2 in RHEL 7 from crash… [\#1249](https://github.com/nlohmann/json/pull/1249) ([LEgregius](https://github.com/LEgregius))
- Use a version check to provide backwards comatible CMake imported target names [\#1245](https://github.com/nlohmann/json/pull/1245) ([chuckatkins](https://github.com/chuckatkins))
- Fix issue \#1237 [\#1238](https://github.com/nlohmann/json/pull/1238) ([theodelrieu](https://github.com/theodelrieu))
- Add a get overload taking a parameter. [\#1231](https://github.com/nlohmann/json/pull/1231) ([theodelrieu](https://github.com/theodelrieu))
- Move lambda out of unevaluated context [\#1230](https://github.com/nlohmann/json/pull/1230) ([mandreyel](https://github.com/mandreyel))
- Remove static asserts [\#1228](https://github.com/nlohmann/json/pull/1228) ([theodelrieu](https://github.com/theodelrieu))
- Better error 305 [\#1221](https://github.com/nlohmann/json/pull/1221) ([rivertam](https://github.com/rivertam))
- Fix \#1213 [\#1214](https://github.com/nlohmann/json/pull/1214) ([simnalamburt](https://github.com/simnalamburt))
- Export package to allow builds without installing [\#1202](https://github.com/nlohmann/json/pull/1202) ([dennisfischer](https://github.com/dennisfischer))
## [v3.2.0](https://github.com/nlohmann/json/releases/tag/v3.2.0) (2018-08-20)
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.2...v3.2.0)
- Am I doing this wrong? Getting an empty string [\#1199](https://github.com/nlohmann/json/issues/1199)
- Incompatible Pointer Type [\#1196](https://github.com/nlohmann/json/issues/1196)
- json.exception.type\_error.316 [\#1195](https://github.com/nlohmann/json/issues/1195)
- Strange warnings in Code::Blocks 17.12, GNU GCC [\#1192](https://github.com/nlohmann/json/issues/1192)
- \[Question\] Current place in code to change floating point resolution [\#1191](https://github.com/nlohmann/json/issues/1191)
- Add key name when throwing type error [\#1189](https://github.com/nlohmann/json/issues/1189)
- Not able to include in visual studio code? [\#1188](https://github.com/nlohmann/json/issues/1188)
- Get an Index or row number of an element [\#1186](https://github.com/nlohmann/json/issues/1186)
- reduce repos size [\#1185](https://github.com/nlohmann/json/issues/1185)
- Difference between `merge\_patch` and `update` [\#1183](https://github.com/nlohmann/json/issues/1183)
- Is there a way to get an element from a JSON without throwing an exception on failure? [\#1182](https://github.com/nlohmann/json/issues/1182)
- to\_string? [\#1181](https://github.com/nlohmann/json/issues/1181)
- How to cache a json object's pointer into a map? [\#1180](https://github.com/nlohmann/json/issues/1180)
- Can this library work within a Qt project for Android using Qt Creator? [\#1178](https://github.com/nlohmann/json/issues/1178)
- How to get all keys of one object? [\#1177](https://github.com/nlohmann/json/issues/1177)
- How can I only parse the first level and get the value as string? [\#1175](https://github.com/nlohmann/json/issues/1175)
- I have a query regarding nlohmann::basic\_json::basic\_json [\#1174](https://github.com/nlohmann/json/issues/1174)
- unordered\_map with vectors won't convert to json? [\#1173](https://github.com/nlohmann/json/issues/1173)
- return json objects from functions [\#1172](https://github.com/nlohmann/json/issues/1172)
- Problem when exporting to CBOR [\#1171](https://github.com/nlohmann/json/issues/1171)
- Roundtripping null to nullptr does not work [\#1169](https://github.com/nlohmann/json/issues/1169)
- MSVC fails to compile std::swap specialization for nlohmann::json [\#1168](https://github.com/nlohmann/json/issues/1168)
- Unexpected behaviour of is\_null - Part II [\#1167](https://github.com/nlohmann/json/issues/1167)
- Floating point imprecision [\#1166](https://github.com/nlohmann/json/issues/1166)
- Combine json objects into one? [\#1165](https://github.com/nlohmann/json/issues/1165)
- Is there any way to know if the object has changed? [\#1164](https://github.com/nlohmann/json/issues/1164)
- Value throws on null string [\#1163](https://github.com/nlohmann/json/issues/1163)
- Weird template issue in large project [\#1162](https://github.com/nlohmann/json/issues/1162)
- \_json returns a different result vs ::parse [\#1161](https://github.com/nlohmann/json/issues/1161)
- Showing difference between two json objects [\#1160](https://github.com/nlohmann/json/issues/1160)
- no instance of overloaded function "std::swap" matches the specified type [\#1159](https://github.com/nlohmann/json/issues/1159)
- resize\(...\)? [\#1157](https://github.com/nlohmann/json/issues/1157)
- Issue with struct nested in class' to\_json [\#1155](https://github.com/nlohmann/json/issues/1155)
- Deserialize std::map with std::nan [\#1154](https://github.com/nlohmann/json/issues/1154)
- Parse throwing errors [\#1149](https://github.com/nlohmann/json/issues/1149)
- cocoapod integration [\#1148](https://github.com/nlohmann/json/issues/1148)
- wstring parsing [\#1147](https://github.com/nlohmann/json/issues/1147)
- Is it possible to dump a two-dimensional array to "\[\[null\],\[1,2,3\]\]"? [\#1146](https://github.com/nlohmann/json/issues/1146)
- Want to write a class member variable and a struct variable \( this structure is inside the class\) to the json file [\#1145](https://github.com/nlohmann/json/issues/1145)
- Does json support converting an instance of a struct into json string? [\#1143](https://github.com/nlohmann/json/issues/1143)
- \#Most efficient way to search for child parameters \(recursive find?\) [\#1141](https://github.com/nlohmann/json/issues/1141)
- could not find to\_json\(\) method in T's namespace [\#1140](https://github.com/nlohmann/json/issues/1140)
- chars get treated as JSON numbers not JSON strings [\#1139](https://github.com/nlohmann/json/issues/1139)
- How do I count number of objects in array? [\#1137](https://github.com/nlohmann/json/issues/1137)
- Serializing a vector of classes? [\#1136](https://github.com/nlohmann/json/issues/1136)
- Compile error. Unable convert form nullptr to nullptr&& [\#1135](https://github.com/nlohmann/json/issues/1135)
- std::unordered\_map in struct, serialization [\#1133](https://github.com/nlohmann/json/issues/1133)
- dump\(\) can't handle umlauts [\#1131](https://github.com/nlohmann/json/issues/1131)
- Add a way to get a key reference from the iterator [\#1127](https://github.com/nlohmann/json/issues/1127)
- can't not parse "\\“ string [\#1123](https://github.com/nlohmann/json/issues/1123)
- if json file contain Internationalization chars , get exception [\#1122](https://github.com/nlohmann/json/issues/1122)
- How to use a json::iterator dereferenced value in code? [\#1120](https://github.com/nlohmann/json/issues/1120)
- clang compiler: error : unknown type name 'not' [\#1119](https://github.com/nlohmann/json/issues/1119)
- Disable implicit conversions from json to std::initializer\_list\<T\> for any T [\#1118](https://github.com/nlohmann/json/issues/1118)
- Implicit conversions to complex types can lead to surprising and confusing errors [\#1116](https://github.com/nlohmann/json/issues/1116)
- How can I write from\_json for a complex datatype that is not default constructible? [\#1115](https://github.com/nlohmann/json/issues/1115)
- Compile error in VS2015 when compiling unit-conversions.cpp [\#1114](https://github.com/nlohmann/json/issues/1114)
- ADL Serializer for std::any / boost::any [\#1113](https://github.com/nlohmann/json/issues/1113)
- Unexpected behaviour of is\_null [\#1112](https://github.com/nlohmann/json/issues/1112)
- How to resolve " undefined reference to `std::\_\_throw\_bad\_cast\(\)'" [\#1111](https://github.com/nlohmann/json/issues/1111)
- cannot compile on ubuntu 18.04 and 16.04 [\#1110](https://github.com/nlohmann/json/issues/1110)
- JSON representation for floating point values has too many digits [\#1109](https://github.com/nlohmann/json/issues/1109)
- Not working for classes containing "\_declspec\(dllimport\)" in their declaration [\#1108](https://github.com/nlohmann/json/issues/1108)
- Get keys from json object [\#1107](https://github.com/nlohmann/json/issues/1107)
- dump\(\) without alphabetical order [\#1106](https://github.com/nlohmann/json/issues/1106)
- Cannot deserialize types using std::ratio [\#1105](https://github.com/nlohmann/json/issues/1105)
- i want to learn json [\#1104](https://github.com/nlohmann/json/issues/1104)
- Type checking during compile [\#1103](https://github.com/nlohmann/json/issues/1103)
- Iterate through sub items [\#1102](https://github.com/nlohmann/json/issues/1102)
- cppcheck failing for version 3.1.2 [\#1101](https://github.com/nlohmann/json/issues/1101)
- Deserializing std::map [\#1100](https://github.com/nlohmann/json/issues/1100)
- accessing key by reference [\#1098](https://github.com/nlohmann/json/issues/1098)
- clang 3.8.0 croaks while trying to compile with debug symbols [\#1097](https://github.com/nlohmann/json/issues/1097)
- Serialize a list of class objects with json [\#1096](https://github.com/nlohmann/json/issues/1096)
- Small question [\#1094](https://github.com/nlohmann/json/issues/1094)
- Upgrading to 3.x: to\_/from\_json with enum class [\#1093](https://github.com/nlohmann/json/issues/1093)
- Q: few questions about json construction [\#1092](https://github.com/nlohmann/json/issues/1092)
- general crayCC compilation failure [\#1091](https://github.com/nlohmann/json/issues/1091)
- Merge Patch clears original data [\#1090](https://github.com/nlohmann/json/issues/1090)
- \[Question\] how to use nlohmann/json in c++? [\#1088](https://github.com/nlohmann/json/issues/1088)
- C++17 decomposition declaration support [\#1087](https://github.com/nlohmann/json/issues/1087)
- \[Question\] Access multi-level json objects [\#1086](https://github.com/nlohmann/json/issues/1086)
- Serializing vector [\#1085](https://github.com/nlohmann/json/issues/1085)
- update nested value in multi hierarchy json object [\#1084](https://github.com/nlohmann/json/issues/1084)
- Overriding default values? [\#1083](https://github.com/nlohmann/json/issues/1083)
- detail namespace collision with Cereal? [\#1082](https://github.com/nlohmann/json/issues/1082)
- Error using json.dump\(\); [\#1081](https://github.com/nlohmann/json/issues/1081)
- Consuming TCP Stream [\#1080](https://github.com/nlohmann/json/issues/1080)
- Compilation error with strong typed enums in map in combination with namespaces [\#1079](https://github.com/nlohmann/json/issues/1079)
- cassert error [\#1076](https://github.com/nlohmann/json/issues/1076)
- Valid json data not being parsed [\#1075](https://github.com/nlohmann/json/issues/1075)
- Feature request :: Better testing for key existance without try/catch [\#1074](https://github.com/nlohmann/json/issues/1074)
- Hi, I have input like a.b.c and want to convert it to \"a\"{\"b\": \"c\"} form. Any suggestions how do I do this? Thanks. [\#1073](https://github.com/nlohmann/json/issues/1073)
- ADL deserializer not picked up for non default-constructible type [\#1072](https://github.com/nlohmann/json/issues/1072)
- Deserializing std::array doesn't compiler \(no insert\(\)\) [\#1071](https://github.com/nlohmann/json/issues/1071)
- Serializing OpenCV Mat problem [\#1070](https://github.com/nlohmann/json/issues/1070)
- Compilation error with ICPC compiler [\#1068](https://github.com/nlohmann/json/issues/1068)
- Minimal branch? [\#1066](https://github.com/nlohmann/json/issues/1066)
- Not existing value, crash [\#1065](https://github.com/nlohmann/json/issues/1065)
- cyryllic symbols [\#1064](https://github.com/nlohmann/json/issues/1064)
- newbie usage question [\#1063](https://github.com/nlohmann/json/issues/1063)
- Trying j\["strTest"\] = "%A" produces "strTest": "-0X1.CCCCCCCCCCCCCP+205" [\#1062](https://github.com/nlohmann/json/issues/1062)
- convert json value to std::string??? [\#1061](https://github.com/nlohmann/json/issues/1061)
- Commented out test cases, should they be removed? [\#1060](https://github.com/nlohmann/json/issues/1060)
- different behaviour between clang and gcc with braced initialization [\#1059](https://github.com/nlohmann/json/issues/1059)
- json array: initialize with prescribed size and `resize` method. [\#1057](https://github.com/nlohmann/json/issues/1057)
- Is it possible to use exceptions istead of assertions? [\#1056](https://github.com/nlohmann/json/issues/1056)
- when using assign operator in with json object a static assertion fails.. [\#1055](https://github.com/nlohmann/json/issues/1055)
- Iterate over leafs of a JSON data structure: enrich the JSON pointer API [\#1054](https://github.com/nlohmann/json/issues/1054)
- \[Feature request\] Access by path [\#1053](https://github.com/nlohmann/json/issues/1053)
- document that implicit js -\> primitive conversion does not work for std::string::value\_type and why [\#1052](https://github.com/nlohmann/json/issues/1052)
- error: BasicJsonType in namespace :: does not name a type [\#1051](https://github.com/nlohmann/json/issues/1051)
- Destructor is called when filling object through assignement [\#1050](https://github.com/nlohmann/json/issues/1050)
- Is this thing thread safe for reads? [\#1049](https://github.com/nlohmann/json/issues/1049)
- clang-tidy: Call to virtual function during construction [\#1046](https://github.com/nlohmann/json/issues/1046)
- Using STL algorithms with JSON containers with expected results? [\#1045](https://github.com/nlohmann/json/issues/1045)
- Usage with gtest/gmock not working as expected [\#1044](https://github.com/nlohmann/json/issues/1044)
- Consequences of from\_json / to\_json being in namespace of data struct. [\#1042](https://github.com/nlohmann/json/issues/1042)
- const\_reference operator\[\]\(const typename object\_t::key\_type& key\) const throw instead of assert [\#1039](https://github.com/nlohmann/json/issues/1039)
- Trying to retrieve data from nested objects [\#1038](https://github.com/nlohmann/json/issues/1038)
- Direct download link for json\_fwd.hpp? [\#1037](https://github.com/nlohmann/json/issues/1037)
- I know the library supports UTF-8, but failed to dump the value [\#1036](https://github.com/nlohmann/json/issues/1036)
- Putting a Vec3-like vector into a json object [\#1035](https://github.com/nlohmann/json/issues/1035)
- Ternary operator crash [\#1034](https://github.com/nlohmann/json/issues/1034)
- Issued with Clion Inspection Resolution since 2018.1 [\#1033](https://github.com/nlohmann/json/issues/1033)
- Some testcases fail and one never finishes [\#1032](https://github.com/nlohmann/json/issues/1032)
- Can this class work with wchar\_t / std::wstring? [\#1031](https://github.com/nlohmann/json/issues/1031)
- Makefile: Valgrind flags have no effect [\#1030](https://github.com/nlohmann/json/issues/1030)
- 「==」 Should be 「\>」 [\#1029](https://github.com/nlohmann/json/issues/1029)
- HOCON reader? [\#1027](https://github.com/nlohmann/json/issues/1027)
- add json string in previous string?? [\#1025](https://github.com/nlohmann/json/issues/1025)
- RFC: fluent parsing interface [\#1023](https://github.com/nlohmann/json/issues/1023)
- Does it support chinese character? [\#1022](https://github.com/nlohmann/json/issues/1022)
- to/from\_msgpack only works with standard typization [\#1021](https://github.com/nlohmann/json/issues/1021)
- Build failure using latest clang and GCC compilers [\#1020](https://github.com/nlohmann/json/issues/1020)
- can two json objects be concatenated? [\#1019](https://github.com/nlohmann/json/issues/1019)
- Erase by integer index [\#1018](https://github.com/nlohmann/json/issues/1018)
- Function find overload taking a json\_pointer [\#1017](https://github.com/nlohmann/json/issues/1017)
- I think should implement an parser function [\#1016](https://github.com/nlohmann/json/issues/1016)
- Readme gif [\#1015](https://github.com/nlohmann/json/issues/1015)
- Python bindings [\#1014](https://github.com/nlohmann/json/issues/1014)
- how to add two json string in single object?? [\#1012](https://github.com/nlohmann/json/issues/1012)
- how to serialize class Object \(convert data in object into json\)?? [\#1011](https://github.com/nlohmann/json/issues/1011)
- Enable forward declaration of json by making json a class instead of a using declaration [\#997](https://github.com/nlohmann/json/issues/997)
- compilation error while using intel c++ compiler 2018 [\#994](https://github.com/nlohmann/json/issues/994)
- How to create a json variable? [\#990](https://github.com/nlohmann/json/issues/990)
- istream \>\> json --- 1st character skipped in stream [\#976](https://github.com/nlohmann/json/issues/976)
- Add a SAX parser [\#971](https://github.com/nlohmann/json/issues/971)
- Add Key name to Exception [\#932](https://github.com/nlohmann/json/issues/932)
- How to solve large json file? [\#927](https://github.com/nlohmann/json/issues/927)
- json\_pointer public push\_back, pop\_back [\#837](https://github.com/nlohmann/json/issues/837)
- Using input\_adapter in a slightly unexpected way [\#834](https://github.com/nlohmann/json/issues/834)
- Stack-overflow \(OSS-Fuzz 4234\) [\#832](https://github.com/nlohmann/json/issues/832)
- Fix -Wno-sometimes-uninitialized by initializing "result" in parse\_sax [\#1200](https://github.com/nlohmann/json/pull/1200) ([thyu](https://github.com/thyu))
- \[RFC\] Introduce a new macro function: JSON\_INTERNAL\_CATCH [\#1187](https://github.com/nlohmann/json/pull/1187) ([simnalamburt](https://github.com/simnalamburt))
- Fix unit tests that were silently skipped or crashed \(depending on the compiler\) [\#1176](https://github.com/nlohmann/json/pull/1176) ([grembo](https://github.com/grembo))
- Refactor/no virtual sax [\#1153](https://github.com/nlohmann/json/pull/1153) ([theodelrieu](https://github.com/theodelrieu))
- Fixed compiler error in VS 2015 for debug mode [\#1151](https://github.com/nlohmann/json/pull/1151) ([sonulohani](https://github.com/sonulohani))
- Fix links to cppreference named requirements \(formerly concepts\) [\#1144](https://github.com/nlohmann/json/pull/1144) ([jrakow](https://github.com/jrakow))
- meson: fix include directory [\#1142](https://github.com/nlohmann/json/pull/1142) ([jrakow](https://github.com/jrakow))
- Feature/unordered map conversion [\#1138](https://github.com/nlohmann/json/pull/1138) ([theodelrieu](https://github.com/theodelrieu))
- fixed compile error for \#1045 [\#1134](https://github.com/nlohmann/json/pull/1134) ([Daniel599](https://github.com/Daniel599))
- test \(non\)equality for alt\_string implementation [\#1130](https://github.com/nlohmann/json/pull/1130) ([agrianius](https://github.com/agrianius))
- remove stringstream dependency [\#1117](https://github.com/nlohmann/json/pull/1117) ([TinyTinni](https://github.com/TinyTinni))
- Provide a from\_json overload for std::map [\#1089](https://github.com/nlohmann/json/pull/1089) ([theodelrieu](https://github.com/theodelrieu))
- fix typo in README [\#1078](https://github.com/nlohmann/json/pull/1078) ([martin-mfg](https://github.com/martin-mfg))
- Fix typo [\#1058](https://github.com/nlohmann/json/pull/1058) ([dns13](https://github.com/dns13))
- Misc cmake packaging enhancements [\#1048](https://github.com/nlohmann/json/pull/1048) ([chuckatkins](https://github.com/chuckatkins))
- Fixed incorrect LLVM version number in README [\#1047](https://github.com/nlohmann/json/pull/1047) ([jammehcow](https://github.com/jammehcow))
- Fix trivial typo in comment. [\#1043](https://github.com/nlohmann/json/pull/1043) ([coryan](https://github.com/coryan))
- Package Manager: Spack [\#1041](https://github.com/nlohmann/json/pull/1041) ([ax3l](https://github.com/ax3l))
- CMake: 3.8+ is Sufficient [\#1040](https://github.com/nlohmann/json/pull/1040) ([ax3l](https://github.com/ax3l))
- Added support for string\_view in C++17 [\#1028](https://github.com/nlohmann/json/pull/1028) ([gracicot](https://github.com/gracicot))
- Added public target\_compile\_features for auto and constexpr [\#1026](https://github.com/nlohmann/json/pull/1026) ([ktonon](https://github.com/ktonon))
## [v3.1.2](https://github.com/nlohmann/json/releases/tag/v3.1.2) (2018-03-14)
[Full Changelog](https://github.com/nlohmann/json/compare/v3.1.1...v3.1.2)
@@ -16,7 +507,6 @@ All notable changes to this project will be documented in this file. This projec
- get\<T\> for types that are not default constructible [\#996](https://github.com/nlohmann/json/issues/996)
- Prevent Null values to appear in .dump\(\) [\#995](https://github.com/nlohmann/json/issues/995)
- number parsing [\#993](https://github.com/nlohmann/json/issues/993)
- How to create a json variable? [\#990](https://github.com/nlohmann/json/issues/990)
- C2664 \(C++/CLR\) cannot convert 'nullptr' to 'nullptr &&' [\#987](https://github.com/nlohmann/json/issues/987)
- Uniform initialization from another json object differs between gcc and clang. [\#985](https://github.com/nlohmann/json/issues/985)
- Problem with adding the lib as a submodule [\#983](https://github.com/nlohmann/json/issues/983)
@@ -31,7 +521,6 @@ All notable changes to this project will be documented in this file. This projec
- os\_defines.h:44:19: error: missing binary operator before token "\(" [\#970](https://github.com/nlohmann/json/issues/970)
- Passing an iteration object by reference to a function [\#967](https://github.com/nlohmann/json/issues/967)
- Json and fmt::lib's format\_arg\(\) [\#964](https://github.com/nlohmann/json/issues/964)
- Feature: to\_string\(const json& j\); [\#916](https://github.com/nlohmann/json/issues/916)
- Allowing for user-defined string type in lexer/parser [\#1009](https://github.com/nlohmann/json/pull/1009) ([nlohmann](https://github.com/nlohmann))
- dump to alternative string type, as defined in basic\_json template [\#1006](https://github.com/nlohmann/json/pull/1006) ([agrianius](https://github.com/agrianius))
@@ -785,7 +1274,6 @@ All notable changes to this project will be documented in this file. This projec
- json::diff generates incorrect patch when removing multiple array elements. [\#269](https://github.com/nlohmann/json/issues/269)
- Docs - What does Json\[key\] return? [\#267](https://github.com/nlohmann/json/issues/267)
- Compiler Errors With JSON.hpp [\#265](https://github.com/nlohmann/json/issues/265)
- Throw exception instead of crashing my app [\#264](https://github.com/nlohmann/json/issues/264)
- Ambiguous push\_back and operator+= overloads [\#263](https://github.com/nlohmann/json/issues/263)
- Preseving order of items in json [\#262](https://github.com/nlohmann/json/issues/262)
- '\' char problem in strings [\#261](https://github.com/nlohmann/json/issues/261)

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2013-2018 Niels Lohmann
Copyright (c) 2013-2019 Niels Lohmann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

247
Makefile
View File

@@ -9,8 +9,10 @@ SRCS = include/nlohmann/json.hpp \
include/nlohmann/detail/exceptions.hpp \
include/nlohmann/detail/input/binary_reader.hpp \
include/nlohmann/detail/input/input_adapters.hpp \
include/nlohmann/detail/input/json_sax.hpp \
include/nlohmann/detail/input/lexer.hpp \
include/nlohmann/detail/input/parser.hpp \
include/nlohmann/detail/input/position_t.hpp \
include/nlohmann/detail/iterators/internal_iterator.hpp \
include/nlohmann/detail/iterators/iter_impl.hpp \
include/nlohmann/detail/iterators/iteration_proxy.hpp \
@@ -20,7 +22,10 @@ SRCS = include/nlohmann/json.hpp \
include/nlohmann/detail/json_ref.hpp \
include/nlohmann/detail/macro_scope.hpp \
include/nlohmann/detail/macro_unscope.hpp \
include/nlohmann/detail/meta.hpp \
include/nlohmann/detail/meta/cpp_future.hpp \
include/nlohmann/detail/meta/detected.hpp \
include/nlohmann/detail/meta/type_traits.hpp \
include/nlohmann/detail/meta/void_t.hpp \
include/nlohmann/detail/output/binary_writer.hpp \
include/nlohmann/detail/output/output_adapters.hpp \
include/nlohmann/detail/output/serializer.hpp \
@@ -31,6 +36,9 @@ CXX=clang++
AMALGAMATED_FILE=single_include/nlohmann/json.hpp
# directory to recent compiler binaries
COMPILER_DIR=/Users/niels/Documents/projects/compilers/local/bin
# main target
all:
@echo "amalgamate - amalgamate file single_include/nlohmann/json.hpp from the include/nlohmann sources"
@@ -41,8 +49,12 @@ all:
@echo "clean - remove built files"
@echo "coverage - create coverage information with lcov"
@echo "cppcheck - analyze code with cppcheck"
@echo "cpplint - analyze code with cpplint"
@echo "clang_tidy - analyze code with Clang-Tidy"
@echo "clang_analyze - analyze code with Clang-Analyzer"
@echo "doctest - compile example files and check their output"
@echo "fuzz_testing - prepare fuzz testing of the JSON parser"
@echo "fuzz_testing_bson - prepare fuzz testing of the BSON parser"
@echo "fuzz_testing_cbor - prepare fuzz testing of the CBOR parser"
@echo "fuzz_testing_msgpack - prepare fuzz testing of the MessagePack parser"
@echo "fuzz_testing_ubjson - prepare fuzz testing of the UBJSON parser"
@@ -82,9 +94,9 @@ clean:
coverage:
mkdir build_coverage
cd build_coverage ; CXX=g++-5 cmake .. -GNinja -DJSON_Coverage=ON -DJSON_MultipleHeaders=ON
cd build_coverage ; CXX=g++-7 cmake .. -GNinja -DJSON_Coverage=ON -DJSON_MultipleHeaders=ON
cd build_coverage ; ninja
cd build_coverage ; ctest -j10
cd build_coverage ; ctest -E '.*_default' -j10
cd build_coverage ; ninja lcov_html
open build_coverage/test/html/index.html
@@ -111,9 +123,10 @@ doctest:
# -Wno-range-loop-analysis: items tests "for(const auto i...)"
# -Wno-float-equal: not all comparisons in the tests can be replaced by Approx
# -Wno-switch-enum -Wno-covered-switch-default: pedantic/contradicting warnings about switches
# -Wno-c++2a-compat: u8 literals will behave differently in C++20...
# -Wno-padded: padding is nothing to warn about
pedantic_clang:
$(MAKE) json_unit CXXFLAGS="\
$(MAKE) json_unit CXX=$(COMPILER_DIR)/clang++ CXXFLAGS=" \
-std=c++11 -Wno-c++98-compat -Wno-c++98-compat-pedantic \
-Werror \
-Weverything \
@@ -125,69 +138,234 @@ pedantic_clang:
-Wno-range-loop-analysis \
-Wno-float-equal \
-Wno-switch-enum -Wno-covered-switch-default \
-Wno-c++2a-compat \
-Wno-c++17-extensions \
-Wno-padded"
# calling GCC with most warnings
pedantic_gcc:
$(MAKE) json_unit CXXFLAGS="\
$(MAKE) json_unit CXX=$(COMPILER_DIR)/g++ CXXFLAGS=" \
-std=c++11 \
-Wno-deprecated-declarations \
-Werror \
-Wall -Wpedantic -Wextra \
-Waddress \
-Waddress-of-packed-member \
-Waggressive-loop-optimizations \
-Waligned-new=all \
-Wall \
-Walloc-zero \
-Walloca \
-Warray-bounds \
-Warray-bounds=2 \
-Wcast-qual -Wcast-align \
-Wattribute-alias=2 \
-Wattribute-warning \
-Wattributes \
-Wbool-compare \
-Wbool-operation \
-Wbuiltin-declaration-mismatch \
-Wbuiltin-macro-redefined \
-Wcannot-profile \
-Wcast-align \
-Wcast-function-type \
-Wcast-qual \
-Wcatch-value=3 \
-Wchar-subscripts \
-Wclass-conversion \
-Wclass-memaccess \
-Wclobbered \
-Wcomment \
-Wcomments \
-Wconditionally-supported \
-Wconversion \
-Wconversion-null \
-Wcoverage-mismatch \
-Wcpp \
-Wctor-dtor-privacy \
-Wdangling-else \
-Wdate-time \
-Wdelete-incomplete \
-Wdelete-non-virtual-dtor \
-Wdeprecated \
-Wdeprecated-copy \
-Wdeprecated-copy-dtor \
-Wdeprecated-declarations \
-Wdisabled-optimization \
-Wdiv-by-zero \
-Wdouble-promotion \
-Wduplicated-branches \
-Wduplicated-cond \
-Weffc++ \
-Wempty-body \
-Wendif-labels \
-Wenum-compare \
-Wexpansion-to-defined \
-Werror \
-Wextra \
-Wextra-semi \
-Wfloat-conversion \
-Wfloat-equal \
-Wformat \
-Wformat-contains-nul \
-Wformat-extra-args \
-Wformat-nonliteral \
-Wformat-overflow=2 \
-Wformat-security \
-Wformat-signedness \
-Wformat-truncation=2 \
-Wformat-y2k \
-Wformat-zero-length \
-Wformat=2 \
-Wno-ignored-qualifiers \
-Wframe-address \
-Wfree-nonheap-object \
-Whsa \
-Wif-not-aligned \
-Wignored-attributes \
-Wignored-qualifiers \
-Wimplicit-fallthrough=5 \
-Winherited-variadic-ctor \
-Winit-list-lifetime \
-Winit-self \
-Winline \
-Wint-in-bool-context \
-Wint-to-pointer-cast \
-Winvalid-memory-model \
-Winvalid-offsetof \
-Winvalid-pch \
-Wliteral-suffix \
-Wlogical-not-parentheses \
-Wlogical-op \
-Wlto-type-mismatch \
-Wmain \
-Wmaybe-uninitialized \
-Wmemset-elt-size \
-Wmemset-transposed-args \
-Wmisleading-indentation \
-Wmissing-attributes \
-Wmissing-braces \
-Wmissing-declarations \
-Wmissing-field-initializers \
-Wmissing-format-attribute \
-Wmissing-include-dirs \
-Wmissing-noreturn \
-Wmissing-profile \
-Wmultichar \
-Wmultiple-inheritance \
-Wmultistatement-macros \
-Wnarrowing \
-Wno-deprecated-declarations \
-Wno-long-long \
-Wno-namespaces \
-Wno-padded \
-Wno-switch-enum \
-Wno-system-headers \
-Wno-templates \
-Wno-undef \
-Wnoexcept \
-Wnoexcept-type \
-Wnon-template-friend \
-Wnon-virtual-dtor \
-Wnonnull \
-Wnonnull-compare \
-Wnonportable-cfstrings \
-Wnormalized \
-Wnull-dereference \
-Wodr \
-Wold-style-cast \
-Wopenmp-simd \
-Woverflow \
-Woverlength-strings \
-Woverloaded-virtual \
-Wpacked \
-Wpacked-bitfield-compat \
-Wpacked-not-aligned \
-Wparentheses \
-Wpedantic \
-Wpessimizing-move \
-Wplacement-new=2 \
-Wpmf-conversions \
-Wpointer-arith \
-Wpointer-compare \
-Wpragmas \
-Wprio-ctor-dtor \
-Wpsabi \
-Wredundant-decls \
-Wredundant-move \
-Wregister \
-Wreorder \
-Wrestrict \
-Wreturn-local-addr \
-Wreturn-type \
-Wscalar-storage-order \
-Wsequence-point \
-Wshadow \
-Wshadow-compatible-local \
-Wshadow-local \
-Wshadow=compatible-local \
-Wshadow=global \
-Wshadow=local \
-Wshift-count-negative \
-Wshift-count-overflow \
-Wshift-negative-value \
-Wshift-overflow=2 \
-Wsign-compare \
-Wsign-conversion \
-Wsign-promo \
-Wsized-deallocation \
-Wsizeof-array-argument \
-Wsizeof-pointer-div \
-Wsizeof-pointer-memaccess \
-Wstack-protector \
-Wstrict-aliasing=3 \
-Wstrict-null-sentinel \
-Wstrict-overflow=5 \
-Wstringop-overflow=4 \
-Wstringop-truncation \
-Wsubobject-linkage \
-Wsuggest-attribute=cold \
-Wsuggest-attribute=const \
-Wsuggest-attribute=format \
-Wsuggest-attribute=malloc \
-Wsuggest-attribute=noreturn \
-Wsuggest-attribute=pure \
-Wsuggest-final-methods \
-Wsuggest-final-types \
-Wsuggest-override \
-Wswitch \
-Wswitch-bool \
-Wswitch-default \
-Wswitch-unreachable \
-Wsync-nand \
-Wsynth \
-Wtautological-compare \
-Wterminate \
-Wtrampolines \
-Wtrigraphs \
-Wundef \
-Wuninitialized -Wunknown-pragmas \
-Wtype-limits \
-Wuninitialized \
-Wunknown-pragmas \
-Wunreachable-code \
-Wunsafe-loop-optimizations \
-Wunused \
-Wunused-but-set-parameter \
-Wunused-but-set-variable \
-Wunused-const-variable=2 \
-Wunused-function \
-Wunused-label \
-Wunused-local-typedefs \
-Wunused-macros \
-Wunused-parameter \
-Wunused-result \
-Wunused-value \
-Wunused-variable \
-Wuseless-cast \
-Wvariadic-macros"
-Wvarargs \
-Wvariadic-macros \
-Wvector-operation-performance \
-Wvirtual-inheritance \
-Wvirtual-move-assign \
-Wvla \
-Wvolatile-register-var \
-Wwrite-strings \
-Wzero-as-null-pointer-constant \
"
##########################################################################
# benchmarks
@@ -212,6 +390,14 @@ fuzz_testing:
find test/data/json_tests -size -5k -name *json | xargs -I{} cp "{}" fuzz-testing/testcases
@echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer"
fuzz_testing_bson:
rm -fr fuzz-testing
mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out
$(MAKE) parse_bson_fuzzer -C test CXX=afl-clang++
mv test/parse_bson_fuzzer fuzz-testing/fuzzer
find test/data -size -5k -name *.bson | xargs -I{} cp "{}" fuzz-testing/testcases
@echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer"
fuzz_testing_cbor:
rm -fr fuzz-testing
mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out
@@ -256,14 +442,38 @@ fuzzing-stop:
# call cppcheck on the main header file
cppcheck:
cppcheck --enable=warning --inconclusive --force --std=c++11 $(AMALGAMATED_FILE) --error-exitcode=1
cppcheck --enable=warning --inline-suppr --inconclusive --force --std=c++11 $(SRCS) --error-exitcode=1
# compile and check with Clang Static Analyzer
clang_analyze:
rm -fr clang_analyze_build
mkdir clang_analyze_build
cd clang_analyze_build ; CCC_CXX=/Users/niels/Documents/projects/llvm-clang/local/bin/clang++ /Users/niels/Documents/projects/llvm-clang/local/bin/scan-build cmake ..
/Users/niels/Documents/projects/llvm-clang/local/bin/scan-build -enable-checker alpha.core.DynamicTypeChecker,alpha.core.PointerArithm,alpha.core.PointerSub,alpha.cplusplus.DeleteWithNonVirtualDtor,alpha.cplusplus.IteratorRange,alpha.cplusplus.MisusedMovedObject,alpha.security.ArrayBoundV2,alpha.core.Conversion --use-c++=/Users/niels/Documents/projects/llvm-clang/local/bin/clang++ --view -analyze-headers -o clang_analyze_build/report.html make -j10 -C clang_analyze_build
cd clang_analyze_build ; CCC_CXX=$(COMPILER_DIR)/clang++ CXX=$(COMPILER_DIR)/clang++ $(COMPILER_DIR)/scan-build cmake .. -GNinja
cd clang_analyze_build ; $(COMPILER_DIR)/scan-build -enable-checker alpha.core.BoolAssignment,alpha.core.CallAndMessageUnInitRefArg,alpha.core.CastSize,alpha.core.CastToStruct,alpha.core.Conversion,alpha.core.DynamicTypeChecker,alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,alpha.core.SizeofPtr,alpha.core.StackAddressAsyncEscape,alpha.core.TestAfterDivZero,alpha.deadcode.UnreachableCode,core.builtin.BuiltinFunctions,core.builtin.NoReturnFunctions,core.CallAndMessage,core.DivideZero,core.DynamicTypePropagation,core.NonnilStringConstants,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,core.VLASize,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.SelfAssignment,deadcode.DeadStores,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull --use-c++=$(COMPILER_DIR)/clang++ --view -analyze-headers -o clang_analyze_build/report.html ninja
# call cpplint (some errors expected due to false positives)
cpplint:
third_party/cpplint/cpplint.py --filter=-whitespace,-legal,-readability/alt_tokens,-runtime/references,-runtime/explicit --quiet --recursive include
clang_tidy:
$(COMPILER_DIR)/clang-tidy $(SRCS) -- -Iinclude -std=c++11
pvs_studio:
rm -fr pvs_studio_build
mkdir pvs_studio_build
cd pvs_studio_build ; cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=On
cd pvs_studio_build ; pvs-studio-analyzer analyze -j 10
cd pvs_studio_build ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs
open pvs_studio_build/pvs/index.html
infer:
rm -fr infer_build
mkdir infer_build
cd infer_build ; infer compile -- cmake .. ; infer run -- make -j 4
oclint:
oclint $(SRCS) -report-type html -enable-global-analysis -o oclint_report.html -max-priority-1=10000 -max-priority-2=10000 -max-priority-3=10000 -- -std=c++11 -Iinclude
open oclint_report.html
##########################################################################
# maintainer targets
@@ -296,10 +506,11 @@ check-amalgamation:
# check if every header in nlohmann includes sufficient headers to be compiled
# individually
check-single-includes:
for x in $(SRCS); do \
@for x in $(SRCS); do \
echo "Checking self-sufficiency of $$x..." ; \
echo "#include <$$x>\nint main() {}\n" | sed 's|include/||' > single_include_test.cpp; \
$(CXX) $(CXXFLAGS) -Iinclude -std=c++11 single_include_test.cpp -o single_include_test; \
rm single_include_test.cpp single_include_test; \
rm -f single_include_test.cpp single_include_test; \
done
##########################################################################

418
README.md
View File

@@ -5,6 +5,7 @@
[![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f3732b3327e34358a0e9d1fe9f661f08)](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=nlohmann/json&amp;utm_campaign=Badge_Grade)
[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/nlohmann/json.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/nlohmann/json/context:cpp)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/TarF5pPn9NtHQjhf)
[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)
@@ -15,6 +16,8 @@
- [Design goals](#design-goals)
- [Integration](#integration)
- [CMake](#cmake)
- [Package Managers](#package-managers)
- [Examples](#examples)
- [JSON as first-class data type](#json-as-first-class-data-type)
- [Serialization / Deserialization](#serialization--deserialization)
@@ -24,7 +27,8 @@
- [JSON Merge Patch](#json-merge-patch)
- [Implicit conversions](#implicit-conversions)
- [Conversions to/from arbitrary types](#arbitrary-types-conversions)
- [Binary formats (CBOR, MessagePack, and UBJSON)](#binary-formats-cbor-messagepack-and-ubjson)
- [Specializing enum conversion](#specializing-enum-conversion)
- [Binary formats (BSON, CBOR, MessagePack, and UBJSON)](#binary-formats-bson-cbor-messagepack-and-ubjson)
- [Supported compilers](#supported-compilers)
- [License](#license)
- [Contact](#contact)
@@ -42,7 +46,7 @@ There are myriads of [JSON](http://json.org) libraries out there, and each may e
- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.
- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests agains all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).
- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).
Other aspects were not so important to us:
@@ -68,22 +72,105 @@ to the files you want to process JSON and set the necessary switches to enable C
You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`.
### CMake
You can also use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage requirements for `INTERFACE_INCLUDE_DIRECTORIES` to point to the appropriate include directories and `INTERFACE_COMPILE_FEATURES` for the necessary C++11 flags.
#### External
To use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration:
```cmake
# CMakeLists.txt
find_package(nlohmann_json 3.2.0 REQUIRED)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree.
#### Embedded
To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file:
```cmake
# Typically you don't care so much for a third party library's tests to be
# run from your own project's code.
set(JSON_BuildTests OFF CACHE INTERNAL "")
# If you only include this third party in PRIVATE source files, you do not
# need to install it when your main project gets installed.
# set(JSON_Install OFF CACHE INTERNAL "")
# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
# unintended consequences that will break the build. It's generally
# discouraged (although not necessarily well documented as such) to use
# include(...) for pulling in other CMake projects anyways.
add_subdirectory(nlohmann_json)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
#### Supporting Both
To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following:
``` cmake
# Top level CMakeLists.txt
project(FOO)
...
option(FOO_USE_EXTERNAL_JSON "Use an external JSON library" OFF)
...
add_subdirectory(thirdparty)
...
add_library(foo ...)
...
# Note that the namespaced target will always be available regardless of the
# import method
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
```cmake
# thirdparty/CMakeLists.txt
...
if(FOO_USE_EXTERNAL_JSON)
find_package(nlohmann_json 3.2.0 REQUIRED)
else()
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(nlohmann_json)
endif()
...
```
`thirdparty/nlohmann_json` is then a complete copy of this source tree.
### Package Managers
:beer: If you are using OS X and [Homebrew](http://brew.sh), just type `brew tap nlohmann/json` and `brew install nlohmann_json` and you're set. If you want the bleeding edge rather than the latest release, use `brew install nlohmann_json --HEAD`.
If you are using the [Meson Build System](http://mesonbuild.com), then you can wrap this repository as a subproject.
If you are using the [Meson Build System](http://mesonbuild.com), then you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/nlohmann_json), or simply use `meson wrap install nlohmann_json`.
If you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add `jsonformoderncpp/x.y.z@vthiery/stable` to your `conanfile.py`'s requires, where `x.y.z` is the release version you want to use. Please file issues [here](https://github.com/vthiery/conan-jsonformoderncpp/issues) if you experience problems with the packages.
If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the `nlohmann_json` package. Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging.
If you are using [hunter](https://github.com/ruslo/hunter/) on your project for external dependencies, then you can use the [nlohmann_json package](https://docs.hunter.sh/en/latest/packages/pkg/nlohmann_json.html). Please see the hunter project for any issues regarding the packaging.
If you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo install nlohmann/json`. Please file issues [here](https://github.com/LoopPerfect/buckaroo-recipes/issues/new?title=nlohmann/nlohmann/json).
If you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo add github.com/buckaroo-pm/nlohmann-json`. Please file issues [here](https://github.com/buckaroo-pm/nlohmann-json). There is a demo repo [here](https://github.com/njlr/buckaroo-nholmann-json-example).
If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can use the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json). Please see the vcpkg project for any issues regarding the packaging.
If you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`).
If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open).
If you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/). Please check [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) on how to use the package. Please files issues [here](https://github.com/hnkb/nlohmann-json-nuget/issues).
If you are using [conda](https://conda.io/), you can use the package [nlohmann_json](https://github.com/conda-forge/nlohmann_json-feedstock) from [conda-forge](https://conda-forge.org) executing `conda install -c conda-forge nlohmann_json`. Please file issues [here](https://github.com/conda-forge/nlohmann_json-feedstock/issues).
## Examples
Beside the examples below, you may want to check the [documentation](https://nlohmann.github.io/json/) where each function contains a separate code example (e.g., check out [`emplace()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a5338e282d1d02bed389d852dd670d98d.html#a5338e282d1d02bed389d852dd670d98d)). All [example files](https://github.com/nlohmann/json/tree/develop/doc/examples) can be compiled and executed on their own (e.g., file [emplace.cpp](https://github.com/nlohmann/json/blob/develop/doc/examples/emplace.cpp)).
@@ -169,7 +256,6 @@ json empty_object_explicit = json::object();
json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });
```
### Serialization / Deserialization
#### To/from strings
@@ -191,7 +277,7 @@ auto j2 = R"(
Note that without appending the `_json` suffix, the passed string literal is not parsed, but just used as JSON string value. That is, `json j = "{ \"happy\": true, \"pi\": 3.141 }"` would just store the string `"{ "happy": true, "pi": 3.141 }"` rather than parsing the actual object.
The above example can also be expressed explicitly using [`json::parse()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_aa9676414f2e36383c4b181fe856aa3c0.html#aa9676414f2e36383c4b181fe856aa3c0):
The above example can also be expressed explicitly using [`json::parse()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a5a0339361f3282cb8fd2f9ede6e17d72.html#a5a0339361f3282cb8fd2f9ede6e17d72):
```cpp
// parse explicitly
@@ -219,10 +305,11 @@ Note the difference between serialization and assignment:
// store a string in a JSON value
json j_string = "this is a string";
// retrieve the string value (implicit JSON to std::string conversion)
std::string cpp_string = j_string;
// retrieve the string value (explicit JSON to std::string conversion)
auto cpp_string2 = j_string.get<std::string>();
// retrieve the string value
auto cpp_string = j_string.get<std::string>();
// retrieve the string value (alternative when an variable already exists)
std::string cpp_string2;
j_string.get_to(cpp_string2);
// retrieve the serialized value (explicit JSON serialization)
std::string serialized_string = j_string.dump();
@@ -233,8 +320,9 @@ std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::
std::cout << j_string << " == " << serialized_string << std::endl;
```
[`.dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a5adea76fedba9898d404fef8598aa663.html#a5adea76fedba9898d404fef8598aa663) always returns the serialized value, and [`.get<std::string>()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a16f9445f7629f634221a42b967cdcd43.html#a16f9445f7629f634221a42b967cdcd43) returns the originally stored string value.
[`.dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a50ec80b02d0f3f51130d4abb5d1cfdc5.html#a50ec80b02d0f3f51130d4abb5d1cfdc5) always returns the serialized value, and [`.get<std::string>()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a16f9445f7629f634221a42b967cdcd43.html#a16f9445f7629f634221a42b967cdcd43) returns the originally stored string value.
Note the library only supports UTF-8. When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a50ec80b02d0f3f51130d4abb5d1cfdc5.html#a50ec80b02d0f3f51130d4abb5d1cfdc5) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.
#### To/from streams (e.g. files, string streams)
@@ -283,10 +371,52 @@ std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
json j = json::parse(v);
```
#### SAX interface
The library uses a SAX-like interface with the following functions:
```cpp
// called when null is parsed
bool null();
// called when a boolean is parsed; value is passed
bool boolean(bool val);
// called when a signed or unsigned integer number is parsed; value is passed
bool number_integer(number_integer_t val);
bool number_unsigned(number_unsigned_t val);
// called when a floating-point number is parsed; value and original string is passed
bool number_float(number_float_t val, const string_t& s);
// called when a string is parsed; value is passed and can be safely moved away
bool string(string_t& val);
// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known)
bool start_object(std::size_t elements);
bool end_object();
bool start_array(std::size_t elements);
bool end_array();
// called when an object key is parsed; value is passed and can be safely moved away
bool key(string_t& val);
// called when a parse error occurs; byte position, the last token, and an exception is passed
bool parse_error(std::size_t position, const std::string& last_token, const detail::exception& ex);
```
The return value of each function determines whether parsing should proceed.
To implement your own SAX handler, proceed as follows:
1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax<json>` as base class, but you can also use any class where the functions described above are implemented and public.
2. Create an object of your SAX interface class, e.g. `my_sax`.
3. Call `bool json::sax_parse(input, &my_sax)`; where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface.
Note the `sax_parse` function only returns a `bool` indicating the result of the last executed SAX event. It does not return a `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file [`json_sax.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/json_sax.hpp).
### STL-like access
We designed the JSON class to behave just like an STL container. In fact, it satisfies the [**ReversibleContainer**](http://en.cppreference.com/w/cpp/concept/ReversibleContainer) requirement.
We designed the JSON class to behave just like an STL container. In fact, it satisfies the [**ReversibleContainer**](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) requirement.
```cpp
// create an array using push_back
@@ -309,7 +439,7 @@ for (auto& element : j) {
}
// getter/setter
const std::string tmp = j[0];
const auto tmp = j[0].get<std::string>();
j[1] = 42;
bool foo = j.at(2);
@@ -344,6 +474,16 @@ for (json::iterator it = o.begin(); it != o.end(); ++it) {
std::cout << it.key() << " : " << it.value() << "\n";
}
// the same code as range for
for (auto& el : o.items()) {
std::cout << el.key() << " : " << el.value() << "\n";
}
// even easier with structured bindings (C++17)
for (auto& [key, value] : o.items()) {
std::cout << key << " : " << value << "\n";
}
// find an entry
if (o.find("foo") != o.end()) {
// there is an entry with key "foo"
@@ -481,7 +621,7 @@ json j_patch = R"({
})"_json;
// apply the patch
j_original.merge_patch(j_patch);
j_document.merge_patch(j_patch);
// {
// "a": "z",
// "c": {
@@ -492,35 +632,48 @@ j_original.merge_patch(j_patch);
### Implicit conversions
The type of the JSON object is determined automatically by the expression to store. Likewise, the stored value is implicitly converted.
Supported types can be implicitly converted to JSON values.
It is recommended to **NOT USE** implicit conversions **FROM** a JSON value.
You can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958).
```cpp
// strings
std::string s1 = "Hello, world!";
json js = s1;
std::string s2 = js;
auto s2 = js.get<std::string>();
// NOT RECOMMENDED
std::string s3 = js;
std::string s4;
s4 = js;
// Booleans
bool b1 = true;
json jb = b1;
bool b2 = jb;
auto b2 = jb.get<bool>();
// NOT RECOMMENDED
bool b3 = jb;
bool b4;
b4 = jb;
// numbers
int i = 42;
json jn = i;
double f = jn;
auto f = jn.get<double>();
// NOT RECOMMENDED
double f2 = jb;
double f3;
f3 = jb;
// etc.
```
You can also explicitly ask for the value:
Note that `char` types are not automatically converted to JSON strings, but to integer numbers. A conversion to a string must be specified explicitly:
```cpp
std::string vs = js.get<std::string>();
bool vb = jb.get<bool>();
int vi = jn.get<int>();
// etc.
char ch = 'A'; // ASCII value 65
json j_default = ch; // stores integer number 65
json j_string = std::string(1, ch); // stores string "A"
```
### Arbitrary types conversions
@@ -568,7 +721,7 @@ std::cout << j << std::endl;
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
// conversion: json -> person
ns::person p2 = j;
auto p2 = j.get<ns::person>();
// that's it
assert(p == p2);
@@ -587,24 +740,23 @@ namespace ns {
}
void from_json(const json& j, person& p) {
p.name = j.at("name").get<std::string>();
p.address = j.at("address").get<std::string>();
p.age = j.at("age").get<int>();
j.at("name").get_to(p.name);
j.at("address").get_to(p.address);
j.at("age").get_to(p.age);
}
} // namespace ns
```
That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.
Likewise, when calling `get<your_type>()`, the `from_json` method will be called.
Likewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.
Some important things:
* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
* When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible). (There is a way to bypass this requirement described later.)
* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
* When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
* In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a93403e803947b86f4da2d1fb3345cf2c.html#a93403e803947b86f4da2d1fb3345cf2c) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
* In case your type contains several `operator=` definitions, code like `your_variable = your_json;` [may not compile](https://github.com/nlohmann/json/issues/667). You need to write `your_variable = your_json.get<decltype your_variable>();` instead.
* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.
* Be careful with the definition order of the `from_json`/`to_json` functions: If a type `B` has a member of type `A`, you **MUST** define `to_json(A)` before `to_json(B)`. Look at [issue 561](https://github.com/nlohmann/json/issues/561) for more details.
#### How do I convert third-party types?
@@ -612,7 +764,7 @@ Some important things:
This requires a bit more advanced technique. But first, let's see how this conversion mechanism works:
The library uses **JSON Serializers** to convert types to json.
The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](http://en.cppreference.com/w/cpp/language/adl)).
The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)).
It is implemented like this (simplified):
@@ -661,7 +813,7 @@ namespace nlohmann {
#### How can I use `get()` for non-default constructible/non-copyable types?
There is a way, if your type is [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload:
There is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload:
```cpp
struct move_only_type {
@@ -748,14 +900,72 @@ struct bad_serializer
};
```
### Binary formats (CBOR, MessagePack, and UBJSON)
### Specializing enum conversion
Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [CBOR](http://cbor.io) (Concise Binary Object Representation), [MessagePack](http://msgpack.org), and [UBJSON](http://ubjson.org) (Universal Binary JSON Specification) to efficiently encode JSON values to byte vectors and to decode such vectors.
By default, enum values are serialized to JSON as integers. In some cases this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later de-serialized JSON data may be undefined or a different enum value than was originally intended.
It is possible to more precisely specify how a given enum is mapped to and from JSON as shown below:
```cpp
// example enum type declaration
enum TaskState {
TS_STOPPED,
TS_RUNNING,
TS_COMPLETED,
TS_INVALID=-1,
};
// map TaskState values to JSON as strings
NLOHMANN_JSON_SERIALIZE_ENUM( TaskState, {
{TS_INVALID, nullptr},
{TS_STOPPED, "stopped"},
{TS_RUNNING, "running"},
{TS_COMPLETED, "completed"},
})
```
The `NLOHMANN_JSON_SERIALIZE_ENUM()` macro declares a set of `to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serilization code.
**Usage:**
```cpp
// enum to JSON as string
json j = TS_STOPPED;
assert(j == "stopped");
// json string to enum
json j3 = "running";
assert(j3.get<TaskState>() == TS_RUNNING);
// undefined json value to enum (where the first map entry above is the default)
json jPi = 3.14;
assert(jPi.get<TaskState>() == TS_INVALID );
```
Just as in [Arbitrary Type Conversions](#arbitrary-types-conversions) above,
- `NLOHMANN_JSON_SERIALIZE_ENUM()` MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it and it will default to integer serialization.
- It MUST be available (e.g., proper headers must be included) everywhere you use the conversions.
Other Important points:
- When using `get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully.
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
### Binary formats (BSON, CBOR, MessagePack, and UBJSON)
Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [BSON](http://bsonspec.org) (Binary JSON), [CBOR](http://cbor.io) (Concise Binary Object Representation), [MessagePack](http://msgpack.org), and [UBJSON](http://ubjson.org) (Universal Binary JSON Specification) to efficiently encode JSON values to byte vectors and to decode such vectors.
```cpp
// create a JSON value
json j = R"({"compact": true, "schema": 0})"_json;
// serialize to BSON
std::vector<std::uint8_t> v_bson = json::to_bson(j);
// 0x1B, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
// roundtrip
json j_from_bson = json::from_bson(v_bson);
// serialize to CBOR
std::vector<std::uint8_t> v_cbor = json::to_cbor(j);
@@ -784,10 +994,10 @@ json j_from_ubjson = json::from_ubjson(v_ubjson);
## Supported compilers
Though it's 2018 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
Though it's 2019 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
- GCC 4.9 - 7.2 (and possibly later)
- Clang 3.4 - 5.0 (and possibly later)
- GCC 4.8 - 9.0 (and possibly later)
- Clang 3.4 - 8.0 (and possibly later)
- Intel C++ Compiler 17.0.2 (and possibly later)
- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
@@ -796,7 +1006,7 @@ I would be happy to learn about other compilers/versions.
Please note:
- GCC 4.8 does not work because of two bugs ([55817](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55817) and [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)) in the C++11 support. Note there is a [pull request](https://github.com/nlohmann/json/pull/212) to fix some of the issues.
- GCC 4.8 has a bug [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)): multiline raw strings cannot be the arguments to macros. Don't use multiline raw strings directly in macros with this compiler.
- Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default.
```
@@ -809,32 +1019,37 @@ Please note:
- For GCC running on MinGW or Android SDK, the error `'to_string' is not a member of 'std'` (or similarly, for `strtod`) may occur. Note this is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](http://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219).
- Unsupported versions of GCC and Clang are rejected by `#error` directives. This can be switched off by defining `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`. Note that you can expect no support in this case.
The following compilers are currently used in continuous integration at [Travis](https://travis-ci.org/nlohmann/json) and [AppVeyor](https://ci.appveyor.com/project/nlohmann/json):
| Compiler | Operating System | Version String |
|-----------------|------------------------------|----------------|
| GCC 4.9.4 | Ubuntu 14.04.5 LTS | g++-4.9 (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4 |
| GCC 5.4.1 | Ubuntu 14.04.5 LTS | g++-5 (Ubuntu 5.4.1-2ubuntu1~14.04) 5.4.1 20160904 |
| GCC 6.3.0 | Ubuntu 14.04.5 LTS | g++-6 (Ubuntu/Linaro 6.3.0-18ubuntu2~14.04) 6.3.0 20170519 |
| GCC 7.1.0 | Ubuntu 14.04.5 LTS | g++-7 (Ubuntu 7.1.0-5ubuntu2~14.04) 7.1.0
| Clang 3.5.0 | Ubuntu 14.04.5 LTS | clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) |
| Clang 3.6.2 | Ubuntu 14.04.5 LTS | clang version 3.6.2-svn240577-1~exp1 (branches/release_36) |
| Clang 3.7.1 | Ubuntu 14.04.5 LTS | clang version 3.7.1-svn253571-1~exp1 (branches/release_37) |
| Clang 3.8.0 | Ubuntu 14.04.5 LTS | clang version 3.8.0-2ubuntu3~trusty5 (tags/RELEASE_380/final) |
| Clang 3.9.1 | Ubuntu 14.04.5 LTS | clang version 3.9.1-4ubuntu3~14.04.2 (tags/RELEASE_391/rc2) |
| Clang 4.0.1 | Ubuntu 14.04.5 LTS | clang version 4.0.1-svn305264-1~exp1 (branches/release_40) |
| Clang 5.0.0 | Ubuntu 14.04.5 LTS | clang version 5.0.0-svn310902-1~exp1 (branches/release_50) |
| Clang Xcode 6.4 | Darwin Kernel Version 14.3.0 (OSX 10.10.3) | Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) |
| Clang Xcode 7.3 | Darwin Kernel Version 15.0.0 (OSX 10.10.5) | Apple LLVM version 7.3.0 (clang-703.0.29) |
| Clang Xcode 8.0 | Darwin Kernel Version 15.6.0 | Apple LLVM version 8.0.0 (clang-800.0.38) |
| Clang Xcode 8.1 | Darwin Kernel Version 16.1.0 (macOS 10.12.1) | Apple LLVM version 8.0.0 (clang-800.0.42.1) |
| Clang Xcode 8.2 | Darwin Kernel Version 16.1.0 (macOS 10.12.1) | Apple LLVM version 8.0.0 (clang-800.0.42.1) |
| Clang Xcode 8.3 | Darwin Kernel Version 16.5.0 (macOS 10.12.4) | Apple LLVM version 8.1.0 (clang-802.0.38) |
| Clang Xcode 9.0 | Darwin Kernel Version 16.7.0 (macOS 10.12.6) | Apple LLVM version 9.0.0 (clang-900.0.37) |
| Clang Xcode 9.1 | Darwin Kernel Version 16.7.0 (macOS 10.12.6) | Apple LLVM version 9.0.0 (clang-900.0.38) |
| Clang Xcode 9.2 | Darwin Kernel Version 16.7.0 (macOS 10.12.6) | Apple LLVM version 8.1.0 (clang-900.0.39.2) |
| GCC 4.8.5 | Ubuntu 14.04.5 LTS | g++-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.2) 4.8.5 |
| GCC 4.9.4 | Ubuntu 14.04.1 LTS | g++-4.9 (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4 |
| GCC 5.5.0 | Ubuntu 14.04.1 LTS | g++-5 (Ubuntu 5.5.0-12ubuntu1~14.04) 5.5.0 20171010 |
| GCC 6.4.0 | Ubuntu 14.04.1 LTS | g++-6 (Ubuntu 6.4.0-17ubuntu1~14.04) 6.4.0 20180424 |
| GCC 7.3.0 | Ubuntu 14.04.1 LTS | g++-7 (Ubuntu 7.3.0-21ubuntu1~14.04) 7.3.0 |
| GCC 7.3.0 | Windows Server 2012 R2 (x64) | g++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 7.3.0 |
| GCC 8.1.0 | Ubuntu 14.04.1 LTS | g++-8 (Ubuntu 8.1.0-5ubuntu1~14.04) 8.1.0 |
| Clang 3.5.0 | Ubuntu 14.04.1 LTS | clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0) |
| Clang 3.6.2 | Ubuntu 14.04.1 LTS | clang version 3.6.2-svn240577-1~exp1 (branches/release_36) (based on LLVM 3.6.2) |
| Clang 3.7.1 | Ubuntu 14.04.1 LTS | clang version 3.7.1-svn253571-1~exp1 (branches/release_37) (based on LLVM 3.7.1) |
| Clang 3.8.0 | Ubuntu 14.04.1 LTS | clang version 3.8.0-2ubuntu3~trusty5 (tags/RELEASE_380/final) |
| Clang 3.9.1 | Ubuntu 14.04.1 LTS | clang version 3.9.1-4ubuntu3~14.04.3 (tags/RELEASE_391/rc2) |
| Clang 4.0.1 | Ubuntu 14.04.1 LTS | clang version 4.0.1-svn305264-1~exp1 (branches/release_40) |
| Clang 5.0.2 | Ubuntu 14.04.1 LTS | clang version 5.0.2-svn328729-1~exp1~20180509123505.100 (branches/release_50) |
| Clang 6.0.1 | Ubuntu 14.04.1 LTS | clang version 6.0.1-svn334776-1~exp1~20180726133705.85 (branches/release_60) |
| Clang 7.0.1 | Ubuntu 14.04.1 LTS | clang version 7.0.1-svn348686-1~exp1~20181213084532.54 (branches/release_70) |
| Clang Xcode 8.3 | OSX 10.11.6 | Apple LLVM version 8.1.0 (clang-802.0.38) |
| Clang Xcode 9.0 | OSX 10.12.6 | Apple LLVM version 9.0.0 (clang-900.0.37) |
| Clang Xcode 9.1 | OSX 10.12.6 | Apple LLVM version 9.0.0 (clang-900.0.38) |
| Clang Xcode 9.2 | OSX 10.13.3 | Apple LLVM version 9.1.0 (clang-902.0.39.1) |
| Clang Xcode 9.3 | OSX 10.13.3 | Apple LLVM version 9.1.0 (clang-902.0.39.2) |
| Clang Xcode 10.0 | OSX 10.13.3 | Apple LLVM version 10.0.0 (clang-1000.11.45.2) |
| Clang Xcode 10.1 | OSX 10.13.3 | Apple LLVM version 10.0.0 (clang-1000.11.45.5) |
| Visual Studio 14 2015 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 14.0.25420.1, MSVC 19.0.24215.1 |
| Visual Studio 2017 | Windows Server 2016 | Microsoft (R) Build Engine version 15.5.180.51428, MSVC 19.12.25830.2 |
| Visual Studio 2017 | Windows Server 2016 | Microsoft (R) Build Engine version 15.7.180.61344, MSVC 19.14.26433.0 |
## License
@@ -842,7 +1057,7 @@ The following compilers are currently used in continuous integration at [Travis]
The class is licensed under the [MIT License](http://opensource.org/licenses/MIT):
Copyright &copy; 2013-2018 [Niels Lohmann](http://nlohmann.me)
Copyright &copy; 2013-2019 [Niels Lohmann](http://nlohmann.me)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
@@ -862,12 +1077,15 @@ If you have questions regarding the library, I would like to invite you to [open
Only if your request would contain confidential information, please [send me an email](mailto:mail@nlohmann.me). For encrypted messages, please use [this key](https://keybase.io/nlohmann/pgp_keys.asc).
## Security
[Commits by Niels Lohmann](https://github.com/nlohmann/json/commits) and [releases](https://github.com/nlohmann/json/releases) are signed with this [PGP Key](https://keybase.io/nlohmann/pgp_keys.asc?fingerprint=797167ae41c0a6d9232e48457f3cea63ae251b69).
## Thanks
I deeply appreciate the help of the following people.
![Contributors](https://raw.githubusercontent.com/nlohmann/json/develop/doc/avatars.png)
<img src="https://raw.githubusercontent.com/nlohmann/json/develop/doc/avatars.png" align="right">
- [Teemperor](https://github.com/Teemperor) implemented CMake support and lcov integration, realized escape and Unicode handling in the string parser, and fixed the JSON serialization.
- [elliotgoodrich](https://github.com/elliotgoodrich) fixed an issue with double deletion in the iterator classes.
@@ -916,7 +1134,7 @@ I deeply appreciate the help of the following people.
- [Vladimir Petrigo](https://github.com/vpetrigo) made a SFINAE hack more readable and added Visual Studio 17 to the build matrix.
- [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file.
- [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function.
- [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](http://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing.
- [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](https://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing.
- [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan.
- [Jared Grubb](https://github.com/jaredgrubb) silenced a nasty documentation warning.
- [Yixin Zhang](https://github.com/qwename) fixed an integer overflow check.
@@ -975,14 +1193,74 @@ I deeply appreciate the help of the following people.
- [Paul Fultz II](https://github.com/pfultz2) added a note on the cget package manager.
- [Wilson Lin](https://github.com/wla80) made the integration section of the README more concise.
- [RalfBielig](https://github.com/ralfbielig) detected and fixed a memory leak in the parser callback.
- [agrianius](https://github.com/agrianius) allowed to dump JSON to an alternative string type
- [agrianius](https://github.com/agrianius) allowed to dump JSON to an alternative string type.
- [Kevin Tonon](https://github.com/ktonon) overworked the C++11 compiler checks in CMake.
- [Axel Huebl](https://github.com/ax3l) simplified a CMake check and added support for the [Spack package manager](https://spack.io).
- [Carlos O'Ryan](https://github.com/coryan) fixed a typo.
- [James Upjohn](https://github.com/jammehcow) fixed a version number in the compilers section.
- [Chuck Atkins](https://github.com/chuckatkins) adjusted the CMake files to the CMake packaging guidelines and provided documentation for the CMake integration.
- [Jan Schöppach](https://github.com/dns13) fixed a typo.
- [martin-mfg](https://github.com/martin-mfg) fixed a typo.
- [Matthias Möller](https://github.com/TinyTinni) removed the dependency from `std::stringstream`.
- [agrianius](https://github.com/agrianius) added code to use alternative string implementations.
- [Daniel599](https://github.com/Daniel599) allowed to use more algorithms with the `items()` function.
- [Julius Rakow](https://github.com/jrakow) fixed the Meson include directory and fixed the links to [cppreference.com](cppreference.com).
- [Sonu Lohani](https://github.com/sonulohani) fixed the compilation with MSVC 2015 in debug mode.
- [grembo](https://github.com/grembo) fixed the test suite and re-enabled several test cases.
- [Hyeon Kim](https://github.com/simnalamburt) introduced the macro `JSON_INTERNAL_CATCH` to control the exception handling inside the library.
- [thyu](https://github.com/thyu) fixed a compiler warning.
- [David Guthrie](https://github.com/LEgregius) fixed a subtle compilation error with Clang 3.4.2.
- [Dennis Fischer](https://github.com/dennisfischer) allowed to call `find_package` without installing the library.
- [Hyeon Kim](https://github.com/simnalamburt) fixed an issue with a double macro definition.
- [Ben Berman](https://github.com/rivertam) made some error messages more understandable.
- [zakalibit](https://github.com/zakalibit) fixed a compilation problem with the Intel C++ compiler.
- [mandreyel](https://github.com/mandreyel) fixed a compilation problem.
- [Kostiantyn Ponomarenko](https://github.com/koponomarenko) added version and license information to the Meson build file.
- [Henry Schreiner](https://github.com/henryiii) added support for GCC 4.8.
- [knilch](https://github.com/knilch0r) made sure the test suite does not stall when run in the wrong directory.
- [Antonio Borondo](https://github.com/antonioborondo) fixed an MSVC 2017 warning.
- [Dan Gendreau](https://github.com/dgendreau) implemented the `NLOHMANN_JSON_SERIALIZE_ENUM` macro to quickly define a enum/JSON mapping.
- [efp](https://github.com/efp) added line and column information to parse errors.
- [julian-becker](https://github.com/julian-becker) added BSON support.
- [Pratik Chowdhury](https://github.com/pratikpc) added support for structured bindings.
- [David Avedissian](https://github.com/davedissian) added support for Clang 5.0.1 (PS4 version).
- [Jonathan Dumaresq](https://github.com/dumarjo) implemented an input adapter to read from `FILE*`.
- [kjpus](https://github.com/kjpus) fixed a link in the documentation.
- [Manvendra Singh](https://github.com/manu-chroma) fixed a typo in the documentation.
- [ziggurat29](https://github.com/ziggurat29) fixed an MSVC warning.
- [Sylvain Corlay](https://github.com/SylvainCorlay) added code to avoid an issue with MSVC.
- [mefyl](https://github.com/mefyl) fixed a bug when JSON was parsed from an input stream.
- [Millian Poquet](https://github.com/mpoquet) allowed to install the library via Meson.
- [Michael Behrns-Miller](https://github.com/moodboom) found an issue with a missing namespace.
- [Nasztanovics Ferenc](https://github.com/naszta) fixed a compilation issue with libc 2.12.
- [Andreas Schwab](https://github.com/andreas-schwab) fixed the endian conversion.
- [Mark-Dunning](https://github.com/Mark-Dunning) fixed a warning in MSVC.
- [Gareth Sylvester-Bradley](https://github.com/garethsb-sony) added `operator/` for JSON Pointers.
- [John-Mark](https://github.com/johnmarkwayve) noted a missing header.
- [Vitaly Zaitsev](https://github.com/xvitaly) fixed compilation with GCC 9.0.
- [Laurent Stacul](https://github.com/stac47) fixed compilation with GCC 9.0.
- [Ivor Wanders](https://github.com/iwanders) helped reducing the CMake requirement to version 3.1.
- [njlr](https://github.com/njlr) updated the Buckaroo instructions.
- [Lion](https://github.com/lieff) fixed a compilation issue with GCC 7 on CentOS.
- [Isaac Nickaein](https://github.com/nickaein) improved the integer serilization performance and implemented the `contains()` function.
- [past-due](https://github.com/past-due) suppressed an unfixable warning.
- [Elvis Oric](https://github.com/elvisoric) improved Meson support.
- [Matěj Plch](https://github.com/Afforix) fixed an example in the README.
- [Mark Beckwith](https://github.com/wythe) fixed a typo.
- [scinart](https://github.com/scinart) fixed bug in the serializer.
- [Patrick Boettcher](https://github.com/pboettch) implemented `push_back()` and `pop_back()` for JSON Pointers.
- [Bruno Oliveira](https://github.com/nicoddemus) added support for Conda.
- [Michele Caini](https://github.com/skypjack) fixed links in the README.
- [Hani](https://github.com/hnkb) documented how to install the library with NuGet.
- [Mark Beckwith](https://github.com/wythe) fixed a typo.
- [yann-morin-1998](https://github.com/yann-morin-1998) helped reducing the CMake requirement to version 3.1.
Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.
## Used third-party tools
The library itself contains of a single header file licensed under the MIT license. However, it is built, tested, documented, and whatnot using a lot of third-party tools and services. Thanks a lot!
The library itself consists of a single header file licensed under the MIT license. However, it is built, tested, documented, and whatnot using a lot of third-party tools and services. Thanks a lot!
- [**amalgamate.py - Amalgamate C source and header files**](https://github.com/edlund/amalgamate) to create a single header file
- [**American fuzzy lop**](http://lcamtuf.coredump.cx/afl/) for fuzz testing
@@ -990,7 +1268,7 @@ The library itself contains of a single header file licensed under the MIT licen
- [**Artistic Style**](http://astyle.sourceforge.net) for automatic source code identation
- [**Catch**](https://github.com/philsquared/Catch) for the unit tests
- [**Clang**](http://clang.llvm.org) for compilation with code sanitizers
- [**Cmake**](https://cmake.org) for build automation
- [**CMake**](https://cmake.org) for build automation
- [**Codacity**](https://www.codacy.com) for further [code analysis](https://www.codacy.com/app/nlohmann/json)
- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json)
- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json)
@@ -1015,10 +1293,10 @@ The library is currently used in Apple macOS Sierra and iOS 10. I am not sure wh
## Notes
- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](http://en.cppreference.com/w/cpp/error/assert). In particular, note [`operator[]`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a2e26bd0b0168abb61f67ad5bcd5b9fa1.html#a2e26bd0b0168abb61f67ad5bcd5b9fa1) implements **unchecked access** for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an [assertion failure](https://github.com/nlohmann/json/issues/289) if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the [`at()` function](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a674de1ee73e6bf4843fc5dc1351fb726.html#a674de1ee73e6bf4843fc5dc1351fb726).
- As the exact type of a number is not defined in the [JSON specification](http://rfc7159.net/rfc7159), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions.
- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](https://en.cppreference.com/w/cpp/error/assert). In particular, note [`operator[]`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a233b02b0839ef798942dd46157cc0fe6.html#a233b02b0839ef798942dd46157cc0fe6) implements **unchecked access** for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an [assertion failure](https://github.com/nlohmann/json/issues/289) if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the [`at()` function](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a73ae333487310e3302135189ce8ff5d8.html#a73ae333487310e3302135189ce8ff5d8).
- As the exact type of a number is not defined in the [JSON specification](https://tools.ietf.org/html/rfc7159.html), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions.
- The library supports **Unicode input** as follows:
- Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 7159](http://rfc7159.net/rfc7159#rfc.section.8.1).
- Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 7159](https://tools.ietf.org/html/rfc7159.html#section-8.1).
- Other encodings such as Latin-1, UTF-16, or UTF-32 are not supported and will yield parse or serialization errors.
- [Unicode noncharacters](http://www.unicode.org/faq/private_use.html#nonchar1) will not be replaced by the library.
- Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors.

View File

@@ -1,26 +1,65 @@
version: '{build}'
os:
- Visual Studio 2015
- Visual Studio 2017
environment:
matrix:
- additional_flags: ""
- additional_flags: "/permissive- /std:c++latest /utf-8"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
COMPILER: mingw
platform: x86
CXX_FLAGS: ""
LINKER_FLAGS: ""
GENERATOR: Ninja
matrix:
exclude:
- additional_flags: "/permissive- /std:c++latest /utf-8"
os: Visual Studio 2015
init: []
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
platform: x86
CXX_FLAGS: ""
LINKER_FLAGS: ""
GENERATOR: Visual Studio 14 2015
install: []
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
platform: x86
CXX_FLAGS: ""
LINKER_FLAGS: ""
GENERATOR: Visual Studio 15 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
platform: x86
CXX_FLAGS: "/permissive- /std:c++latest /utf-8"
LINKER_FLAGS: ""
GENERATOR: Visual Studio 15 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
platform: x64
CXX_FLAGS: ""
LINKER_FLAGS: ""
GENERATOR: Visual Studio 14 2015 Win64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
platform: x64
CXX_FLAGS: ""
LINKER_FLAGS: ""
GENERATOR: Visual Studio 15 2017 Win64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
platform: x64
CXX_FLAGS: "/permissive- /std:c++latest /utf-8 /F4000000"
LINKER_FLAGS: "/STACK:4000000"
GENERATOR: Visual Studio 15 2017 Win64
init:
- cmake --version
- msbuild /version
install:
- if "%COMPILER%"=="mingw" appveyor DownloadFile https://github.com/ninja-build/ninja/releases/download/v1.6.0/ninja-win.zip -FileName ninja.zip
- if "%COMPILER%"=="mingw" 7z x ninja.zip -oC:\projects\deps\ninja > nul
- if "%COMPILER%"=="mingw" set PATH=C:\projects\deps\ninja;%PATH%
- if "%COMPILER%"=="mingw" set PATH=C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin;%PATH%
- if "%COMPILER%"=="mingw" g++ --version
before_build:
- cmake . -G "%GENERATOR%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_EXE_LINKER_FLAGS="%LINKER_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin"
build_script:
- IF "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2015" ( SET GEN="Visual Studio 14 2015") ELSE (SET GEN="Visual Studio 15 2017")
- cmake . -G%GEN% -DCMAKE_CXX_FLAGS="%additional_flags%"
- cmake --build . --config Release
test_script:

View File

@@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.8)
project(JSON_Benchmarks LANGUAGES CXX)
# set compiler flags
if((CMAKE_CXX_COMPILER_ID MATCHES GNU) OR (CMAKE_CXX_COMPILER_ID MATCHES Clang))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -flto -DNDEBUG -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto -DNDEBUG -O3")
endif()
# configure Google Benchmarks
@@ -19,8 +19,10 @@ file(COPY ${CMAKE_SOURCE_DIR}/data DESTINATION .)
file(COPY ${CMAKE_SOURCE_DIR}/../test/data/regression/floats.json
${CMAKE_SOURCE_DIR}/../test/data/regression/unsigned_ints.json
${CMAKE_SOURCE_DIR}/../test/data/regression/signed_ints.json
${CMAKE_SOURCE_DIR}/../test/data/regression/small_signed_ints.json
DESTINATION data/numbers)
# benchmark binary
add_executable(json_benchmarks src/benchmarks.cpp)
target_compile_features(json_benchmarks PRIVATE cxx_std_11)
target_link_libraries(json_benchmarks benchmark ${CMAKE_THREAD_LIBS_INIT})

View File

@@ -28,14 +28,14 @@ static void ParseFile(benchmark::State& state, const char* filename)
std::ifstream file(filename, std::ios::binary | std::ios::ate);
state.SetBytesProcessed(state.iterations() * file.tellg());
}
BENCHMARK_CAPTURE(ParseFile, jeopardy, "data/jeopardy/jeopardy.json");
BENCHMARK_CAPTURE(ParseFile, canada, "data/nativejson-benchmark/canada.json");
BENCHMARK_CAPTURE(ParseFile, citm_catalog, "data/nativejson-benchmark/citm_catalog.json");
BENCHMARK_CAPTURE(ParseFile, twitter, "data/nativejson-benchmark/twitter.json");
BENCHMARK_CAPTURE(ParseFile, floats, "data/numbers/floats.json");
BENCHMARK_CAPTURE(ParseFile, signed_ints, "data/numbers/signed_ints.json");
BENCHMARK_CAPTURE(ParseFile, unsigned_ints, "data/numbers/unsigned_ints.json");
BENCHMARK_CAPTURE(ParseFile, jeopardy, "data/jeopardy/jeopardy.json");
BENCHMARK_CAPTURE(ParseFile, canada, "data/nativejson-benchmark/canada.json");
BENCHMARK_CAPTURE(ParseFile, citm_catalog, "data/nativejson-benchmark/citm_catalog.json");
BENCHMARK_CAPTURE(ParseFile, twitter, "data/nativejson-benchmark/twitter.json");
BENCHMARK_CAPTURE(ParseFile, floats, "data/numbers/floats.json");
BENCHMARK_CAPTURE(ParseFile, signed_ints, "data/numbers/signed_ints.json");
BENCHMARK_CAPTURE(ParseFile, unsigned_ints, "data/numbers/unsigned_ints.json");
BENCHMARK_CAPTURE(ParseFile, small_signed_ints, "data/numbers/small_signed_ints.json");
//////////////////////////////////////////////////////////////////////////////
// parse JSON from string
@@ -61,13 +61,14 @@ static void ParseString(benchmark::State& state, const char* filename)
state.SetBytesProcessed(state.iterations() * str.size());
}
BENCHMARK_CAPTURE(ParseString, jeopardy, "data/jeopardy/jeopardy.json");
BENCHMARK_CAPTURE(ParseString, canada, "data/nativejson-benchmark/canada.json");
BENCHMARK_CAPTURE(ParseString, citm_catalog, "data/nativejson-benchmark/citm_catalog.json");
BENCHMARK_CAPTURE(ParseString, twitter, "data/nativejson-benchmark/twitter.json");
BENCHMARK_CAPTURE(ParseString, floats, "data/numbers/floats.json");
BENCHMARK_CAPTURE(ParseString, signed_ints, "data/numbers/signed_ints.json");
BENCHMARK_CAPTURE(ParseString, unsigned_ints, "data/numbers/unsigned_ints.json");
BENCHMARK_CAPTURE(ParseString, jeopardy, "data/jeopardy/jeopardy.json");
BENCHMARK_CAPTURE(ParseString, canada, "data/nativejson-benchmark/canada.json");
BENCHMARK_CAPTURE(ParseString, citm_catalog, "data/nativejson-benchmark/citm_catalog.json");
BENCHMARK_CAPTURE(ParseString, twitter, "data/nativejson-benchmark/twitter.json");
BENCHMARK_CAPTURE(ParseString, floats, "data/numbers/floats.json");
BENCHMARK_CAPTURE(ParseString, signed_ints, "data/numbers/signed_ints.json");
BENCHMARK_CAPTURE(ParseString, unsigned_ints, "data/numbers/unsigned_ints.json");
BENCHMARK_CAPTURE(ParseString, small_signed_ints, "data/numbers/small_signed_ints.json");
//////////////////////////////////////////////////////////////////////////////
@@ -101,6 +102,8 @@ BENCHMARK_CAPTURE(Dump, signed_ints / -, "data/numbers/signed_ints.json",
BENCHMARK_CAPTURE(Dump, signed_ints / 4, "data/numbers/signed_ints.json", 4);
BENCHMARK_CAPTURE(Dump, unsigned_ints / -, "data/numbers/unsigned_ints.json", -1);
BENCHMARK_CAPTURE(Dump, unsigned_ints / 4, "data/numbers/unsigned_ints.json", 4);
BENCHMARK_CAPTURE(Dump, small_signed_ints / -, "data/numbers/small_signed_ints.json", -1);
BENCHMARK_CAPTURE(Dump, small_signed_ints / 4, "data/numbers/small_signed_ints.json", 4);
BENCHMARK_MAIN();

3
benchmarks/thirdparty/benchmark/AUTHORS vendored Normal file → Executable file
View File

@@ -13,6 +13,7 @@ Arne Beer <arne@twobeer.de>
Carto
Christopher Seymour <chris.j.seymour@hotmail.com>
David Coeurjolly <david.coeurjolly@liris.cnrs.fr>
Deniz Evrenci <denizevrenci@gmail.com>
Dirac Research
Dominik Czarnota <dominik.b.czarnota@gmail.com>
Eric Fiselier <eric@efcs.ca>
@@ -31,6 +32,7 @@ Kishan Kumar <kumar.kishan@outlook.com>
Lei Xu <eddyxu@gmail.com>
Matt Clarkson <mattyclarkson@gmail.com>
Maxim Vafin <maxvafin@gmail.com>
MongoDB Inc.
Nick Hutchinson <nshutchinson@gmail.com>
Oleksandr Sochka <sasha.sochka@gmail.com>
Paul Redmond <paul.redmond@gmail.com>
@@ -38,6 +40,7 @@ Radoslav Yovchev <radoslav.tm@gmail.com>
Roman Lebedev <lebedev.ri@gmail.com>
Shuo Chen <chenshuo@chenshuo.com>
Steinar H. Gunderson <sgunderson@bigfoot.com>
Stripe, Inc.
Yixuan Qiu <yixuanq@gmail.com>
Yusuke Suzuki <utatane.tea@gmail.com>
Zbigniew Skowron <zbychs@gmail.com>

42
benchmarks/thirdparty/benchmark/BUILD.bazel vendored Executable file
View File

@@ -0,0 +1,42 @@
licenses(["notice"])
config_setting(
name = "windows",
values = {
"cpu": "x64_windows",
},
visibility = [":__subpackages__"],
)
cc_library(
name = "benchmark",
srcs = glob(
[
"src/*.cc",
"src/*.h",
],
exclude = ["src/benchmark_main.cc"],
),
hdrs = ["include/benchmark/benchmark.h"],
linkopts = select({
":windows": ["-DEFAULTLIB:shlwapi.lib"],
"//conditions:default": ["-pthread"],
}),
strip_include_prefix = "include",
visibility = ["//visibility:public"],
)
cc_library(
name = "benchmark_main",
srcs = ["src/benchmark_main.cc"],
hdrs = ["include/benchmark/benchmark.h"],
strip_include_prefix = "include",
visibility = ["//visibility:public"],
deps = [":benchmark"],
)
cc_library(
name = "benchmark_internal_headers",
hdrs = glob(["src/*.h"]),
visibility = ["//test:__pkg__"],
)

40
benchmarks/thirdparty/benchmark/CMakeLists.txt vendored Normal file → Executable file
View File

@@ -27,10 +27,48 @@ option(BENCHMARK_DOWNLOAD_DEPENDENCIES "Allow the downloading and in-tree buildi
# in cases where it is not possible to build or find a valid version of gtest.
option(BENCHMARK_ENABLE_GTEST_TESTS "Enable building the unit tests which depend on gtest" ON)
set(ENABLE_ASSEMBLY_TESTS_DEFAULT OFF)
function(should_enable_assembly_tests)
if(CMAKE_BUILD_TYPE)
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
if (${CMAKE_BUILD_TYPE_LOWER} MATCHES "coverage")
# FIXME: The --coverage flag needs to be removed when building assembly
# tests for this to work.
return()
endif()
endif()
if (MSVC)
return()
elseif(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
return()
elseif(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
# FIXME: Make these work on 32 bit builds
return()
elseif(BENCHMARK_BUILD_32_BITS)
# FIXME: Make these work on 32 bit builds
return()
endif()
find_program(LLVM_FILECHECK_EXE FileCheck)
if (LLVM_FILECHECK_EXE)
set(LLVM_FILECHECK_EXE "${LLVM_FILECHECK_EXE}" CACHE PATH "llvm filecheck" FORCE)
message(STATUS "LLVM FileCheck Found: ${LLVM_FILECHECK_EXE}")
else()
message(STATUS "Failed to find LLVM FileCheck")
return()
endif()
set(ENABLE_ASSEMBLY_TESTS_DEFAULT ON PARENT_SCOPE)
endfunction()
should_enable_assembly_tests()
# This option disables the building and running of the assembly verification tests
option(BENCHMARK_ENABLE_ASSEMBLY_TESTS "Enable building and running the assembly tests"
${ENABLE_ASSEMBLY_TESTS_DEFAULT})
# Make sure we can import out CMake functions
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Read the git tags to determine the project version
include(GetGitVersion)
get_git_version(GIT_VERSION)
@@ -178,7 +216,7 @@ if (BENCHMARK_USE_LIBCXX)
# linker flags appear before all linker inputs and -lc++ must appear after.
list(APPEND BENCHMARK_CXX_LIBRARIES c++)
else()
message(FATAL "-DBENCHMARK_USE_LIBCXX:BOOL=ON is not supported for compiler")
message(FATAL_ERROR "-DBENCHMARK_USE_LIBCXX:BOOL=ON is not supported for compiler")
endif()
endif(BENCHMARK_USE_LIBCXX)

View File

@@ -0,0 +1,58 @@
# How to contribute #
We'd love to accept your patches and contributions to this project. There are
a just a few small guidelines you need to follow.
## Contributor License Agreement ##
Contributions to any Google project must be accompanied by a Contributor
License Agreement. This is not a copyright **assignment**, it simply gives
Google permission to use and redistribute your contributions as part of the
project.
* If you are an individual writing original source code and you're sure you
own the intellectual property, then you'll need to sign an [individual
CLA][].
* If you work for a company that wants to allow you to contribute your work,
then you'll need to sign a [corporate CLA][].
You generally only need to submit a CLA once, so if you've already submitted
one (even if it was for a different project), you probably don't need to do it
again.
[individual CLA]: https://developers.google.com/open-source/cla/individual
[corporate CLA]: https://developers.google.com/open-source/cla/corporate
Once your CLA is submitted (or if you already submitted one for
another Google project), make a commit adding yourself to the
[AUTHORS][] and [CONTRIBUTORS][] files. This commit can be part
of your first [pull request][].
[AUTHORS]: AUTHORS
[CONTRIBUTORS]: CONTRIBUTORS
## Submitting a patch ##
1. It's generally best to start by opening a new issue describing the bug or
feature you're intending to fix. Even if you think it's relatively minor,
it's helpful to know what people are working on. Mention in the initial
issue that you are planning to work on that bug or feature so that it can
be assigned to you.
1. Follow the normal process of [forking][] the project, and setup a new
branch to work in. It's important that each group of changes be done in
separate branches in order to ensure that a pull request only includes the
commits related to that bug or feature.
1. Do your best to have [well-formed commit messages][] for each change.
This provides consistency throughout the project, and ensures that commit
messages are able to be formatted properly by various git tools.
1. Finally, push the commits to your fork and submit a [pull request][].
[forking]: https://help.github.com/articles/fork-a-repo
[well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
[pull request]: https://help.github.com/articles/creating-a-pull-request

3
benchmarks/thirdparty/benchmark/CONTRIBUTORS vendored Normal file → Executable file
View File

@@ -28,6 +28,7 @@ Billy Robert O'Neal III <billy.oneal@gmail.com> <bion@microsoft.com>
Chris Kennelly <ckennelly@google.com> <ckennelly@ckennelly.com>
Christopher Seymour <chris.j.seymour@hotmail.com>
David Coeurjolly <david.coeurjolly@liris.cnrs.fr>
Deniz Evrenci <denizevrenci@gmail.com>
Dominic Hamon <dma@stripysock.com> <dominic@google.com>
Dominik Czarnota <dominik.b.czarnota@gmail.com>
Eric Fiselier <eric@efcs.ca>
@@ -38,6 +39,7 @@ Ismael Jimenez Martinez <ismael.jimenez.martinez@gmail.com>
Jern-Kuan Leong <jernkuan@gmail.com>
JianXiong Zhou <zhoujianxiong2@gmail.com>
Joao Paulo Magalhaes <joaoppmagalhaes@gmail.com>
John Millikin <jmillikin@stripe.com>
Jussi Knuuttila <jussi.knuuttila@gmail.com>
Kai Wolf <kai.wolf@gmail.com>
Kishan Kumar <kumar.kishan@outlook.com>
@@ -53,6 +55,7 @@ Pierre Phaneuf <pphaneuf@google.com>
Radoslav Yovchev <radoslav.tm@gmail.com>
Raul Marin <rmrodriguez@cartodb.com>
Ray Glover <ray.glover@uk.ibm.com>
Robert Guo <robert.guo@mongodb.com>
Roman Lebedev <lebedev.ri@gmail.com>
Shuo Chen <chenshuo@chenshuo.com>
Tobias Ulvgård <tobias.ulvgard@dirac.se>

0
benchmarks/thirdparty/benchmark/LICENSE vendored Normal file → Executable file
View File

39
benchmarks/thirdparty/benchmark/README.md vendored Normal file → Executable file
View File

@@ -14,6 +14,8 @@ IRC channel: https://freenode.net #googlebenchmark
[Additional Tooling Documentation](docs/tools.md)
[Assembly Testing Documentation](docs/AssemblyTests.md)
## Building
@@ -21,7 +23,7 @@ The basic steps for configuring and building the library look like this:
```bash
$ git clone https://github.com/google/benchmark.git
# Benchmark requires GTest as a dependency. Add the source tree as a subdirectory.
# Benchmark requires Google Test as a dependency. Add the source tree as a subdirectory.
$ git clone https://github.com/google/googletest.git benchmark/googletest
$ mkdir build && cd build
$ cmake -G <generator> [options] ../benchmark
@@ -29,15 +31,13 @@ $ cmake -G <generator> [options] ../benchmark
$ make
```
Note that Google Benchmark requires GTest to build and run the tests. This
dependency can be provided three ways:
Note that Google Benchmark requires Google Test to build and run the tests. This
dependency can be provided two ways:
* Checkout the GTest sources into `benchmark/googletest`.
* Checkout the Google Test sources into `benchmark/googletest` as above.
* Otherwise, if `-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON` is specified during
configuration, the library will automatically download and build any required
dependencies.
* Otherwise, if nothing is done, CMake will use `find_package(GTest REQUIRED)`
to resolve the required GTest dependency.
If you do not wish to build and run the tests, add `-DBENCHMARK_ENABLE_GTEST_TESTS=OFF`
to `CMAKE_ARGS`.
@@ -59,6 +59,7 @@ Now, let's clone the repository and build it
```
git clone https://github.com/google/benchmark.git
cd benchmark
git clone https://github.com/google/googletest.git
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=RELEASE
@@ -71,7 +72,7 @@ We need to install the library globally now
sudo make install
```
Now you have google/benchmark installed in your machine
Now you have google/benchmark installed in your machine
Note: Don't forget to link to pthread library while building
## Stable and Experimental Library Versions
@@ -86,6 +87,11 @@ to use, test, and provide feedback on the new features are encouraged to try
this branch. However, this branch provides no stability guarantees and reserves
the right to change and break the API at any time.
##Prerequisite knowledge
Before attempting to understand this framework one should ideally have some familiarity with the structure and format of the Google Test framework, upon which it is based. Documentation for Google Test, including a "Getting Started" (primer) guide, is available here:
https://github.com/google/googletest/blob/master/googletest/docs/Documentation.md
## Example usage
### Basic usage
@@ -112,7 +118,10 @@ BENCHMARK(BM_StringCopy);
BENCHMARK_MAIN();
```
Don't forget to inform your linker to add benchmark library e.g. through `-lbenchmark` compilation flag.
Don't forget to inform your linker to add benchmark library e.g. through
`-lbenchmark` compilation flag. Alternatively, you may leave out the
`BENCHMARK_MAIN();` at the end of the source file and link against
`-lbenchmark_main` to get the same default behavior.
The benchmark library will reporting the timing for the code within the `for(...)` loop.
@@ -821,7 +830,7 @@ BM_SetInsert/1024/10 33157 33648 21431 1.13369M
The JSON format outputs human readable json split into two top level attributes.
The `context` attribute contains information about the run in general, including
information about the CPU and the date.
The `benchmarks` attribute contains a list of ever benchmark run. Example json
The `benchmarks` attribute contains a list of every benchmark run. Example json
output looks like:
```json
{
@@ -893,8 +902,11 @@ If you are using gcc, you might need to set `GCC_AR` and `GCC_RANLIB` cmake cach
If you are using clang, you may need to set `LLVMAR_EXECUTABLE`, `LLVMNM_EXECUTABLE` and `LLVMRANLIB_EXECUTABLE` cmake cache variables.
## Linking against the library
When using gcc, it is necessary to link against pthread to avoid runtime exceptions.
This is due to how gcc implements std::thread.
When the library is built using GCC it is necessary to link with `-pthread`,
due to how GCC implements `std::thread`.
For GCC 4.x failing to link to pthreads will lead to runtime exceptions, not linker errors.
See [issue #67](https://github.com/google/benchmark/issues/67) for more details.
## Compiler Support
@@ -928,8 +940,11 @@ sudo cpupower frequency-set --governor powersave
# Known Issues
### Windows
### Windows with CMake
* Users must manually link `shlwapi.lib`. Failure to do so may result
in unresolved symbols.
### Solaris
* Users must explicitly link with kstat library (-lkstat compilation flag).

7
benchmarks/thirdparty/benchmark/WORKSPACE vendored Executable file
View File

@@ -0,0 +1,7 @@
workspace(name = "com_github_google_benchmark")
http_archive(
name = "com_google_googletest",
urls = ["https://github.com/google/googletest/archive/3f0cf6b62ad1eb50d8736538363d3580dd640c3e.zip"],
strip_prefix = "googletest-3f0cf6b62ad1eb50d8736538363d3580dd640c3e",
)

56
benchmarks/thirdparty/benchmark/appveyor.yml vendored Executable file
View File

@@ -0,0 +1,56 @@
version: '{build}'
image: Visual Studio 2017
configuration:
- Debug
- Release
environment:
matrix:
- compiler: msvc-15-seh
generator: "Visual Studio 15 2017"
- compiler: msvc-15-seh
generator: "Visual Studio 15 2017 Win64"
- compiler: msvc-14-seh
generator: "Visual Studio 14 2015"
- compiler: msvc-14-seh
generator: "Visual Studio 14 2015 Win64"
- compiler: msvc-12-seh
generator: "Visual Studio 12 2013"
- compiler: msvc-12-seh
generator: "Visual Studio 12 2013 Win64"
- compiler: gcc-5.3.0-posix
generator: "MinGW Makefiles"
cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin'
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
matrix:
fast_finish: true
install:
# git bash conflicts with MinGW makefiles
- if "%generator%"=="MinGW Makefiles" (set "PATH=%PATH:C:\Program Files\Git\usr\bin;=%")
- if not "%cxx_path%"=="" (set "PATH=%PATH%;%cxx_path%")
build_script:
- md _build -Force
- cd _build
- echo %configuration%
- cmake -G "%generator%" "-DCMAKE_BUILD_TYPE=%configuration%" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON ..
- cmake --build . --config %configuration%
test_script:
- ctest -c %configuration% --timeout 300 --output-on-failure
artifacts:
- path: '_build/CMakeFiles/*.log'
name: logs
- path: '_build/Testing/**/*.xml'
name: test_results

10
benchmarks/thirdparty/benchmark/cmake/AddCXXCompilerFlag.cmake vendored Normal file → Executable file
View File

@@ -62,3 +62,13 @@ function(add_required_cxx_compiler_flag FLAG)
message(FATAL_ERROR "Required flag '${FLAG}' is not supported by the compiler")
endif()
endfunction()
function(check_cxx_warning_flag FLAG)
mangle_compiler_flag("${FLAG}" MANGLED_FLAG)
set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
# Add -Werror to ensure the compiler generates an error if the warning flag
# doesn't exist.
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror ${FLAG}")
check_cxx_compiler_flag("${FLAG}" ${MANGLED_FLAG})
set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
endfunction()

38
benchmarks/thirdparty/benchmark/cmake/CXXFeatureCheck.cmake vendored Normal file → Executable file
View File

@@ -27,25 +27,27 @@ function(cxx_feature_check FILE)
return()
endif()
message("-- Performing Test ${FEATURE}")
if(CMAKE_CROSSCOMPILING)
try_compile(COMPILE_${FEATURE}
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}
LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES})
if(COMPILE_${FEATURE})
message(WARNING
"If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0")
set(RUN_${FEATURE} 0)
else()
set(RUN_${FEATURE} 1)
endif()
else()
if (NOT DEFINED COMPILE_${FEATURE})
message("-- Performing Test ${FEATURE}")
try_run(RUN_${FEATURE} COMPILE_${FEATURE}
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}
LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES})
if(CMAKE_CROSSCOMPILING)
try_compile(COMPILE_${FEATURE}
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}
LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES})
if(COMPILE_${FEATURE})
message(WARNING
"If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0")
set(RUN_${FEATURE} 0)
else()
set(RUN_${FEATURE} 1)
endif()
else()
message("-- Performing Test ${FEATURE}")
try_run(RUN_${FEATURE} COMPILE_${FEATURE}
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}
LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES})
endif()
endif()
if(RUN_${FEATURE} EQUAL 0)

0
benchmarks/thirdparty/benchmark/cmake/Config.cmake.in vendored Normal file → Executable file
View File

3
benchmarks/thirdparty/benchmark/cmake/GetGitVersion.cmake vendored Normal file → Executable file
View File

@@ -21,6 +21,7 @@ set(__get_git_version INCLUDED)
function(get_git_version var)
if(GIT_EXECUTABLE)
execute_process(COMMAND ${GIT_EXECUTABLE} describe --match "v[0-9]*.[0-9]*.[0-9]*" --abbrev=8
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE status
OUTPUT_VARIABLE GIT_VERSION
ERROR_QUIET)
@@ -33,9 +34,11 @@ function(get_git_version var)
# Work out if the repository is dirty
execute_process(COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_QUIET
ERROR_QUIET)
execute_process(COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_DIFF_INDEX
ERROR_QUIET)
string(COMPARE NOTEQUAL "${GIT_DIFF_INDEX}" "" GIT_DIRTY)

78
benchmarks/thirdparty/benchmark/cmake/HandleGTest.cmake vendored Normal file → Executable file
View File

@@ -1,7 +1,5 @@
macro(split_list listname)
string(REPLACE ";" " " ${listname} "${${listname}}")
endmacro()
include(split_list)
macro(build_external_gtest)
include(ExternalProject)
@@ -23,9 +21,22 @@ macro(build_external_gtest)
if ("${GTEST_BUILD_TYPE}" STREQUAL "COVERAGE")
set(GTEST_BUILD_TYPE "DEBUG")
endif()
# FIXME: Since 10/Feb/2017 the googletest trunk has had a bug where
# -Werror=unused-function fires during the build on OS X. This is a temporary
# workaround to keep our travis bots from failing. It should be removed
# once gtest is fixed.
if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
list(APPEND GTEST_FLAGS "-Wno-unused-function")
endif()
split_list(GTEST_FLAGS)
set(EXCLUDE_FROM_ALL_OPT "")
set(EXCLUDE_FROM_ALL_VALUE "")
if (${CMAKE_VERSION} VERSION_GREATER "3.0.99")
set(EXCLUDE_FROM_ALL_OPT "EXCLUDE_FROM_ALL")
set(EXCLUDE_FROM_ALL_VALUE "ON")
endif()
ExternalProject_Add(googletest
EXCLUDE_FROM_ALL ON
${EXCLUDE_FROM_ALL_OPT} ${EXCLUDE_FROM_ALL_VALUE}
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
PREFIX "${CMAKE_BINARY_DIR}/googletest"
@@ -35,45 +46,68 @@ macro(build_external_gtest)
-DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DCMAKE_INSTALL_LIBDIR:PATH=<INSTALL_DIR>/lib
-DCMAKE_CXX_FLAGS:STRING=${GTEST_FLAGS}
-Dgtest_force_shared_crt:BOOL=ON
)
ExternalProject_Get_Property(googletest install_dir)
add_library(gtest UNKNOWN IMPORTED)
add_library(gtest_main UNKNOWN IMPORTED)
set(GTEST_INCLUDE_DIRS ${install_dir}/include)
file(MAKE_DIRECTORY ${GTEST_INCLUDE_DIRS})
set(LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(LIB_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
if("${GTEST_BUILD_TYPE}" STREQUAL "DEBUG")
set(LIB_SUFFIX "d${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif()
file(MAKE_DIRECTORY ${install_dir}/include)
set_target_properties(gtest PROPERTIES
IMPORTED_LOCATION ${install_dir}/lib/${LIB_PREFIX}gtest${LIB_SUFFIX}
INTERFACE_INCLUDE_DIRECTORIES ${install_dir}/include
)
set_target_properties(gtest_main PROPERTIES
IMPORTED_LOCATION ${install_dir}/lib/${LIB_PREFIX}gtest_main${LIB_SUFFIX}
INTERFACE_INCLUDE_DIRECTORIES ${install_dir}/include
)
add_dependencies(gtest googletest)
add_dependencies(gtest_main googletest)
set(GTEST_BOTH_LIBRARIES gtest gtest_main)
#set(GTEST_INCLUDE_DIRS ${install_dir}/include)
# Use gmock_main instead of gtest_main because it initializes gtest as well.
# Note: The libraries are listed in reverse order of their dependancies.
foreach(LIB gtest gmock gmock_main)
add_library(${LIB} UNKNOWN IMPORTED)
set_target_properties(${LIB} PROPERTIES
IMPORTED_LOCATION ${install_dir}/lib/${LIB_PREFIX}${LIB}${LIB_SUFFIX}
INTERFACE_INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIRS}
INTERFACE_LINK_LIBRARIES "${GTEST_BOTH_LIBRARIES}"
)
add_dependencies(${LIB} googletest)
list(APPEND GTEST_BOTH_LIBRARIES ${LIB})
endforeach()
endmacro(build_external_gtest)
if (BENCHMARK_ENABLE_GTEST_TESTS)
if (IS_DIRECTORY ${CMAKE_SOURCE_DIR}/googletest)
set(GTEST_ROOT "${CMAKE_SOURCE_DIR}/googletest")
set(INSTALL_GTEST OFF CACHE INTERNAL "")
set(INSTALL_GMOCK OFF CACHE INTERNAL "")
add_subdirectory(${CMAKE_SOURCE_DIR}/googletest)
set(GTEST_BOTH_LIBRARIES gtest gtest_main)
set(GTEST_BOTH_LIBRARIES gtest gmock gmock_main)
foreach(HEADER test mock)
# CMake 2.8 and older don't respect INTERFACE_INCLUDE_DIRECTORIES, so we
# have to add the paths ourselves.
set(HFILE g${HEADER}/g${HEADER}.h)
set(HPATH ${GTEST_ROOT}/google${HEADER}/include)
find_path(HEADER_PATH_${HEADER} ${HFILE}
NO_DEFAULT_PATHS
HINTS ${HPATH}
)
if (NOT HEADER_PATH_${HEADER})
message(FATAL_ERROR "Failed to find header ${HFILE} in ${HPATH}")
endif()
list(APPEND GTEST_INCLUDE_DIRS ${HEADER_PATH_${HEADER}})
endforeach()
elseif(BENCHMARK_DOWNLOAD_DEPENDENCIES)
build_external_gtest()
else()
find_package(GTest REQUIRED)
find_path(GMOCK_INCLUDE_DIRS gmock/gmock.h
HINTS ${GTEST_INCLUDE_DIRS})
if (NOT GMOCK_INCLUDE_DIRS)
message(FATAL_ERROR "Failed to find header gmock/gmock.h with hint ${GTEST_INCLUDE_DIRS}")
endif()
set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS})
# FIXME: We don't currently require the gmock library to build the tests,
# and it's likely we won't find it, so we don't try. As long as we've
# found the gmock/gmock.h header and gtest_main that should be good enough.
endif()
endif()

0
benchmarks/thirdparty/benchmark/cmake/Modules/FindLLVMAr.cmake vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/cmake/Modules/FindLLVMNm.cmake vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/cmake/Modules/FindLLVMRanLib.cmake vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/cmake/benchmark.pc.in vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/cmake/gnu_posix_regex.cpp vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/cmake/llvm-toolchain.cmake vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/cmake/posix_regex.cpp vendored Normal file → Executable file
View File

View File

@@ -0,0 +1,3 @@
macro(split_list listname)
string(REPLACE ";" " " ${listname} "${${listname}}")
endmacro()

0
benchmarks/thirdparty/benchmark/cmake/std_regex.cpp vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/cmake/steady_clock.cpp vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/cmake/thread_safety_attributes.cpp vendored Normal file → Executable file
View File

View File

@@ -0,0 +1,147 @@
# Assembly Tests
The Benchmark library provides a number of functions whose primary
purpose in to affect assembly generation, including `DoNotOptimize`
and `ClobberMemory`. In addition there are other functions,
such as `KeepRunning`, for which generating good assembly is paramount.
For these functions it's important to have tests that verify the
correctness and quality of the implementation. This requires testing
the code generated by the compiler.
This document describes how the Benchmark library tests compiler output,
as well as how to properly write new tests.
## Anatomy of a Test
Writing a test has two steps:
* Write the code you want to generate assembly for.
* Add `// CHECK` lines to match against the verified assembly.
Example:
```c++
// CHECK-LABEL: test_add:
extern "C" int test_add() {
extern int ExternInt;
return ExternInt + 1;
// CHECK: movl ExternInt(%rip), %eax
// CHECK: addl %eax
// CHECK: ret
}
```
#### LLVM Filecheck
[LLVM's Filecheck](https://llvm.org/docs/CommandGuide/FileCheck.html)
is used to test the generated assembly against the `// CHECK` lines
specified in the tests source file. Please see the documentation
linked above for information on how to write `CHECK` directives.
#### Tips and Tricks:
* Tests should match the minimal amount of output required to establish
correctness. `CHECK` directives don't have to match on the exact next line
after the previous match, so tests should omit checks for unimportant
bits of assembly. ([`CHECK-NEXT`](https://llvm.org/docs/CommandGuide/FileCheck.html#the-check-next-directive)
can be used to ensure a match occurs exactly after the previous match).
* The tests are compiled with `-O3 -g0`. So we're only testing the
optimized output.
* The assembly output is further cleaned up using `tools/strip_asm.py`.
This removes comments, assembler directives, and unused labels before
the test is run.
* The generated and stripped assembly file for a test is output under
`<build-directory>/test/<test-name>.s`
* Filecheck supports using [`CHECK` prefixes](https://llvm.org/docs/CommandGuide/FileCheck.html#cmdoption-check-prefixes)
to specify lines that should only match in certain situations.
The Benchmark tests use `CHECK-CLANG` and `CHECK-GNU` for lines that
are only expected to match Clang or GCC's output respectively. Normal
`CHECK` lines match against all compilers. (Note: `CHECK-NOT` and
`CHECK-LABEL` are NOT prefixes. They are versions of non-prefixed
`CHECK` lines)
* Use `extern "C"` to disable name mangling for specific functions. This
makes them easier to name in the `CHECK` lines.
## Problems Writing Portable Tests
Writing tests which check the code generated by a compiler are
inherently non-portable. Different compilers and even different compiler
versions may generate entirely different code. The Benchmark tests
must tolerate this.
LLVM Filecheck provides a number of mechanisms to help write
"more portable" tests; including [matching using regular expressions](https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-pattern-matching-syntax),
allowing the creation of [named variables](https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-variables)
for later matching, and [checking non-sequential matches](https://llvm.org/docs/CommandGuide/FileCheck.html#the-check-dag-directive).
#### Capturing Variables
For example, say GCC stores a variable in a register but Clang stores
it in memory. To write a test that tolerates both cases we "capture"
the destination of the store, and then use the captured expression
to write the remainder of the test.
```c++
// CHECK-LABEL: test_div_no_op_into_shr:
extern "C" void test_div_no_op_into_shr(int value) {
int divisor = 2;
benchmark::DoNotOptimize(divisor); // hide the value from the optimizer
return value / divisor;
// CHECK: movl $2, [[DEST:.*]]
// CHECK: idivl [[DEST]]
// CHECK: ret
}
```
#### Using Regular Expressions to Match Differing Output
Often tests require testing assembly lines which may subtly differ
between compilers or compiler versions. A common example of this
is matching stack frame addresses. In this case regular expressions
can be used to match the differing bits of output. For example:
```c++
int ExternInt;
struct Point { int x, y, z; };
// CHECK-LABEL: test_store_point:
extern "C" void test_store_point() {
Point p{ExternInt, ExternInt, ExternInt};
benchmark::DoNotOptimize(p);
// CHECK: movl ExternInt(%rip), %eax
// CHECK: movl %eax, -{{[0-9]+}}(%rsp)
// CHECK: movl %eax, -{{[0-9]+}}(%rsp)
// CHECK: movl %eax, -{{[0-9]+}}(%rsp)
// CHECK: ret
}
```
## Current Requirements and Limitations
The tests require Filecheck to be installed along the `PATH` of the
build machine. Otherwise the tests will be disabled.
Additionally, as mentioned in the previous section, codegen tests are
inherently non-portable. Currently the tests are limited to:
* x86_64 targets.
* Compiled with GCC or Clang
Further work could be done, at least on a limited basis, to extend the
tests to other architectures and compilers (using `CHECK` prefixes).
Furthermore, the tests fail for builds which specify additional flags
that modify code generation, including `--coverage` or `-fsanitize=`.

242
benchmarks/thirdparty/benchmark/docs/tools.md vendored Executable file
View File

@@ -0,0 +1,242 @@
# Benchmark Tools
## compare_bench.py
The `compare_bench.py` utility which can be used to compare the result of benchmarks.
The program is invoked like:
``` bash
$ compare_bench.py <old-benchmark> <new-benchmark> [benchmark options]...
```
Where `<old-benchmark>` and `<new-benchmark>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
The sample output using the JSON test files under `Inputs/` gives:
``` bash
$ ./compare_bench.py ./gbench/Inputs/test1_run1.json ./gbench/Inputs/test1_run2.json
Comparing ./gbench/Inputs/test1_run1.json to ./gbench/Inputs/test1_run2.json
Benchmark Time CPU Time Old Time New CPU Old CPU New
-------------------------------------------------------------------------------------------------------------
BM_SameTimes +0.0000 +0.0000 10 10 10 10
BM_2xFaster -0.5000 -0.5000 50 25 50 25
BM_2xSlower +1.0000 +1.0000 50 100 50 100
BM_1PercentFaster -0.0100 -0.0100 100 99 100 99
BM_1PercentSlower +0.0100 +0.0100 100 101 100 101
BM_10PercentFaster -0.1000 -0.1000 100 90 100 90
BM_10PercentSlower +0.1000 +0.1000 100 110 100 110
BM_100xSlower +99.0000 +99.0000 100 10000 100 10000
BM_100xFaster -0.9900 -0.9900 10000 100 10000 100
BM_10PercentCPUToTime +0.1000 -0.1000 100 110 100 90
BM_ThirdFaster -0.3333 -0.3334 100 67 100 67
BM_BadTimeUnit -0.9000 +0.2000 0 0 0 1
```
As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
When a benchmark executable is run, the raw output from the benchmark is printed in real time to stdout. The sample output using `benchmark/basic_test` for both arguments looks like:
```
./compare_bench.py test/basic_test test/basic_test --benchmark_filter=BM_empty.*
RUNNING: test/basic_test --benchmark_filter=BM_empty.* --benchmark_out=/tmp/tmpN7LF3a
Run on (8 X 4000 MHz CPU s)
2017-11-07 23:28:36
---------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------
BM_empty 4 ns 4 ns 170178757
BM_empty/threads:8 1 ns 7 ns 103868920
BM_empty_stop_start 0 ns 0 ns 1000000000
BM_empty_stop_start/threads:8 0 ns 0 ns 1403031720
RUNNING: /test/basic_test --benchmark_filter=BM_empty.* --benchmark_out=/tmp/tmplvrIp8
Run on (8 X 4000 MHz CPU s)
2017-11-07 23:28:38
---------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------
BM_empty 4 ns 4 ns 169534855
BM_empty/threads:8 1 ns 7 ns 104188776
BM_empty_stop_start 0 ns 0 ns 1000000000
BM_empty_stop_start/threads:8 0 ns 0 ns 1404159424
Comparing ../build/test/basic_test to ../build/test/basic_test
Benchmark Time CPU Time Old Time New CPU Old CPU New
---------------------------------------------------------------------------------------------------------------------
BM_empty -0.0048 -0.0049 4 4 4 4
BM_empty/threads:8 -0.0123 -0.0054 1 1 7 7
BM_empty_stop_start -0.0000 -0.0000 0 0 0 0
BM_empty_stop_start/threads:8 -0.0029 +0.0001 0 0 0 0
```
As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
Obviously this example doesn't give any useful output, but it's intended to show the output format when 'compare_bench.py' needs to run benchmarks.
## compare.py
The `compare.py` can be used to compare the result of benchmarks.
There are three modes of operation:
1. Just compare two benchmarks, what `compare_bench.py` did.
The program is invoked like:
``` bash
$ compare.py benchmarks <benchmark_baseline> <benchmark_contender> [benchmark options]...
```
Where `<benchmark_baseline>` and `<benchmark_contender>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
Example output:
```
$ ./compare.py benchmarks ./a.out ./a.out
RUNNING: ./a.out --benchmark_out=/tmp/tmprBT5nW
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:16:44
------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------
BM_memcpy/8 36 ns 36 ns 19101577 211.669MB/s
BM_memcpy/64 76 ns 76 ns 9412571 800.199MB/s
BM_memcpy/512 84 ns 84 ns 8249070 5.64771GB/s
BM_memcpy/1024 116 ns 116 ns 6181763 8.19505GB/s
BM_memcpy/8192 643 ns 643 ns 1062855 11.8636GB/s
BM_copy/8 222 ns 222 ns 3137987 34.3772MB/s
BM_copy/64 1608 ns 1608 ns 432758 37.9501MB/s
BM_copy/512 12589 ns 12589 ns 54806 38.7867MB/s
BM_copy/1024 25169 ns 25169 ns 27713 38.8003MB/s
BM_copy/8192 201165 ns 201112 ns 3486 38.8466MB/s
RUNNING: ./a.out --benchmark_out=/tmp/tmpt1wwG_
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:16:53
------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------
BM_memcpy/8 36 ns 36 ns 19397903 211.255MB/s
BM_memcpy/64 73 ns 73 ns 9691174 839.635MB/s
BM_memcpy/512 85 ns 85 ns 8312329 5.60101GB/s
BM_memcpy/1024 118 ns 118 ns 6438774 8.11608GB/s
BM_memcpy/8192 656 ns 656 ns 1068644 11.6277GB/s
BM_copy/8 223 ns 223 ns 3146977 34.2338MB/s
BM_copy/64 1611 ns 1611 ns 435340 37.8751MB/s
BM_copy/512 12622 ns 12622 ns 54818 38.6844MB/s
BM_copy/1024 25257 ns 25239 ns 27779 38.6927MB/s
BM_copy/8192 205013 ns 205010 ns 3479 38.108MB/s
Comparing ./a.out to ./a.out
Benchmark Time CPU Time Old Time New CPU Old CPU New
------------------------------------------------------------------------------------------------------
BM_memcpy/8 +0.0020 +0.0020 36 36 36 36
BM_memcpy/64 -0.0468 -0.0470 76 73 76 73
BM_memcpy/512 +0.0081 +0.0083 84 85 84 85
BM_memcpy/1024 +0.0098 +0.0097 116 118 116 118
BM_memcpy/8192 +0.0200 +0.0203 643 656 643 656
BM_copy/8 +0.0046 +0.0042 222 223 222 223
BM_copy/64 +0.0020 +0.0020 1608 1611 1608 1611
BM_copy/512 +0.0027 +0.0026 12589 12622 12589 12622
BM_copy/1024 +0.0035 +0.0028 25169 25257 25169 25239
BM_copy/8192 +0.0191 +0.0194 201165 205013 201112 205010
```
What it does is for the every benchmark from the first run it looks for the benchmark with exactly the same name in the second run, and then compares the results. If the names differ, the benchmark is omitted from the diff.
As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
2. Compare two different filters of one benchmark
The program is invoked like:
``` bash
$ compare.py filters <benchmark> <filter_baseline> <filter_contender> [benchmark options]...
```
Where `<benchmark>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
Where `<filter_baseline>` and `<filter_contender>` are the same regex filters that you would pass to the `[--benchmark_filter=<regex>]` parameter of the benchmark binary.
`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
Example output:
```
$ ./compare.py filters ./a.out BM_memcpy BM_copy
RUNNING: ./a.out --benchmark_filter=BM_memcpy --benchmark_out=/tmp/tmpBWKk0k
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:37:28
------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------
BM_memcpy/8 36 ns 36 ns 17891491 211.215MB/s
BM_memcpy/64 74 ns 74 ns 9400999 825.646MB/s
BM_memcpy/512 87 ns 87 ns 8027453 5.46126GB/s
BM_memcpy/1024 111 ns 111 ns 6116853 8.5648GB/s
BM_memcpy/8192 657 ns 656 ns 1064679 11.6247GB/s
RUNNING: ./a.out --benchmark_filter=BM_copy --benchmark_out=/tmp/tmpAvWcOM
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:37:33
----------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------
BM_copy/8 227 ns 227 ns 3038700 33.6264MB/s
BM_copy/64 1640 ns 1640 ns 426893 37.2154MB/s
BM_copy/512 12804 ns 12801 ns 55417 38.1444MB/s
BM_copy/1024 25409 ns 25407 ns 27516 38.4365MB/s
BM_copy/8192 202986 ns 202990 ns 3454 38.4871MB/s
Comparing BM_memcpy to BM_copy (from ./a.out)
Benchmark Time CPU Time Old Time New CPU Old CPU New
--------------------------------------------------------------------------------------------------------------------
[BM_memcpy vs. BM_copy]/8 +5.2829 +5.2812 36 227 36 227
[BM_memcpy vs. BM_copy]/64 +21.1719 +21.1856 74 1640 74 1640
[BM_memcpy vs. BM_copy]/512 +145.6487 +145.6097 87 12804 87 12801
[BM_memcpy vs. BM_copy]/1024 +227.1860 +227.1776 111 25409 111 25407
[BM_memcpy vs. BM_copy]/8192 +308.1664 +308.2898 657 202986 656 202990
```
As you can see, it applies filter to the benchmarks, both when running the benchmark, and before doing the diff. And to make the diff work, the matches are replaced with some common string. Thus, you can compare two different benchmark families within one benchmark binary.
As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
3. Compare filter one from benchmark one to filter two from benchmark two:
The program is invoked like:
``` bash
$ compare.py filters <benchmark_baseline> <filter_baseline> <benchmark_contender> <filter_contender> [benchmark options]...
```
Where `<benchmark_baseline>` and `<benchmark_contender>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
Where `<filter_baseline>` and `<filter_contender>` are the same regex filters that you would pass to the `[--benchmark_filter=<regex>]` parameter of the benchmark binary.
`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
Example output:
```
$ ./compare.py benchmarksfiltered ./a.out BM_memcpy ./a.out BM_copy
RUNNING: ./a.out --benchmark_filter=BM_memcpy --benchmark_out=/tmp/tmp_FvbYg
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:38:27
------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------
BM_memcpy/8 37 ns 37 ns 18953482 204.118MB/s
BM_memcpy/64 74 ns 74 ns 9206578 828.245MB/s
BM_memcpy/512 91 ns 91 ns 8086195 5.25476GB/s
BM_memcpy/1024 120 ns 120 ns 5804513 7.95662GB/s
BM_memcpy/8192 664 ns 664 ns 1028363 11.4948GB/s
RUNNING: ./a.out --benchmark_filter=BM_copy --benchmark_out=/tmp/tmpDfL5iE
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:38:32
----------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------
BM_copy/8 230 ns 230 ns 2985909 33.1161MB/s
BM_copy/64 1654 ns 1653 ns 419408 36.9137MB/s
BM_copy/512 13122 ns 13120 ns 53403 37.2156MB/s
BM_copy/1024 26679 ns 26666 ns 26575 36.6218MB/s
BM_copy/8192 215068 ns 215053 ns 3221 36.3283MB/s
Comparing BM_memcpy (from ./a.out) to BM_copy (from ./a.out)
Benchmark Time CPU Time Old Time New CPU Old CPU New
--------------------------------------------------------------------------------------------------------------------
[BM_memcpy vs. BM_copy]/8 +5.1649 +5.1637 37 230 37 230
[BM_memcpy vs. BM_copy]/64 +21.4352 +21.4374 74 1654 74 1653
[BM_memcpy vs. BM_copy]/512 +143.6022 +143.5865 91 13122 91 13120
[BM_memcpy vs. BM_copy]/1024 +221.5903 +221.4790 120 26679 120 26666
[BM_memcpy vs. BM_copy]/8192 +322.9059 +323.0096 664 215068 664 215053
```
This is a mix of the previous two modes, two (potentially different) benchmark binaries are run, and a different filter is applied to each one.
As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.

171
benchmarks/thirdparty/benchmark/include/benchmark/benchmark.h vendored Normal file → Executable file
View File

@@ -172,6 +172,7 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
#include <stdint.h>
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iosfwd>
@@ -291,7 +292,7 @@ BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
defined(EMSCRIPTN)
defined(__EMSCRIPTEN__)
# define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
#endif
@@ -302,15 +303,20 @@ BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
// See: https://youtu.be/nXaxk27zwlk?t=2441
#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
// Clang doesn't like the 'X' constraint on `value` and certain GCC versions
// don't like the 'g' constraint. Attempt to placate them both.
inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
asm volatile("" : : "r,m"(value) : "memory");
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
#if defined(__clang__)
asm volatile("" : : "g"(value) : "memory");
asm volatile("" : "+r,m"(value) : : "memory");
#else
asm volatile("" : : "i,r,m"(value) : "memory");
asm volatile("" : "+m,r"(value) : : "memory");
#endif
}
// Force the compiler to flush pending writes to global memory. Acts as an
// effective read/write barrier
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
@@ -379,7 +385,7 @@ enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
// BigOFunc is passed to a benchmark in order to specify the asymptotic
// computational complexity for the benchmark.
typedef double(BigOFunc)(int);
typedef double(BigOFunc)(int64_t);
// StatisticsFunc is passed to a benchmark in order to compute some descriptive
// statistics over all the measurements of some type
@@ -429,16 +435,19 @@ class State {
// Returns true if the benchmark should continue through another iteration.
// NOTE: A benchmark may not return from the test until KeepRunning() has
// returned false.
bool KeepRunning() {
if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
StartKeepRunning();
}
bool const res = (--total_iterations_ != 0);
if (BENCHMARK_BUILTIN_EXPECT(!res, false)) {
FinishKeepRunning();
}
return res;
}
bool KeepRunning();
// Returns true iff the benchmark should run n more iterations.
// REQUIRES: 'n' > 0.
// NOTE: A benchmark must not return from the test until KeepRunningBatch()
// has returned false.
// NOTE: KeepRunningBatch() may overshoot by up to 'n' iterations.
//
// Intended usage:
// while (state.KeepRunningBatch(1000)) {
// // process 1000 elements
// }
bool KeepRunningBatch(size_t n);
// REQUIRES: timer is running and 'SkipWithError(...)' has not been called
// by the current thread.
@@ -505,10 +514,10 @@ class State {
//
// REQUIRES: a benchmark has exited its benchmarking loop.
BENCHMARK_ALWAYS_INLINE
void SetBytesProcessed(size_t bytes) { bytes_processed_ = bytes; }
void SetBytesProcessed(int64_t bytes) { bytes_processed_ = bytes; }
BENCHMARK_ALWAYS_INLINE
size_t bytes_processed() const { return bytes_processed_; }
int64_t bytes_processed() const { return bytes_processed_; }
// If this routine is called with complexity_n > 0 and complexity report is
// requested for the
@@ -516,10 +525,10 @@ class State {
// and complexity_n will
// represent the length of N.
BENCHMARK_ALWAYS_INLINE
void SetComplexityN(int complexity_n) { complexity_n_ = complexity_n; }
void SetComplexityN(int64_t complexity_n) { complexity_n_ = complexity_n; }
BENCHMARK_ALWAYS_INLINE
int complexity_length_n() { return complexity_n_; }
int64_t complexity_length_n() { return complexity_n_; }
// If this routine is called with items > 0, then an items/s
// label is printed on the benchmark report line for the currently
@@ -528,10 +537,10 @@ class State {
//
// REQUIRES: a benchmark has exited its benchmarking loop.
BENCHMARK_ALWAYS_INLINE
void SetItemsProcessed(size_t items) { items_processed_ = items; }
void SetItemsProcessed(int64_t items) { items_processed_ = items; }
BENCHMARK_ALWAYS_INLINE
size_t items_processed() const { return items_processed_; }
int64_t items_processed() const { return items_processed_; }
// If this routine is called, the specified label is printed at the
// end of the benchmark report line for the currently executing
@@ -539,7 +548,7 @@ class State {
// static void BM_Compress(benchmark::State& state) {
// ...
// double compress = input_size / output_size;
// state.SetLabel(StringPrintf("compress:%.1f%%", 100.0*compression));
// state.SetLabel(StrFormat("compress:%.1f%%", 100.0*compression));
// }
// Produces output that looks like:
// BM_Compress 50 50 14115038 compress:27.3%
@@ -553,34 +562,52 @@ class State {
// Range arguments for this run. CHECKs if the argument has been set.
BENCHMARK_ALWAYS_INLINE
int range(std::size_t pos = 0) const {
int64_t range(std::size_t pos = 0) const {
assert(range_.size() > pos);
return range_[pos];
}
BENCHMARK_DEPRECATED_MSG("use 'range(0)' instead")
int range_x() const { return range(0); }
int64_t range_x() const { return range(0); }
BENCHMARK_DEPRECATED_MSG("use 'range(1)' instead")
int range_y() const { return range(1); }
int64_t range_y() const { return range(1); }
BENCHMARK_ALWAYS_INLINE
size_t iterations() const { return (max_iterations - total_iterations_) + 1; }
size_t iterations() const {
if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
return 0;
}
return max_iterations - total_iterations_ + batch_leftover_;
}
private:
bool started_;
bool finished_;
private: // items we expect on the first cache line (ie 64 bytes of the struct)
// When total_iterations_ is 0, KeepRunning() and friends will return false.
// May be larger than max_iterations.
size_t total_iterations_;
std::vector<int> range_;
// When using KeepRunningBatch(), batch_leftover_ holds the number of
// iterations beyond max_iters that were run. Used to track
// completed_iterations_ accurately.
size_t batch_leftover_;
size_t bytes_processed_;
size_t items_processed_;
int complexity_n_;
public:
const size_t max_iterations;
private:
bool started_;
bool finished_;
bool error_occurred_;
private: // items we don't need on the first cache line
std::vector<int64_t> range_;
int64_t bytes_processed_;
int64_t items_processed_;
int64_t complexity_n_;
public:
// Container for user-defined counters.
UserCounters counters;
@@ -588,27 +615,69 @@ class State {
const int thread_index;
// Number of threads concurrently executing the benchmark.
const int threads;
const size_t max_iterations;
// TODO(EricWF) make me private
State(size_t max_iters, const std::vector<int>& ranges, int thread_i,
State(size_t max_iters, const std::vector<int64_t>& ranges, int thread_i,
int n_threads, internal::ThreadTimer* timer,
internal::ThreadManager* manager);
private:
void StartKeepRunning();
// Implementation of KeepRunning() and KeepRunningBatch().
// is_batch must be true unless n is 1.
bool KeepRunningInternal(size_t n, bool is_batch);
void FinishKeepRunning();
internal::ThreadTimer* timer_;
internal::ThreadManager* manager_;
BENCHMARK_DISALLOW_COPY_AND_ASSIGN(State);
};
inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunning() {
return KeepRunningInternal(1, /*is_batch=*/ false);
}
inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningBatch(size_t n) {
return KeepRunningInternal(n, /*is_batch=*/ true);
}
inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningInternal(size_t n, bool is_batch) {
// total_iterations_ is set to 0 by the constructor, and always set to a
// nonzero value by StartKepRunning().
assert(n > 0);
// n must be 1 unless is_batch is true.
assert(is_batch || n == 1);
if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n, true)) {
total_iterations_ -= n;
return true;
}
if (!started_) {
StartKeepRunning();
if (!error_occurred_ && total_iterations_ >= n) {
total_iterations_-= n;
return true;
}
}
// For non-batch runs, total_iterations_ must be 0 by now.
if (is_batch && total_iterations_ != 0) {
batch_leftover_ = n - total_iterations_;
total_iterations_ = 0;
return true;
}
FinishKeepRunning();
return false;
}
struct State::StateIterator {
struct BENCHMARK_UNUSED Value {};
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef Value reference;
typedef Value pointer;
typedef std::ptrdiff_t difference_type;
private:
friend class State;
@@ -670,7 +739,7 @@ class Benchmark {
// Run this benchmark once with "x" as the extra argument passed
// to the function.
// REQUIRES: The function passed to the constructor must accept an arg1.
Benchmark* Arg(int x);
Benchmark* Arg(int64_t x);
// Run this benchmark with the given time unit for the generated output report
Benchmark* Unit(TimeUnit unit);
@@ -678,23 +747,23 @@ class Benchmark {
// Run this benchmark once for a number of values picked from the
// range [start..limit]. (start and limit are always picked.)
// REQUIRES: The function passed to the constructor must accept an arg1.
Benchmark* Range(int start, int limit);
Benchmark* Range(int64_t start, int64_t limit);
// Run this benchmark once for all values in the range [start..limit] with
// specific step
// REQUIRES: The function passed to the constructor must accept an arg1.
Benchmark* DenseRange(int start, int limit, int step = 1);
Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1);
// Run this benchmark once with "args" as the extra arguments passed
// to the function.
// REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
Benchmark* Args(const std::vector<int>& args);
Benchmark* Args(const std::vector<int64_t>& args);
// Equivalent to Args({x, y})
// NOTE: This is a legacy C++03 interface provided for compatibility only.
// New code should use 'Args'.
Benchmark* ArgPair(int x, int y) {
std::vector<int> args;
Benchmark* ArgPair(int64_t x, int64_t y) {
std::vector<int64_t> args;
args.push_back(x);
args.push_back(y);
return Args(args);
@@ -703,7 +772,7 @@ class Benchmark {
// Run this benchmark once for a number of values picked from the
// ranges [start..limit]. (starts and limits are always picked.)
// REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
Benchmark* Ranges(const std::vector<std::pair<int, int> >& ranges);
Benchmark* Ranges(const std::vector<std::pair<int64_t, int64_t> >& ranges);
// Equivalent to ArgNames({name})
Benchmark* ArgName(const std::string& name);
@@ -715,8 +784,8 @@ class Benchmark {
// Equivalent to Ranges({{lo1, hi1}, {lo2, hi2}}).
// NOTE: This is a legacy C++03 interface provided for compatibility only.
// New code should use 'Ranges'.
Benchmark* RangePair(int lo1, int hi1, int lo2, int hi2) {
std::vector<std::pair<int, int> > ranges;
Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
std::vector<std::pair<int64_t, int64_t> > ranges;
ranges.push_back(std::make_pair(lo1, hi1));
ranges.push_back(std::make_pair(lo2, hi2));
return Ranges(ranges);
@@ -823,15 +892,13 @@ class Benchmark {
int ArgsCnt() const;
static void AddRange(std::vector<int>* dst, int lo, int hi, int mult);
private:
friend class BenchmarkFamilies;
std::string name_;
ReportMode report_mode_;
std::vector<std::string> arg_names_; // Args for all benchmark runs
std::vector<std::vector<int> > args_; // Args for all benchmark runs
std::vector<std::vector<int64_t> > args_; // Args for all benchmark runs
TimeUnit time_unit_;
int range_multiplier_;
double min_time_;
@@ -1186,7 +1253,7 @@ class BenchmarkReporter {
CPUInfo const& cpu_info;
// The number of chars in the longest benchmark name.
size_t name_field_width;
static const char *executable_name;
Context();
};
@@ -1239,7 +1306,7 @@ class BenchmarkReporter {
// Keep track of arguments to compute asymptotic complexity
BigO complexity;
BigOFunc* complexity_lambda;
int complexity_n;
int64_t complexity_n;
// what statistics to compute from the measurements
const std::vector<Statistics>* statistics;

320
benchmarks/thirdparty/benchmark/mingw.py vendored Executable file
View File

@@ -0,0 +1,320 @@
#! /usr/bin/env python
# encoding: utf-8
import argparse
import errno
import logging
import os
import platform
import re
import sys
import subprocess
import tempfile
try:
import winreg
except ImportError:
import _winreg as winreg
try:
import urllib.request as request
except ImportError:
import urllib as request
try:
import urllib.parse as parse
except ImportError:
import urlparse as parse
class EmptyLogger(object):
'''
Provides an implementation that performs no logging
'''
def debug(self, *k, **kw):
pass
def info(self, *k, **kw):
pass
def warn(self, *k, **kw):
pass
def error(self, *k, **kw):
pass
def critical(self, *k, **kw):
pass
def setLevel(self, *k, **kw):
pass
urls = (
'http://downloads.sourceforge.net/project/mingw-w64/Toolchains%20'
'targetting%20Win32/Personal%20Builds/mingw-builds/installer/'
'repository.txt',
'http://downloads.sourceforge.net/project/mingwbuilds/host-windows/'
'repository.txt'
)
'''
A list of mingw-build repositories
'''
def repository(urls = urls, log = EmptyLogger()):
'''
Downloads and parse mingw-build repository files and parses them
'''
log.info('getting mingw-builds repository')
versions = {}
re_sourceforge = re.compile(r'http://sourceforge.net/projects/([^/]+)/files')
re_sub = r'http://downloads.sourceforge.net/project/\1'
for url in urls:
log.debug(' - requesting: %s', url)
socket = request.urlopen(url)
repo = socket.read()
if not isinstance(repo, str):
repo = repo.decode();
socket.close()
for entry in repo.split('\n')[:-1]:
value = entry.split('|')
version = tuple([int(n) for n in value[0].strip().split('.')])
version = versions.setdefault(version, {})
arch = value[1].strip()
if arch == 'x32':
arch = 'i686'
elif arch == 'x64':
arch = 'x86_64'
arch = version.setdefault(arch, {})
threading = arch.setdefault(value[2].strip(), {})
exceptions = threading.setdefault(value[3].strip(), {})
revision = exceptions.setdefault(int(value[4].strip()[3:]),
re_sourceforge.sub(re_sub, value[5].strip()))
return versions
def find_in_path(file, path=None):
'''
Attempts to find an executable in the path
'''
if platform.system() == 'Windows':
file += '.exe'
if path is None:
path = os.environ.get('PATH', '')
if type(path) is type(''):
path = path.split(os.pathsep)
return list(filter(os.path.exists,
map(lambda dir, file=file: os.path.join(dir, file), path)))
def find_7zip(log = EmptyLogger()):
'''
Attempts to find 7zip for unpacking the mingw-build archives
'''
log.info('finding 7zip')
path = find_in_path('7z')
if not path:
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\7-Zip')
path, _ = winreg.QueryValueEx(key, 'Path')
path = [os.path.join(path, '7z.exe')]
log.debug('found \'%s\'', path[0])
return path[0]
find_7zip()
def unpack(archive, location, log = EmptyLogger()):
'''
Unpacks a mingw-builds archive
'''
sevenzip = find_7zip(log)
log.info('unpacking %s', os.path.basename(archive))
cmd = [sevenzip, 'x', archive, '-o' + location, '-y']
log.debug(' - %r', cmd)
with open(os.devnull, 'w') as devnull:
subprocess.check_call(cmd, stdout = devnull)
def download(url, location, log = EmptyLogger()):
'''
Downloads and unpacks a mingw-builds archive
'''
log.info('downloading MinGW')
log.debug(' - url: %s', url)
log.debug(' - location: %s', location)
re_content = re.compile(r'attachment;[ \t]*filename=(")?([^"]*)(")?[\r\n]*')
stream = request.urlopen(url)
try:
content = stream.getheader('Content-Disposition') or ''
except AttributeError:
content = stream.headers.getheader('Content-Disposition') or ''
matches = re_content.match(content)
if matches:
filename = matches.group(2)
else:
parsed = parse.urlparse(stream.geturl())
filename = os.path.basename(parsed.path)
try:
os.makedirs(location)
except OSError as e:
if e.errno == errno.EEXIST and os.path.isdir(location):
pass
else:
raise
archive = os.path.join(location, filename)
with open(archive, 'wb') as out:
while True:
buf = stream.read(1024)
if not buf:
break
out.write(buf)
unpack(archive, location, log = log)
os.remove(archive)
possible = os.path.join(location, 'mingw64')
if not os.path.exists(possible):
possible = os.path.join(location, 'mingw32')
if not os.path.exists(possible):
raise ValueError('Failed to find unpacked MinGW: ' + possible)
return possible
def root(location = None, arch = None, version = None, threading = None,
exceptions = None, revision = None, log = EmptyLogger()):
'''
Returns the root folder of a specific version of the mingw-builds variant
of gcc. Will download the compiler if needed
'''
# Get the repository if we don't have all the information
if not (arch and version and threading and exceptions and revision):
versions = repository(log = log)
# Determine some defaults
version = version or max(versions.keys())
if not arch:
arch = platform.machine().lower()
if arch == 'x86':
arch = 'i686'
elif arch == 'amd64':
arch = 'x86_64'
if not threading:
keys = versions[version][arch].keys()
if 'posix' in keys:
threading = 'posix'
elif 'win32' in keys:
threading = 'win32'
else:
threading = keys[0]
if not exceptions:
keys = versions[version][arch][threading].keys()
if 'seh' in keys:
exceptions = 'seh'
elif 'sjlj' in keys:
exceptions = 'sjlj'
else:
exceptions = keys[0]
if revision == None:
revision = max(versions[version][arch][threading][exceptions].keys())
if not location:
location = os.path.join(tempfile.gettempdir(), 'mingw-builds')
# Get the download url
url = versions[version][arch][threading][exceptions][revision]
# Tell the user whatzzup
log.info('finding MinGW %s', '.'.join(str(v) for v in version))
log.debug(' - arch: %s', arch)
log.debug(' - threading: %s', threading)
log.debug(' - exceptions: %s', exceptions)
log.debug(' - revision: %s', revision)
log.debug(' - url: %s', url)
# Store each specific revision differently
slug = '{version}-{arch}-{threading}-{exceptions}-rev{revision}'
slug = slug.format(
version = '.'.join(str(v) for v in version),
arch = arch,
threading = threading,
exceptions = exceptions,
revision = revision
)
if arch == 'x86_64':
root_dir = os.path.join(location, slug, 'mingw64')
elif arch == 'i686':
root_dir = os.path.join(location, slug, 'mingw32')
else:
raise ValueError('Unknown MinGW arch: ' + arch)
# Download if needed
if not os.path.exists(root_dir):
downloaded = download(url, os.path.join(location, slug), log = log)
if downloaded != root_dir:
raise ValueError('The location of mingw did not match\n%s\n%s'
% (downloaded, root_dir))
return root_dir
def str2ver(string):
'''
Converts a version string into a tuple
'''
try:
version = tuple(int(v) for v in string.split('.'))
if len(version) is not 3:
raise ValueError()
except ValueError:
raise argparse.ArgumentTypeError(
'please provide a three digit version string')
return version
def main():
'''
Invoked when the script is run directly by the python interpreter
'''
parser = argparse.ArgumentParser(
description = 'Downloads a specific version of MinGW',
formatter_class = argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument('--location',
help = 'the location to download the compiler to',
default = os.path.join(tempfile.gettempdir(), 'mingw-builds'))
parser.add_argument('--arch', required = True, choices = ['i686', 'x86_64'],
help = 'the target MinGW architecture string')
parser.add_argument('--version', type = str2ver,
help = 'the version of GCC to download')
parser.add_argument('--threading', choices = ['posix', 'win32'],
help = 'the threading type of the compiler')
parser.add_argument('--exceptions', choices = ['sjlj', 'seh', 'dwarf'],
help = 'the method to throw exceptions')
parser.add_argument('--revision', type=int,
help = 'the revision of the MinGW release')
group = parser.add_mutually_exclusive_group()
group.add_argument('-v', '--verbose', action='store_true',
help='increase the script output verbosity')
group.add_argument('-q', '--quiet', action='store_true',
help='only print errors and warning')
args = parser.parse_args()
# Create the logger
logger = logging.getLogger('mingw')
handler = logging.StreamHandler()
formatter = logging.Formatter('%(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
if args.quiet:
logger.setLevel(logging.WARN)
if args.verbose:
logger.setLevel(logging.DEBUG)
# Get MinGW
root_dir = root(location = args.location, arch = args.arch,
version = args.version, threading = args.threading,
exceptions = args.exceptions, revision = args.revision,
log = logger)
sys.stdout.write('%s\n' % os.path.join(root_dir, 'bin'))
if __name__ == '__main__':
try:
main()
except IOError as e:
sys.stderr.write('IO error: %s\n' % e)
sys.exit(1)
except OSError as e:
sys.stderr.write('OS error: %s\n' % e)
sys.exit(1)
except KeyboardInterrupt as e:
sys.stderr.write('Killed\n')
sys.exit(1)

16
benchmarks/thirdparty/benchmark/releasing.md vendored Executable file
View File

@@ -0,0 +1,16 @@
# How to release
* Make sure you're on master and synced to HEAD
* Ensure the project builds and tests run (sanity check only, obviously)
* `parallel -j0 exec ::: test/*_test` can help ensure everything at least
passes
* Prepare release notes
* `git log $(git describe --abbrev=0 --tags)..HEAD` gives you the list of
commits between the last annotated tag and HEAD
* Pick the most interesting.
* Create a release through github's interface
* Note this will create a lightweight tag.
* Update this to an annotated tag:
* `git pull --tags`
* `git tag -a -f <tag> <tag>`
* `git push --force origin`

20
benchmarks/thirdparty/benchmark/src/CMakeLists.txt vendored Normal file → Executable file
View File

@@ -11,6 +11,7 @@ file(GLOB
*.cc
${PROJECT_SOURCE_DIR}/include/benchmark/*.h
${CMAKE_CURRENT_SOURCE_DIR}/*.h)
list(FILTER SOURCE_FILES EXCLUDE REGEX "benchmark_main\\.cc")
add_library(benchmark ${SOURCE_FILES})
set_target_properties(benchmark PROPERTIES
@@ -34,6 +35,23 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
target_link_libraries(benchmark Shlwapi)
endif()
# We need extra libraries on Solaris
if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
target_link_libraries(benchmark kstat)
endif()
# Benchmark main library
add_library(benchmark_main "benchmark_main.cc")
set_target_properties(benchmark_main PROPERTIES
OUTPUT_NAME "benchmark_main"
VERSION ${GENERIC_LIB_VERSION}
SOVERSION ${GENERIC_LIB_SOVERSION}
)
target_include_directories(benchmark PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
)
target_link_libraries(benchmark_main benchmark)
set(include_install_dir "include")
set(lib_install_dir "lib/")
set(bin_install_dir "bin/")
@@ -60,7 +78,7 @@ configure_file("${PROJECT_SOURCE_DIR}/cmake/benchmark.pc.in" "${pkg_config}" @ON
if (BENCHMARK_ENABLE_INSTALL)
# Install target (will install the library to specified CMAKE_INSTALL_PREFIX variable)
install(
TARGETS benchmark
TARGETS benchmark benchmark_main
EXPORT ${targets_export_name}
ARCHIVE DESTINATION ${lib_install_dir}
LIBRARY DESTINATION ${lib_install_dir}

0
benchmarks/thirdparty/benchmark/src/arraysize.h vendored Normal file → Executable file
View File

174
benchmarks/thirdparty/benchmark/src/benchmark.cc vendored Normal file → Executable file
View File

@@ -17,7 +17,9 @@
#include "internal_macros.h"
#ifndef BENCHMARK_OS_WINDOWS
#ifndef BENCHMARK_OS_FUCHSIA
#include <sys/resource.h>
#endif
#include <sys/time.h>
#include <unistd.h>
#endif
@@ -27,10 +29,10 @@
#include <condition_variable>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include "check.h"
@@ -44,7 +46,8 @@
#include "re.h"
#include "statistics.h"
#include "string_util.h"
#include "timers.h"
#include "thread_manager.h"
#include "thread_timer.h"
DEFINE_bool(benchmark_list_tests, false,
"Print a list of benchmarks. This option overrides all other "
@@ -82,7 +85,7 @@ DEFINE_string(benchmark_out_format, "json",
"The format to use for file output. Valid values are "
"'console', 'json', or 'csv'.");
DEFINE_string(benchmark_out, "", "The file to write additonal output to");
DEFINE_string(benchmark_out, "", "The file to write additional output to");
DEFINE_string(benchmark_color, "auto",
"Whether to use colors in the output. Valid values: "
@@ -108,118 +111,11 @@ namespace internal {
void UseCharPointer(char const volatile*) {}
class ThreadManager {
public:
ThreadManager(int num_threads)
: alive_threads_(num_threads), start_stop_barrier_(num_threads) {}
Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) {
return benchmark_mutex_;
}
bool StartStopBarrier() EXCLUDES(end_cond_mutex_) {
return start_stop_barrier_.wait();
}
void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) {
start_stop_barrier_.removeThread();
if (--alive_threads_ == 0) {
MutexLock lock(end_cond_mutex_);
end_condition_.notify_all();
}
}
void WaitForAllThreads() EXCLUDES(end_cond_mutex_) {
MutexLock lock(end_cond_mutex_);
end_condition_.wait(lock.native_handle(),
[this]() { return alive_threads_ == 0; });
}
public:
struct Result {
double real_time_used = 0;
double cpu_time_used = 0;
double manual_time_used = 0;
int64_t bytes_processed = 0;
int64_t items_processed = 0;
int complexity_n = 0;
std::string report_label_;
std::string error_message_;
bool has_error_ = false;
UserCounters counters;
};
GUARDED_BY(GetBenchmarkMutex()) Result results;
private:
mutable Mutex benchmark_mutex_;
std::atomic<int> alive_threads_;
Barrier start_stop_barrier_;
Mutex end_cond_mutex_;
Condition end_condition_;
};
// Timer management class
class ThreadTimer {
public:
ThreadTimer() = default;
// Called by each thread
void StartTimer() {
running_ = true;
start_real_time_ = ChronoClockNow();
start_cpu_time_ = ThreadCPUUsage();
}
// Called by each thread
void StopTimer() {
CHECK(running_);
running_ = false;
real_time_used_ += ChronoClockNow() - start_real_time_;
// Floating point error can result in the subtraction producing a negative
// time. Guard against that.
cpu_time_used_ += std::max<double>(ThreadCPUUsage() - start_cpu_time_, 0);
}
// Called by each thread
void SetIterationTime(double seconds) { manual_time_used_ += seconds; }
bool running() const { return running_; }
// REQUIRES: timer is not running
double real_time_used() {
CHECK(!running_);
return real_time_used_;
}
// REQUIRES: timer is not running
double cpu_time_used() {
CHECK(!running_);
return cpu_time_used_;
}
// REQUIRES: timer is not running
double manual_time_used() {
CHECK(!running_);
return manual_time_used_;
}
private:
bool running_ = false; // Is the timer running
double start_real_time_ = 0; // If running_
double start_cpu_time_ = 0; // If running_
// Accumulated time so far (does not contain current slice if running_)
double real_time_used_ = 0;
double cpu_time_used_ = 0;
// Manually set iteration time. User sets this with SetIterationTime(seconds).
double manual_time_used_ = 0;
};
namespace {
BenchmarkReporter::Run CreateRunReport(
const benchmark::internal::Benchmark::Instance& b,
const internal::ThreadManager::Result& results, size_t iters,
const internal::ThreadManager::Result& results,
double seconds) {
// Create report about this benchmark run.
BenchmarkReporter::Run report;
@@ -228,8 +124,8 @@ BenchmarkReporter::Run CreateRunReport(
report.error_occurred = results.has_error_;
report.error_message = results.error_message_;
report.report_label = results.report_label_;
// Report the total iterations across all threads.
report.iterations = static_cast<int64_t>(iters) * b.threads;
// This is the total iterations across all threads.
report.iterations = results.iterations;
report.time_unit = b.time_unit;
if (!report.error_occurred) {
@@ -268,11 +164,12 @@ void RunInThread(const benchmark::internal::Benchmark::Instance* b,
internal::ThreadTimer timer;
State st(iters, b->arg, thread_id, b->threads, &timer, manager);
b->benchmark->Run(st);
CHECK(st.iterations() == st.max_iterations)
CHECK(st.iterations() >= st.max_iterations)
<< "Benchmark returned before State::KeepRunning() returned false!";
{
MutexLock l(manager->GetBenchmarkMutex());
internal::ThreadManager::Result& results = manager->results;
results.iterations += st.iterations();
results.cpu_time_used += timer.cpu_time_used();
results.real_time_used += timer.real_time_used();
results.manual_time_used += timer.manual_time_used();
@@ -340,18 +237,17 @@ std::vector<BenchmarkReporter::Run> RunBenchmark(
// Determine if this run should be reported; Either it has
// run for a sufficient amount of time or because an error was reported.
const bool should_report = repetition_num > 0
|| has_explicit_iteration_count // An exact iteration count was requested
|| has_explicit_iteration_count // An exact iteration count was requested
|| results.has_error_
|| iters >= kMaxIterations
|| seconds >= min_time // the elapsed time is large enough
|| iters >= kMaxIterations // No chance to try again, we hit the limit.
|| seconds >= min_time // the elapsed time is large enough
// CPU time is specified but the elapsed real time greatly exceeds the
// minimum time. Note that user provided timers are except from this
// sanity check.
|| ((results.real_time_used >= 5 * min_time) && !b.use_manual_time);
if (should_report) {
BenchmarkReporter::Run report =
CreateRunReport(b, results, iters, seconds);
BenchmarkReporter::Run report = CreateRunReport(b, results, seconds);
if (!report.error_occurred && b.complexity != oNone)
complexity_reports->push_back(report);
reports.push_back(report);
@@ -394,26 +290,44 @@ std::vector<BenchmarkReporter::Run> RunBenchmark(
} // namespace
} // namespace internal
State::State(size_t max_iters, const std::vector<int>& ranges, int thread_i,
State::State(size_t max_iters, const std::vector<int64_t>& ranges, int thread_i,
int n_threads, internal::ThreadTimer* timer,
internal::ThreadManager* manager)
: started_(false),
: total_iterations_(0),
batch_leftover_(0),
max_iterations(max_iters),
started_(false),
finished_(false),
total_iterations_(max_iters + 1),
error_occurred_(false),
range_(ranges),
bytes_processed_(0),
items_processed_(0),
complexity_n_(0),
error_occurred_(false),
counters(),
thread_index(thread_i),
threads(n_threads),
max_iterations(max_iters),
timer_(timer),
manager_(manager) {
CHECK(max_iterations != 0) << "At least one iteration must be run";
CHECK(total_iterations_ != 0) << "max iterations wrapped around";
CHECK_LT(thread_index, threads) << "thread_index must be less than threads";
// Note: The use of offsetof below is technically undefined until C++17
// because State is not a standard layout type. However, all compilers
// currently provide well-defined behavior as an extension (which is
// demonstrated since constexpr evaluation must diagnose all undefined
// behavior). However, GCC and Clang also warn about this use of offsetof,
// which must be suppressed.
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
#endif
// Offset tests to ensure commonly accessed data is on the first cache line.
const int cache_line_size = 64;
static_assert(offsetof(State, error_occurred_) <=
(cache_line_size - sizeof(error_occurred_)), "");
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
}
void State::PauseTiming() {
@@ -437,7 +351,7 @@ void State::SkipWithError(const char* msg) {
manager_->results.has_error_ = true;
}
}
total_iterations_ = 1;
total_iterations_ = 0;
if (timer_->running()) timer_->StopTimer();
}
@@ -453,6 +367,7 @@ void State::SetLabel(const char* label) {
void State::StartKeepRunning() {
CHECK(!started_ && !finished_);
started_ = true;
total_iterations_ = error_occurred_ ? 0 : max_iterations;
manager_->StartStopBarrier();
if (!error_occurred_) ResumeTiming();
}
@@ -462,8 +377,8 @@ void State::FinishKeepRunning() {
if (!error_occurred_) {
PauseTiming();
}
// Total iterations has now wrapped around zero. Fix this.
total_iterations_ = 1;
// Total iterations has now wrapped around past 0. Fix this.
total_iterations_ = 0;
finished_ = true;
manager_->StartStopBarrier();
}
@@ -495,7 +410,7 @@ void RunBenchmarks(const std::vector<Benchmark::Instance>& benchmarks,
BenchmarkReporter::Context context;
context.name_field_width = name_field_width;
// Keep track of runing times of all instances of current benchmark
// Keep track of running times of all instances of current benchmark
std::vector<BenchmarkReporter::Run> complexity_reports;
// We flush streams after invoking reporter methods that write to them. This
@@ -653,6 +568,7 @@ void PrintUsageAndExit() {
void ParseCommandLineFlags(int* argc, char** argv) {
using namespace benchmark;
BenchmarkReporter::Context::executable_name = argv[0];
for (int i = 1; i < *argc; ++i) {
if (ParseBoolFlag(argv[i], "benchmark_list_tests",
&FLAGS_benchmark_list_tests) ||

2
benchmarks/thirdparty/benchmark/src/benchmark_api_internal.h vendored Normal file → Executable file
View File

@@ -17,7 +17,7 @@ struct Benchmark::Instance {
std::string name;
Benchmark* benchmark;
ReportMode report_mode;
std::vector<int> arg;
std::vector<int64_t> arg;
TimeUnit time_unit;
int range_multiplier;
bool use_real_time;

View File

@@ -0,0 +1,17 @@
// Copyright 2018 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "benchmark/benchmark.h"
BENCHMARK_MAIN();

83
benchmarks/thirdparty/benchmark/src/benchmark_register.cc vendored Normal file → Executable file
View File

@@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "benchmark/benchmark.h"
#include "benchmark_api_internal.h"
#include "internal_macros.h"
#include "benchmark_register.h"
#ifndef BENCHMARK_OS_WINDOWS
#ifndef BENCHMARK_OS_FUCHSIA
#include <sys/resource.h>
#endif
#include <sys/time.h>
#include <unistd.h>
#endif
@@ -34,13 +34,16 @@
#include <sstream>
#include <thread>
#include "benchmark/benchmark.h"
#include "benchmark_api_internal.h"
#include "check.h"
#include "commandlineflags.h"
#include "complexity.h"
#include "statistics.h"
#include "internal_macros.h"
#include "log.h"
#include "mutex.h"
#include "re.h"
#include "statistics.h"
#include "string_util.h"
#include "timers.h"
@@ -74,7 +77,7 @@ class BenchmarkFamilies {
// Extract the list of benchmark instances that match the specified
// regular expression.
bool FindBenchmarks(const std::string& re,
bool FindBenchmarks(std::string re,
std::vector<Benchmark::Instance>* benchmarks,
std::ostream* Err);
@@ -104,13 +107,18 @@ void BenchmarkFamilies::ClearBenchmarks() {
}
bool BenchmarkFamilies::FindBenchmarks(
const std::string& spec, std::vector<Benchmark::Instance>* benchmarks,
std::string spec, std::vector<Benchmark::Instance>* benchmarks,
std::ostream* ErrStream) {
CHECK(ErrStream);
auto& Err = *ErrStream;
// Make regular expression out of command-line flag
std::string error_msg;
Regex re;
bool isNegativeFilter = false;
if(spec[0] == '-') {
spec.replace(0, 1, "");
isNegativeFilter = true;
}
if (!re.Init(spec, &error_msg)) {
Err << "Could not compile benchmark re: " << error_msg << std::endl;
return false;
@@ -170,20 +178,20 @@ bool BenchmarkFamilies::FindBenchmarks(
const auto& arg_name = family->arg_names_[arg_i];
if (!arg_name.empty()) {
instance.name +=
StringPrintF("%s:", family->arg_names_[arg_i].c_str());
StrFormat("%s:", family->arg_names_[arg_i].c_str());
}
}
instance.name += StringPrintF("%d", arg);
instance.name += StrFormat("%d", arg);
++arg_i;
}
if (!IsZero(family->min_time_))
instance.name += StringPrintF("/min_time:%0.3f", family->min_time_);
instance.name += StrFormat("/min_time:%0.3f", family->min_time_);
if (family->iterations_ != 0)
instance.name += StringPrintF("/iterations:%d", family->iterations_);
instance.name += StrFormat("/iterations:%d", family->iterations_);
if (family->repetitions_ != 0)
instance.name += StringPrintF("/repeats:%d", family->repetitions_);
instance.name += StrFormat("/repeats:%d", family->repetitions_);
if (family->use_manual_time_) {
instance.name += "/manual_time";
@@ -193,10 +201,11 @@ bool BenchmarkFamilies::FindBenchmarks(
// Add the number of threads used to the name
if (!family->thread_counts_.empty()) {
instance.name += StringPrintF("/threads:%d", instance.threads);
instance.name += StrFormat("/threads:%d", instance.threads);
}
if (re.Match(instance.name)) {
if ((re.Match(instance.name) && !isNegativeFilter) ||
(!re.Match(instance.name) && isNegativeFilter)) {
instance.last_benchmark_instance = (&args == &family->args_.back());
benchmarks->push_back(std::move(instance));
}
@@ -244,30 +253,7 @@ Benchmark::Benchmark(const char* name)
Benchmark::~Benchmark() {}
void Benchmark::AddRange(std::vector<int>* dst, int lo, int hi, int mult) {
CHECK_GE(lo, 0);
CHECK_GE(hi, lo);
CHECK_GE(mult, 2);
// Add "lo"
dst->push_back(lo);
static const int kint32max = std::numeric_limits<int32_t>::max();
// Now space out the benchmarks in multiples of "mult"
for (int32_t i = 1; i < kint32max / mult; i *= mult) {
if (i >= hi) break;
if (i > lo) {
dst->push_back(i);
}
}
// Add "hi" (if different from "lo")
if (hi != lo) {
dst->push_back(hi);
}
}
Benchmark* Benchmark::Arg(int x) {
Benchmark* Benchmark::Arg(int64_t x) {
CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
args_.push_back({x});
return this;
@@ -278,20 +264,21 @@ Benchmark* Benchmark::Unit(TimeUnit unit) {
return this;
}
Benchmark* Benchmark::Range(int start, int limit) {
Benchmark* Benchmark::Range(int64_t start, int64_t limit) {
CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
std::vector<int> arglist;
std::vector<int64_t> arglist;
AddRange(&arglist, start, limit, range_multiplier_);
for (int i : arglist) {
for (int64_t i : arglist) {
args_.push_back({i});
}
return this;
}
Benchmark* Benchmark::Ranges(const std::vector<std::pair<int, int>>& ranges) {
Benchmark* Benchmark::Ranges(
const std::vector<std::pair<int64_t, int64_t>>& ranges) {
CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(ranges.size()));
std::vector<std::vector<int>> arglists(ranges.size());
std::vector<std::vector<int64_t>> arglists(ranges.size());
std::size_t total = 1;
for (std::size_t i = 0; i < ranges.size(); i++) {
AddRange(&arglists[i], ranges[i].first, ranges[i].second,
@@ -302,7 +289,7 @@ Benchmark* Benchmark::Ranges(const std::vector<std::pair<int, int>>& ranges) {
std::vector<std::size_t> ctr(arglists.size(), 0);
for (std::size_t i = 0; i < total; i++) {
std::vector<int> tmp;
std::vector<int64_t> tmp;
tmp.reserve(arglists.size());
for (std::size_t j = 0; j < arglists.size(); j++) {
@@ -334,17 +321,17 @@ Benchmark* Benchmark::ArgNames(const std::vector<std::string>& names) {
return this;
}
Benchmark* Benchmark::DenseRange(int start, int limit, int step) {
Benchmark* Benchmark::DenseRange(int64_t start, int64_t limit, int step) {
CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
CHECK_GE(start, 0);
CHECK_LE(start, limit);
for (int arg = start; arg <= limit; arg += step) {
for (int64_t arg = start; arg <= limit; arg += step) {
args_.push_back({arg});
}
return this;
}
Benchmark* Benchmark::Args(const std::vector<int>& args) {
Benchmark* Benchmark::Args(const std::vector<int64_t>& args) {
CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(args.size()));
args_.push_back(args);
return this;
@@ -361,7 +348,6 @@ Benchmark* Benchmark::RangeMultiplier(int multiplier) {
return this;
}
Benchmark* Benchmark::MinTime(double t) {
CHECK(t > 0.0);
CHECK(iterations_ == 0);
@@ -369,7 +355,6 @@ Benchmark* Benchmark::MinTime(double t) {
return this;
}
Benchmark* Benchmark::Iterations(size_t n) {
CHECK(n > 0);
CHECK(IsZero(min_time_));

View File

@@ -0,0 +1,33 @@
#ifndef BENCHMARK_REGISTER_H
#define BENCHMARK_REGISTER_H
#include <vector>
#include "check.h"
template <typename T>
void AddRange(std::vector<T>* dst, T lo, T hi, int mult) {
CHECK_GE(lo, 0);
CHECK_GE(hi, lo);
CHECK_GE(mult, 2);
// Add "lo"
dst->push_back(lo);
static const T kmax = std::numeric_limits<T>::max();
// Now space out the benchmarks in multiples of "mult"
for (T i = 1; i < kmax / mult; i *= mult) {
if (i >= hi) break;
if (i > lo) {
dst->push_back(i);
}
}
// Add "hi" (if different from "lo")
if (hi != lo) {
dst->push_back(hi);
}
}
#endif // BENCHMARK_REGISTER_H

0
benchmarks/thirdparty/benchmark/src/check.h vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/src/colorprint.cc vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/src/colorprint.h vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/src/commandlineflags.cc vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/src/commandlineflags.h vendored Normal file → Executable file
View File

22
benchmarks/thirdparty/benchmark/src/complexity.cc vendored Normal file → Executable file
View File

@@ -28,18 +28,18 @@ namespace benchmark {
BigOFunc* FittingCurve(BigO complexity) {
switch (complexity) {
case oN:
return [](int n) -> double { return n; };
return [](int64_t n) -> double { return static_cast<double>(n); };
case oNSquared:
return [](int n) -> double { return std::pow(n, 2); };
return [](int64_t n) -> double { return std::pow(n, 2); };
case oNCubed:
return [](int n) -> double { return std::pow(n, 3); };
return [](int64_t n) -> double { return std::pow(n, 3); };
case oLogN:
return [](int n) { return log2(n); };
return [](int64_t n) { return log2(n); };
case oNLogN:
return [](int n) { return n * log2(n); };
return [](int64_t n) { return n * log2(n); };
case o1:
default:
return [](int) { return 1.0; };
return [](int64_t) { return 1.0; };
}
}
@@ -65,15 +65,15 @@ std::string GetBigOString(BigO complexity) {
// Find the coefficient for the high-order term in the running time, by
// minimizing the sum of squares of relative error, for the fitting curve
// given by the lambda expresion.
// given by the lambda expression.
// - n : Vector containing the size of the benchmark tests.
// - time : Vector containing the times for the benchmark tests.
// - fitting_curve : lambda expresion (e.g. [](int n) {return n; };).
// - fitting_curve : lambda expression (e.g. [](int64_t n) {return n; };).
// For a deeper explanation on the algorithm logic, look the README file at
// http://github.com/ismaelJimenez/Minimal-Cpp-Least-Squared-Fit
LeastSq MinimalLeastSq(const std::vector<int>& n,
LeastSq MinimalLeastSq(const std::vector<int64_t>& n,
const std::vector<double>& time,
BigOFunc* fitting_curve) {
double sigma_gn = 0.0;
@@ -117,7 +117,7 @@ LeastSq MinimalLeastSq(const std::vector<int>& n,
// - complexity : If different than oAuto, the fitting curve will stick to
// this one. If it is oAuto, it will be calculated the best
// fitting curve.
LeastSq MinimalLeastSq(const std::vector<int>& n,
LeastSq MinimalLeastSq(const std::vector<int64_t>& n,
const std::vector<double>& time, const BigO complexity) {
CHECK_EQ(n.size(), time.size());
CHECK_GE(n.size(), 2); // Do not compute fitting curve is less than two
@@ -157,7 +157,7 @@ std::vector<BenchmarkReporter::Run> ComputeBigO(
if (reports.size() < 2) return results;
// Accumulators.
std::vector<int> n;
std::vector<int64_t> n;
std::vector<double> real_time;
std::vector<double> cpu_time;

0
benchmarks/thirdparty/benchmark/src/complexity.h vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/src/console_reporter.cc vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/src/counter.cc vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/src/counter.h vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/src/csv_reporter.cc vendored Normal file → Executable file
View File

5
benchmarks/thirdparty/benchmark/src/cycleclock.h vendored Normal file → Executable file
View File

@@ -159,6 +159,11 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
struct timeval tv;
gettimeofday(&tv, nullptr);
return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
#elif defined(__s390__) // Covers both s390 and s390x.
// Return the CPU clock.
uint64_t tsc;
asm("stck %0" : "=Q" (tsc) : : "cc");
return tsc;
#else
// The soft failover to a generic implementation is automatic only for ARM.
// For other platforms the developer is expected to make an attempt to create

9
benchmarks/thirdparty/benchmark/src/internal_macros.h vendored Normal file → Executable file
View File

@@ -39,6 +39,7 @@
#elif defined(_WIN32)
#define BENCHMARK_OS_WINDOWS 1
#elif defined(__APPLE__)
#define BENCHMARK_OS_APPLE 1
#include "TargetConditionals.h"
#if defined(TARGET_OS_MAC)
#define BENCHMARK_OS_MACOSX 1
@@ -50,14 +51,20 @@
#define BENCHMARK_OS_FREEBSD 1
#elif defined(__NetBSD__)
#define BENCHMARK_OS_NETBSD 1
#elif defined(__OpenBSD__)
#define BENCHMARK_OS_OPENBSD 1
#elif defined(__linux__)
#define BENCHMARK_OS_LINUX 1
#elif defined(__native_client__)
#define BENCHMARK_OS_NACL 1
#elif defined(EMSCRIPTEN)
#elif defined(__EMSCRIPTEN__)
#define BENCHMARK_OS_EMSCRIPTEN 1
#elif defined(__rtems__)
#define BENCHMARK_OS_RTEMS 1
#elif defined(__Fuchsia__)
#define BENCHMARK_OS_FUCHSIA 1
#elif defined (__SVR4) && defined (__sun)
#define BENCHMARK_OS_SOLARIS 1
#endif
#if !__has_feature(cxx_exceptions) && !defined(__cpp_exceptions) \

10
benchmarks/thirdparty/benchmark/src/json_reporter.cc vendored Normal file → Executable file
View File

@@ -32,15 +32,15 @@ namespace benchmark {
namespace {
std::string FormatKV(std::string const& key, std::string const& value) {
return StringPrintF("\"%s\": \"%s\"", key.c_str(), value.c_str());
return StrFormat("\"%s\": \"%s\"", key.c_str(), value.c_str());
}
std::string FormatKV(std::string const& key, const char* value) {
return StringPrintF("\"%s\": \"%s\"", key.c_str(), value);
return StrFormat("\"%s\": \"%s\"", key.c_str(), value);
}
std::string FormatKV(std::string const& key, bool value) {
return StringPrintF("\"%s\": %s", key.c_str(), value ? "true" : "false");
return StrFormat("\"%s\": %s", key.c_str(), value ? "true" : "false");
}
std::string FormatKV(std::string const& key, int64_t value) {
@@ -77,6 +77,10 @@ bool JSONReporter::ReportContext(const Context& context) {
std::string walltime_value = LocalDateTimeString();
out << indent << FormatKV("date", walltime_value) << ",\n";
if (Context::executable_name) {
out << indent << FormatKV("executable", Context::executable_name) << ",\n";
}
CPUInfo const& info = context.cpu_info;
out << indent << FormatKV("num_cpus", static_cast<int64_t>(info.num_cpus))
<< ",\n";

0
benchmarks/thirdparty/benchmark/src/log.h vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/src/mutex.h vendored Normal file → Executable file
View File

24
benchmarks/thirdparty/benchmark/src/re.h vendored Normal file → Executable file
View File

@@ -17,19 +17,31 @@
#include "internal_macros.h"
#if !defined(HAVE_STD_REGEX) && \
!defined(HAVE_GNU_POSIX_REGEX) && \
!defined(HAVE_POSIX_REGEX)
// No explicit regex selection; detect based on builtin hints.
#if defined(BENCHMARK_OS_LINUX) || defined(BENCHMARK_OS_APPLE)
#define HAVE_POSIX_REGEX 1
#elif __cplusplus >= 199711L
#define HAVE_STD_REGEX 1
#endif
#endif
// Prefer C regex libraries when compiling w/o exceptions so that we can
// correctly report errors.
#if defined(BENCHMARK_HAS_NO_EXCEPTIONS) && defined(HAVE_STD_REGEX) && \
#if defined(BENCHMARK_HAS_NO_EXCEPTIONS) && \
defined(BENCHMARK_HAVE_STD_REGEX) && \
(defined(HAVE_GNU_POSIX_REGEX) || defined(HAVE_POSIX_REGEX))
#undef HAVE_STD_REGEX
#undef HAVE_STD_REGEX
#endif
#if defined(HAVE_STD_REGEX)
#include <regex>
#include <regex>
#elif defined(HAVE_GNU_POSIX_REGEX)
#include <gnuregex.h>
#include <gnuregex.h>
#elif defined(HAVE_POSIX_REGEX)
#include <regex.h>
#include <regex.h>
#else
#error No regular expression backend was found!
#endif
@@ -64,7 +76,7 @@ class Regex {
#elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX)
regex_t re_;
#else
#error No regular expression backend implementation available
#error No regular expression backend implementation available
#endif
};

6
benchmarks/thirdparty/benchmark/src/reporter.cc vendored Normal file → Executable file
View File

@@ -37,6 +37,9 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out,
Out << LocalDateTimeString() << "\n";
if (context.executable_name)
Out << "Running " << context.executable_name << "\n";
const CPUInfo &info = context.cpu_info;
Out << "Run on (" << info.num_cpus << " X "
<< (info.cycles_per_second / 1000000.0) << " MHz CPU "
@@ -64,6 +67,9 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out,
#endif
}
// No initializer because it's already initialized to NULL.
const char* BenchmarkReporter::Context::executable_name;
BenchmarkReporter::Context::Context() : cpu_info(CPUInfo::Get()) {}
double BenchmarkReporter::Run::GetAdjustedRealTime() const {

0
benchmarks/thirdparty/benchmark/src/sleep.cc vendored Normal file → Executable file
View File

0
benchmarks/thirdparty/benchmark/src/sleep.h vendored Normal file → Executable file
View File

25
benchmarks/thirdparty/benchmark/src/statistics.cc vendored Normal file → Executable file
View File

@@ -30,22 +30,25 @@ auto StatisticsSum = [](const std::vector<double>& v) {
};
double StatisticsMean(const std::vector<double>& v) {
if (v.size() == 0) return 0.0;
if (v.empty()) return 0.0;
return StatisticsSum(v) * (1.0 / v.size());
}
double StatisticsMedian(const std::vector<double>& v) {
if (v.size() < 3) return StatisticsMean(v);
std::vector<double> partial;
// we need roundDown(count/2)+1 slots
partial.resize(1 + (v.size() / 2));
std::partial_sort_copy(v.begin(), v.end(), partial.begin(), partial.end());
// did we have odd number of samples?
// if yes, then the last element of partially-sorted vector is the median
// it no, then the average of the last two elements is the median
std::vector<double> copy(v);
auto center = copy.begin() + v.size() / 2;
std::nth_element(copy.begin(), center, copy.end());
// did we have an odd number of samples?
// if yes, then center is the median
// it no, then we are looking for the average between center and the value before
if(v.size() % 2 == 1)
return partial.back();
return (partial[partial.size() - 2] + partial[partial.size() - 1]) / 2.0;
return *center;
auto center2 = copy.begin() + v.size() / 2 - 1;
std::nth_element(copy.begin(), center2, copy.end());
return (*center + *center2) / 2.0;
}
// Return the sum of the squares of this sample set
@@ -62,7 +65,7 @@ auto Sqrt = [](const double dat) {
double StatisticsStdDev(const std::vector<double>& v) {
const auto mean = StatisticsMean(v);
if (v.size() == 0) return mean;
if (v.empty()) return mean;
// Sample standard deviation is undefined for n = 1
if (v.size() == 1)

0
benchmarks/thirdparty/benchmark/src/statistics.h vendored Normal file → Executable file
View File

6
benchmarks/thirdparty/benchmark/src/string_util.cc vendored Normal file → Executable file
View File

@@ -122,7 +122,7 @@ std::string HumanReadableNumber(double n, double one_k) {
return ToBinaryStringFullySpecified(n, 1.1, 1, one_k);
}
std::string StringPrintFImp(const char* msg, va_list args) {
std::string StrFormatImp(const char* msg, va_list args) {
// we might need a second shot at this, so pre-emptivly make a copy
va_list args_cp;
va_copy(args_cp, args);
@@ -152,10 +152,10 @@ std::string StringPrintFImp(const char* msg, va_list args) {
return std::string(buff_ptr.get());
}
std::string StringPrintF(const char* format, ...) {
std::string StrFormat(const char* format, ...) {
va_list args;
va_start(args, format);
std::string tmp = StringPrintFImp(format, args);
std::string tmp = StrFormatImp(format, args);
va_end(args);
return tmp;
}

10
benchmarks/thirdparty/benchmark/src/string_util.h vendored Normal file → Executable file
View File

@@ -12,23 +12,23 @@ void AppendHumanReadable(int n, std::string* str);
std::string HumanReadableNumber(double n, double one_k = 1024.0);
std::string StringPrintF(const char* format, ...);
std::string StrFormat(const char* format, ...);
inline std::ostream& StringCatImp(std::ostream& out) BENCHMARK_NOEXCEPT {
inline std::ostream& StrCatImp(std::ostream& out) BENCHMARK_NOEXCEPT {
return out;
}
template <class First, class... Rest>
inline std::ostream& StringCatImp(std::ostream& out, First&& f,
inline std::ostream& StrCatImp(std::ostream& out, First&& f,
Rest&&... rest) {
out << std::forward<First>(f);
return StringCatImp(out, std::forward<Rest>(rest)...);
return StrCatImp(out, std::forward<Rest>(rest)...);
}
template <class... Args>
inline std::string StrCat(Args&&... args) {
std::ostringstream ss;
StringCatImp(ss, std::forward<Args>(args)...);
StrCatImp(ss, std::forward<Args>(args)...);
return ss.str();
}

78
benchmarks/thirdparty/benchmark/src/sysinfo.cc vendored Normal file → Executable file
View File

@@ -16,20 +16,26 @@
#ifdef BENCHMARK_OS_WINDOWS
#include <Shlwapi.h>
#undef StrCat // Don't let StrCat in string_util.h be renamed to lstrcatA
#include <VersionHelpers.h>
#include <Windows.h>
#else
#include <fcntl.h>
#ifndef BENCHMARK_OS_FUCHSIA
#include <sys/resource.h>
#endif
#include <sys/time.h>
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
#include <unistd.h>
#if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_MACOSX || \
defined BENCHMARK_OS_NETBSD
defined BENCHMARK_OS_NETBSD || defined BENCHMARK_OS_OPENBSD
#define BENCHMARK_HAS_SYSCTL
#include <sys/sysctl.h>
#endif
#endif
#if defined(BENCHMARK_OS_SOLARIS)
#include <kstat.h>
#endif
#include <algorithm>
#include <array>
@@ -130,6 +136,26 @@ struct ValueUnion {
};
ValueUnion GetSysctlImp(std::string const& Name) {
#if defined BENCHMARK_OS_OPENBSD
int mib[2];
mib[0] = CTL_HW;
if ((Name == "hw.ncpu") || (Name == "hw.cpuspeed")){
ValueUnion buff(sizeof(int));
if (Name == "hw.ncpu") {
mib[1] = HW_NCPU;
} else {
mib[1] = HW_CPUSPEED;
}
if (sysctl(mib, 2, buff.data(), &buff.Size, nullptr, 0) == -1) {
return ValueUnion();
}
return buff;
}
return ValueUnion();
#else
size_t CurBuffSize = 0;
if (sysctlbyname(Name.c_str(), nullptr, &CurBuffSize, nullptr, 0) == -1)
return ValueUnion();
@@ -138,6 +164,7 @@ ValueUnion GetSysctlImp(std::string const& Name) {
if (sysctlbyname(Name.c_str(), buff.data(), &buff.Size, nullptr, 0) == 0)
return buff;
return ValueUnion();
#endif
}
BENCHMARK_MAYBE_UNUSED
@@ -303,7 +330,7 @@ std::vector<CPUInfo::CacheInfo> GetCacheSizesWindows() {
if (!B.test(0)) continue;
CInfo* Cache = &it->Cache;
CPUInfo::CacheInfo C;
C.num_sharing = B.count();
C.num_sharing = static_cast<int>(B.count());
C.level = Cache->Level;
C.size = Cache->Size;
switch (Cache->Type) {
@@ -354,6 +381,15 @@ int GetNumCPUs() {
return sysinfo.dwNumberOfProcessors; // number of logical
// processors in the current
// group
#elif defined(BENCHMARK_OS_SOLARIS)
// Returns -1 in case of a failure.
int NumCPU = sysconf(_SC_NPROCESSORS_ONLN);
if (NumCPU < 0) {
fprintf(stderr,
"sysconf(_SC_NPROCESSORS_ONLN) failed with error: %s\n",
strerror(errno));
}
return NumCPU;
#else
int NumCPUs = 0;
int MaxID = -1;
@@ -441,7 +477,7 @@ double GetCPUCyclesPerSecond() {
std::string value;
if (SplitIdx != std::string::npos) value = ln.substr(SplitIdx + 1);
// When parsing the "cpu MHz" and "bogomips" (fallback) entries, we only
// accept postive values. Some environments (virtual machines) report zero,
// accept positive values. Some environments (virtual machines) report zero,
// which would cause infinite looping in WallTime_Init.
if (startsWithKey(ln, "cpu MHz")) {
if (!value.empty()) {
@@ -473,12 +509,17 @@ double GetCPUCyclesPerSecond() {
constexpr auto* FreqStr =
#if defined(BENCHMARK_OS_FREEBSD) || defined(BENCHMARK_OS_NETBSD)
"machdep.tsc_freq";
#elif defined BENCHMARK_OS_OPENBSD
"hw.cpuspeed";
#else
"hw.cpufrequency";
#endif
unsigned long long hz = 0;
#if defined BENCHMARK_OS_OPENBSD
if (GetSysctl(FreqStr, &hz)) return hz * 1000000;
#else
if (GetSysctl(FreqStr, &hz)) return hz;
#endif
fprintf(stderr, "Unable to determine clock rate from sysctl: %s: %s\n",
FreqStr, strerror(errno));
@@ -493,6 +534,35 @@ double GetCPUCyclesPerSecond() {
"~MHz", nullptr, &data, &data_size)))
return static_cast<double>((int64_t)data *
(int64_t)(1000 * 1000)); // was mhz
#elif defined (BENCHMARK_OS_SOLARIS)
kstat_ctl_t *kc = kstat_open();
if (!kc) {
std::cerr << "failed to open /dev/kstat\n";
return -1;
}
kstat_t *ksp = kstat_lookup(kc, (char*)"cpu_info", -1, (char*)"cpu_info0");
if (!ksp) {
std::cerr << "failed to lookup in /dev/kstat\n";
return -1;
}
if (kstat_read(kc, ksp, NULL) < 0) {
std::cerr << "failed to read from /dev/kstat\n";
return -1;
}
kstat_named_t *knp =
(kstat_named_t*)kstat_data_lookup(ksp, (char*)"current_clock_Hz");
if (!knp) {
std::cerr << "failed to lookup data in /dev/kstat\n";
return -1;
}
if (knp->data_type != KSTAT_DATA_UINT64) {
std::cerr << "current_clock_Hz is of unexpected data type: "
<< knp->data_type << "\n";
return -1;
}
double clock_hz = knp->value.ui64;
kstat_close(kc);
return clock_hz;
#endif
// If we've fallen through, attempt to roughly estimate the CPU clock rate.
const int estimate_time_ms = 1000;

View File

@@ -0,0 +1,66 @@
#ifndef BENCHMARK_THREAD_MANAGER_H
#define BENCHMARK_THREAD_MANAGER_H
#include <atomic>
#include "benchmark/benchmark.h"
#include "mutex.h"
namespace benchmark {
namespace internal {
class ThreadManager {
public:
ThreadManager(int num_threads)
: alive_threads_(num_threads), start_stop_barrier_(num_threads) {}
Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) {
return benchmark_mutex_;
}
bool StartStopBarrier() EXCLUDES(end_cond_mutex_) {
return start_stop_barrier_.wait();
}
void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) {
start_stop_barrier_.removeThread();
if (--alive_threads_ == 0) {
MutexLock lock(end_cond_mutex_);
end_condition_.notify_all();
}
}
void WaitForAllThreads() EXCLUDES(end_cond_mutex_) {
MutexLock lock(end_cond_mutex_);
end_condition_.wait(lock.native_handle(),
[this]() { return alive_threads_ == 0; });
}
public:
struct Result {
int64_t iterations = 0;
double real_time_used = 0;
double cpu_time_used = 0;
double manual_time_used = 0;
int64_t bytes_processed = 0;
int64_t items_processed = 0;
int64_t complexity_n = 0;
std::string report_label_;
std::string error_message_;
bool has_error_ = false;
UserCounters counters;
};
GUARDED_BY(GetBenchmarkMutex()) Result results;
private:
mutable Mutex benchmark_mutex_;
std::atomic<int> alive_threads_;
Barrier start_stop_barrier_;
Mutex end_cond_mutex_;
Condition end_condition_;
};
} // namespace internal
} // namespace benchmark
#endif // BENCHMARK_THREAD_MANAGER_H

View File

@@ -0,0 +1,69 @@
#ifndef BENCHMARK_THREAD_TIMER_H
#define BENCHMARK_THREAD_TIMER_H
#include "check.h"
#include "timers.h"
namespace benchmark {
namespace internal {
class ThreadTimer {
public:
ThreadTimer() = default;
// Called by each thread
void StartTimer() {
running_ = true;
start_real_time_ = ChronoClockNow();
start_cpu_time_ = ThreadCPUUsage();
}
// Called by each thread
void StopTimer() {
CHECK(running_);
running_ = false;
real_time_used_ += ChronoClockNow() - start_real_time_;
// Floating point error can result in the subtraction producing a negative
// time. Guard against that.
cpu_time_used_ += std::max<double>(ThreadCPUUsage() - start_cpu_time_, 0);
}
// Called by each thread
void SetIterationTime(double seconds) { manual_time_used_ += seconds; }
bool running() const { return running_; }
// REQUIRES: timer is not running
double real_time_used() {
CHECK(!running_);
return real_time_used_;
}
// REQUIRES: timer is not running
double cpu_time_used() {
CHECK(!running_);
return cpu_time_used_;
}
// REQUIRES: timer is not running
double manual_time_used() {
CHECK(!running_);
return manual_time_used_;
}
private:
bool running_ = false; // Is the timer running
double start_real_time_ = 0; // If running_
double start_cpu_time_ = 0; // If running_
// Accumulated time so far (does not contain current slice if running_)
double real_time_used_ = 0;
double cpu_time_used_ = 0;
// Manually set iteration time. User sets this with SetIterationTime(seconds).
double manual_time_used_ = 0;
};
} // namespace internal
} // namespace benchmark
#endif // BENCHMARK_THREAD_TIMER_H

11
benchmarks/thirdparty/benchmark/src/timers.cc vendored Normal file → Executable file
View File

@@ -17,11 +17,14 @@
#ifdef BENCHMARK_OS_WINDOWS
#include <Shlwapi.h>
#undef StrCat // Don't let StrCat in string_util.h be renamed to lstrcatA
#include <VersionHelpers.h>
#include <Windows.h>
#else
#include <fcntl.h>
#ifndef BENCHMARK_OS_FUCHSIA
#include <sys/resource.h>
#endif
#include <sys/time.h>
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
#include <unistd.h>
@@ -74,7 +77,7 @@ double MakeTime(FILETIME const& kernel_time, FILETIME const& user_time) {
static_cast<double>(user.QuadPart)) *
1e-7;
}
#else
#elif !defined(BENCHMARK_OS_FUCHSIA)
double MakeTime(struct rusage const& ru) {
return (static_cast<double>(ru.ru_utime.tv_sec) +
static_cast<double>(ru.ru_utime.tv_usec) * 1e-6 +
@@ -162,6 +165,10 @@ double ThreadCPUUsage() {
// RTEMS doesn't support CLOCK_THREAD_CPUTIME_ID. See
// https://github.com/RTEMS/rtems/blob/master/cpukit/posix/src/clockgettime.c
return ProcessCPUUsage();
#elif defined(BENCHMARK_OS_SOLARIS)
struct rusage ru;
if (getrusage(RUSAGE_LWP, &ru) == 0) return MakeTime(ru);
DiagnoseAndExit("getrusage(RUSAGE_LWP, ...) failed");
#elif defined(CLOCK_THREAD_CPUTIME_ID)
struct timespec ts;
if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) return MakeTime(ts);
@@ -186,7 +193,6 @@ std::string DateTimeString(bool local) {
std::strftime(storage, sizeof(storage), "%x %X", ::localtime(&now));
#else
std::tm timeinfo;
std::memset(&timeinfo, 0, sizeof(std::tm));
::localtime_r(&now, &timeinfo);
written = std::strftime(storage, sizeof(storage), "%F %T", &timeinfo);
#endif
@@ -195,7 +201,6 @@ std::string DateTimeString(bool local) {
written = std::strftime(storage, sizeof(storage), "%x %X", ::gmtime(&now));
#else
std::tm timeinfo;
std::memset(&timeinfo, 0, sizeof(std::tm));
::gmtime_r(&now, &timeinfo);
written = std::strftime(storage, sizeof(storage), "%F %T", &timeinfo);
#endif

0
benchmarks/thirdparty/benchmark/src/timers.h vendored Normal file → Executable file
View File

View File

@@ -0,0 +1,316 @@
#!/usr/bin/env python
"""
compare.py - versatile benchmark output compare tool
"""
import argparse
from argparse import ArgumentParser
import sys
import gbench
from gbench import util, report
from gbench.util import *
def check_inputs(in1, in2, flags):
"""
Perform checking on the user provided inputs and diagnose any abnormalities
"""
in1_kind, in1_err = classify_input_file(in1)
in2_kind, in2_err = classify_input_file(in2)
output_file = find_benchmark_flag('--benchmark_out=', flags)
output_type = find_benchmark_flag('--benchmark_out_format=', flags)
if in1_kind == IT_Executable and in2_kind == IT_Executable and output_file:
print(("WARNING: '--benchmark_out=%s' will be passed to both "
"benchmarks causing it to be overwritten") % output_file)
if in1_kind == IT_JSON and in2_kind == IT_JSON and len(flags) > 0:
print("WARNING: passing optional flags has no effect since both "
"inputs are JSON")
if output_type is not None and output_type != 'json':
print(("ERROR: passing '--benchmark_out_format=%s' to 'compare.py`"
" is not supported.") % output_type)
sys.exit(1)
def create_parser():
parser = ArgumentParser(
description='versatile benchmark output compare tool')
subparsers = parser.add_subparsers(
help='This tool has multiple modes of operation:',
dest='mode')
parser_a = subparsers.add_parser(
'benchmarks',
help='The most simple use-case, compare all the output of these two benchmarks')
baseline = parser_a.add_argument_group(
'baseline', 'The benchmark baseline')
baseline.add_argument(
'test_baseline',
metavar='test_baseline',
type=argparse.FileType('r'),
nargs=1,
help='A benchmark executable or JSON output file')
contender = parser_a.add_argument_group(
'contender', 'The benchmark that will be compared against the baseline')
contender.add_argument(
'test_contender',
metavar='test_contender',
type=argparse.FileType('r'),
nargs=1,
help='A benchmark executable or JSON output file')
parser_a.add_argument(
'benchmark_options',
metavar='benchmark_options',
nargs=argparse.REMAINDER,
help='Arguments to pass when running benchmark executables')
parser_b = subparsers.add_parser(
'filters', help='Compare filter one with the filter two of benchmark')
baseline = parser_b.add_argument_group(
'baseline', 'The benchmark baseline')
baseline.add_argument(
'test',
metavar='test',
type=argparse.FileType('r'),
nargs=1,
help='A benchmark executable or JSON output file')
baseline.add_argument(
'filter_baseline',
metavar='filter_baseline',
type=str,
nargs=1,
help='The first filter, that will be used as baseline')
contender = parser_b.add_argument_group(
'contender', 'The benchmark that will be compared against the baseline')
contender.add_argument(
'filter_contender',
metavar='filter_contender',
type=str,
nargs=1,
help='The second filter, that will be compared against the baseline')
parser_b.add_argument(
'benchmark_options',
metavar='benchmark_options',
nargs=argparse.REMAINDER,
help='Arguments to pass when running benchmark executables')
parser_c = subparsers.add_parser(
'benchmarksfiltered',
help='Compare filter one of first benchmark with filter two of the second benchmark')
baseline = parser_c.add_argument_group(
'baseline', 'The benchmark baseline')
baseline.add_argument(
'test_baseline',
metavar='test_baseline',
type=argparse.FileType('r'),
nargs=1,
help='A benchmark executable or JSON output file')
baseline.add_argument(
'filter_baseline',
metavar='filter_baseline',
type=str,
nargs=1,
help='The first filter, that will be used as baseline')
contender = parser_c.add_argument_group(
'contender', 'The benchmark that will be compared against the baseline')
contender.add_argument(
'test_contender',
metavar='test_contender',
type=argparse.FileType('r'),
nargs=1,
help='The second benchmark executable or JSON output file, that will be compared against the baseline')
contender.add_argument(
'filter_contender',
metavar='filter_contender',
type=str,
nargs=1,
help='The second filter, that will be compared against the baseline')
parser_c.add_argument(
'benchmark_options',
metavar='benchmark_options',
nargs=argparse.REMAINDER,
help='Arguments to pass when running benchmark executables')
return parser
def main():
# Parse the command line flags
parser = create_parser()
args, unknown_args = parser.parse_known_args()
if args.mode is None:
parser.print_help()
exit(1)
assert not unknown_args
benchmark_options = args.benchmark_options
if args.mode == 'benchmarks':
test_baseline = args.test_baseline[0].name
test_contender = args.test_contender[0].name
filter_baseline = ''
filter_contender = ''
# NOTE: if test_baseline == test_contender, you are analyzing the stdev
description = 'Comparing %s to %s' % (test_baseline, test_contender)
elif args.mode == 'filters':
test_baseline = args.test[0].name
test_contender = args.test[0].name
filter_baseline = args.filter_baseline[0]
filter_contender = args.filter_contender[0]
# NOTE: if filter_baseline == filter_contender, you are analyzing the
# stdev
description = 'Comparing %s to %s (from %s)' % (
filter_baseline, filter_contender, args.test[0].name)
elif args.mode == 'benchmarksfiltered':
test_baseline = args.test_baseline[0].name
test_contender = args.test_contender[0].name
filter_baseline = args.filter_baseline[0]
filter_contender = args.filter_contender[0]
# NOTE: if test_baseline == test_contender and
# filter_baseline == filter_contender, you are analyzing the stdev
description = 'Comparing %s (from %s) to %s (from %s)' % (
filter_baseline, test_baseline, filter_contender, test_contender)
else:
# should never happen
print("Unrecognized mode of operation: '%s'" % args.mode)
parser.print_help()
exit(1)
check_inputs(test_baseline, test_contender, benchmark_options)
options_baseline = []
options_contender = []
if filter_baseline and filter_contender:
options_baseline = ['--benchmark_filter=%s' % filter_baseline]
options_contender = ['--benchmark_filter=%s' % filter_contender]
# Run the benchmarks and report the results
json1 = json1_orig = gbench.util.run_or_load_benchmark(
test_baseline, benchmark_options + options_baseline)
json2 = json2_orig = gbench.util.run_or_load_benchmark(
test_contender, benchmark_options + options_contender)
# Now, filter the benchmarks so that the difference report can work
if filter_baseline and filter_contender:
replacement = '[%s vs. %s]' % (filter_baseline, filter_contender)
json1 = gbench.report.filter_benchmark(
json1_orig, filter_baseline, replacement)
json2 = gbench.report.filter_benchmark(
json2_orig, filter_contender, replacement)
# Diff and output
output_lines = gbench.report.generate_difference_report(json1, json2)
print(description)
for ln in output_lines:
print(ln)
import unittest
class TestParser(unittest.TestCase):
def setUp(self):
self.parser = create_parser()
testInputs = os.path.join(
os.path.dirname(
os.path.realpath(__file__)),
'gbench',
'Inputs')
self.testInput0 = os.path.join(testInputs, 'test1_run1.json')
self.testInput1 = os.path.join(testInputs, 'test1_run2.json')
def test_benchmarks_basic(self):
parsed = self.parser.parse_args(
['benchmarks', self.testInput0, self.testInput1])
self.assertEqual(parsed.mode, 'benchmarks')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertFalse(parsed.benchmark_options)
def test_benchmarks_with_remainder(self):
parsed = self.parser.parse_args(
['benchmarks', self.testInput0, self.testInput1, 'd'])
self.assertEqual(parsed.mode, 'benchmarks')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertEqual(parsed.benchmark_options, ['d'])
def test_benchmarks_with_remainder_after_doubleminus(self):
parsed = self.parser.parse_args(
['benchmarks', self.testInput0, self.testInput1, '--', 'e'])
self.assertEqual(parsed.mode, 'benchmarks')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertEqual(parsed.benchmark_options, ['e'])
def test_filters_basic(self):
parsed = self.parser.parse_args(
['filters', self.testInput0, 'c', 'd'])
self.assertEqual(parsed.mode, 'filters')
self.assertEqual(parsed.test[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], 'c')
self.assertEqual(parsed.filter_contender[0], 'd')
self.assertFalse(parsed.benchmark_options)
def test_filters_with_remainder(self):
parsed = self.parser.parse_args(
['filters', self.testInput0, 'c', 'd', 'e'])
self.assertEqual(parsed.mode, 'filters')
self.assertEqual(parsed.test[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], 'c')
self.assertEqual(parsed.filter_contender[0], 'd')
self.assertEqual(parsed.benchmark_options, ['e'])
def test_filters_with_remainder_after_doubleminus(self):
parsed = self.parser.parse_args(
['filters', self.testInput0, 'c', 'd', '--', 'f'])
self.assertEqual(parsed.mode, 'filters')
self.assertEqual(parsed.test[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], 'c')
self.assertEqual(parsed.filter_contender[0], 'd')
self.assertEqual(parsed.benchmark_options, ['f'])
def test_benchmarksfiltered_basic(self):
parsed = self.parser.parse_args(
['benchmarksfiltered', self.testInput0, 'c', self.testInput1, 'e'])
self.assertEqual(parsed.mode, 'benchmarksfiltered')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], 'c')
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertEqual(parsed.filter_contender[0], 'e')
self.assertFalse(parsed.benchmark_options)
def test_benchmarksfiltered_with_remainder(self):
parsed = self.parser.parse_args(
['benchmarksfiltered', self.testInput0, 'c', self.testInput1, 'e', 'f'])
self.assertEqual(parsed.mode, 'benchmarksfiltered')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], 'c')
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertEqual(parsed.filter_contender[0], 'e')
self.assertEqual(parsed.benchmark_options[0], 'f')
def test_benchmarksfiltered_with_remainder_after_doubleminus(self):
parsed = self.parser.parse_args(
['benchmarksfiltered', self.testInput0, 'c', self.testInput1, 'e', '--', 'g'])
self.assertEqual(parsed.mode, 'benchmarksfiltered')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], 'c')
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertEqual(parsed.filter_contender[0], 'e')
self.assertEqual(parsed.benchmark_options[0], 'g')
if __name__ == '__main__':
# unittest.main()
main()
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
# kate: tab-width: 4; replace-tabs on; indent-width 4; tab-indents: off;
# kate: indent-mode python; remove-trailing-spaces modified;

View File

@@ -0,0 +1,67 @@
#!/usr/bin/env python
"""
compare_bench.py - Compare two benchmarks or their results and report the
difference.
"""
import argparse
from argparse import ArgumentParser
import sys
import gbench
from gbench import util, report
from gbench.util import *
def check_inputs(in1, in2, flags):
"""
Perform checking on the user provided inputs and diagnose any abnormalities
"""
in1_kind, in1_err = classify_input_file(in1)
in2_kind, in2_err = classify_input_file(in2)
output_file = find_benchmark_flag('--benchmark_out=', flags)
output_type = find_benchmark_flag('--benchmark_out_format=', flags)
if in1_kind == IT_Executable and in2_kind == IT_Executable and output_file:
print(("WARNING: '--benchmark_out=%s' will be passed to both "
"benchmarks causing it to be overwritten") % output_file)
if in1_kind == IT_JSON and in2_kind == IT_JSON and len(flags) > 0:
print("WARNING: passing --benchmark flags has no effect since both "
"inputs are JSON")
if output_type is not None and output_type != 'json':
print(("ERROR: passing '--benchmark_out_format=%s' to 'compare_bench.py`"
" is not supported.") % output_type)
sys.exit(1)
def main():
parser = ArgumentParser(
description='compare the results of two benchmarks')
parser.add_argument(
'test1', metavar='test1', type=str, nargs=1,
help='A benchmark executable or JSON output file')
parser.add_argument(
'test2', metavar='test2', type=str, nargs=1,
help='A benchmark executable or JSON output file')
parser.add_argument(
'benchmark_options', metavar='benchmark_options', nargs=argparse.REMAINDER,
help='Arguments to pass when running benchmark executables'
)
args, unknown_args = parser.parse_known_args()
# Parse the command line flags
test1 = args.test1[0]
test2 = args.test2[0]
if unknown_args:
# should never happen
print("Unrecognized positional argument arguments: '%s'"
% unknown_args)
exit(1)
benchmark_options = args.benchmark_options
check_inputs(test1, test2, benchmark_options)
# Run the benchmarks and report the results
json1 = gbench.util.run_or_load_benchmark(test1, benchmark_options)
json2 = gbench.util.run_or_load_benchmark(test2, benchmark_options)
output_lines = gbench.report.generate_difference_report(json1, json2)
print('Comparing %s to %s' % (test1, test2))
for ln in output_lines:
print(ln)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,102 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "BM_SameTimes",
"iterations": 1000,
"real_time": 10,
"cpu_time": 10,
"time_unit": "ns"
},
{
"name": "BM_2xFaster",
"iterations": 1000,
"real_time": 50,
"cpu_time": 50,
"time_unit": "ns"
},
{
"name": "BM_2xSlower",
"iterations": 1000,
"real_time": 50,
"cpu_time": 50,
"time_unit": "ns"
},
{
"name": "BM_1PercentFaster",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_1PercentSlower",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_10PercentFaster",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_10PercentSlower",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_100xSlower",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_100xFaster",
"iterations": 1000,
"real_time": 10000,
"cpu_time": 10000,
"time_unit": "ns"
},
{
"name": "BM_10PercentCPUToTime",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_ThirdFaster",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_BadTimeUnit",
"iterations": 1000,
"real_time": 0.4,
"cpu_time": 0.5,
"time_unit": "s"
},
{
"name": "BM_DifferentTimeUnit",
"iterations": 1,
"real_time": 1,
"cpu_time": 1,
"time_unit": "s"
}
]
}

View File

@@ -0,0 +1,102 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "BM_SameTimes",
"iterations": 1000,
"real_time": 10,
"cpu_time": 10,
"time_unit": "ns"
},
{
"name": "BM_2xFaster",
"iterations": 1000,
"real_time": 25,
"cpu_time": 25,
"time_unit": "ns"
},
{
"name": "BM_2xSlower",
"iterations": 20833333,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_1PercentFaster",
"iterations": 1000,
"real_time": 98.9999999,
"cpu_time": 98.9999999,
"time_unit": "ns"
},
{
"name": "BM_1PercentSlower",
"iterations": 1000,
"real_time": 100.9999999,
"cpu_time": 100.9999999,
"time_unit": "ns"
},
{
"name": "BM_10PercentFaster",
"iterations": 1000,
"real_time": 90,
"cpu_time": 90,
"time_unit": "ns"
},
{
"name": "BM_10PercentSlower",
"iterations": 1000,
"real_time": 110,
"cpu_time": 110,
"time_unit": "ns"
},
{
"name": "BM_100xSlower",
"iterations": 1000,
"real_time": 1.0000e+04,
"cpu_time": 1.0000e+04,
"time_unit": "ns"
},
{
"name": "BM_100xFaster",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_10PercentCPUToTime",
"iterations": 1000,
"real_time": 110,
"cpu_time": 90,
"time_unit": "ns"
},
{
"name": "BM_ThirdFaster",
"iterations": 1000,
"real_time": 66.665,
"cpu_time": 66.664,
"time_unit": "ns"
},
{
"name": "BM_BadTimeUnit",
"iterations": 1000,
"real_time": 0.04,
"cpu_time": 0.6,
"time_unit": "s"
},
{
"name": "BM_DifferentTimeUnit",
"iterations": 1,
"real_time": 1,
"cpu_time": 1,
"time_unit": "ns"
}
]
}

View File

@@ -0,0 +1,81 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "BM_Hi",
"iterations": 1234,
"real_time": 42,
"cpu_time": 24,
"time_unit": "ms"
},
{
"name": "BM_Zero",
"iterations": 1000,
"real_time": 10,
"cpu_time": 10,
"time_unit": "ns"
},
{
"name": "BM_Zero/4",
"iterations": 4000,
"real_time": 40,
"cpu_time": 40,
"time_unit": "ns"
},
{
"name": "Prefix/BM_Zero",
"iterations": 2000,
"real_time": 20,
"cpu_time": 20,
"time_unit": "ns"
},
{
"name": "Prefix/BM_Zero/3",
"iterations": 3000,
"real_time": 30,
"cpu_time": 30,
"time_unit": "ns"
},
{
"name": "BM_One",
"iterations": 5000,
"real_time": 5,
"cpu_time": 5,
"time_unit": "ns"
},
{
"name": "BM_One/4",
"iterations": 2000,
"real_time": 20,
"cpu_time": 20,
"time_unit": "ns"
},
{
"name": "Prefix/BM_One",
"iterations": 1000,
"real_time": 10,
"cpu_time": 10,
"time_unit": "ns"
},
{
"name": "Prefix/BM_One/3",
"iterations": 1500,
"real_time": 15,
"cpu_time": 15,
"time_unit": "ns"
},
{
"name": "BM_Bye",
"iterations": 5321,
"real_time": 11,
"cpu_time": 63,
"time_unit": "ns"
}
]
}

View File

@@ -0,0 +1,8 @@
"""Google Benchmark tooling"""
__author__ = 'Eric Fiselier'
__email__ = 'eric@efcs.ca'
__versioninfo__ = (0, 5, 0)
__version__ = '.'.join(str(v) for v in __versioninfo__) + 'dev'
__all__ = []

View File

@@ -0,0 +1,208 @@
"""report.py - Utilities for reporting statistics about benchmark results
"""
import os
import re
import copy
class BenchmarkColor(object):
def __init__(self, name, code):
self.name = name
self.code = code
def __repr__(self):
return '%s%r' % (self.__class__.__name__,
(self.name, self.code))
def __format__(self, format):
return self.code
# Benchmark Colors Enumeration
BC_NONE = BenchmarkColor('NONE', '')
BC_MAGENTA = BenchmarkColor('MAGENTA', '\033[95m')
BC_CYAN = BenchmarkColor('CYAN', '\033[96m')
BC_OKBLUE = BenchmarkColor('OKBLUE', '\033[94m')
BC_HEADER = BenchmarkColor('HEADER', '\033[92m')
BC_WARNING = BenchmarkColor('WARNING', '\033[93m')
BC_WHITE = BenchmarkColor('WHITE', '\033[97m')
BC_FAIL = BenchmarkColor('FAIL', '\033[91m')
BC_ENDC = BenchmarkColor('ENDC', '\033[0m')
BC_BOLD = BenchmarkColor('BOLD', '\033[1m')
BC_UNDERLINE = BenchmarkColor('UNDERLINE', '\033[4m')
def color_format(use_color, fmt_str, *args, **kwargs):
"""
Return the result of 'fmt_str.format(*args, **kwargs)' after transforming
'args' and 'kwargs' according to the value of 'use_color'. If 'use_color'
is False then all color codes in 'args' and 'kwargs' are replaced with
the empty string.
"""
assert use_color is True or use_color is False
if not use_color:
args = [arg if not isinstance(arg, BenchmarkColor) else BC_NONE
for arg in args]
kwargs = {key: arg if not isinstance(arg, BenchmarkColor) else BC_NONE
for key, arg in kwargs.items()}
return fmt_str.format(*args, **kwargs)
def find_longest_name(benchmark_list):
"""
Return the length of the longest benchmark name in a given list of
benchmark JSON objects
"""
longest_name = 1
for bc in benchmark_list:
if len(bc['name']) > longest_name:
longest_name = len(bc['name'])
return longest_name
def calculate_change(old_val, new_val):
"""
Return a float representing the decimal change between old_val and new_val.
"""
if old_val == 0 and new_val == 0:
return 0.0
if old_val == 0:
return float(new_val - old_val) / (float(old_val + new_val) / 2)
return float(new_val - old_val) / abs(old_val)
def filter_benchmark(json_orig, family, replacement=""):
"""
Apply a filter to the json, and only leave the 'family' of benchmarks.
"""
regex = re.compile(family)
filtered = {}
filtered['benchmarks'] = []
for be in json_orig['benchmarks']:
if not regex.search(be['name']):
continue
filteredbench = copy.deepcopy(be) # Do NOT modify the old name!
filteredbench['name'] = regex.sub(replacement, filteredbench['name'])
filtered['benchmarks'].append(filteredbench)
return filtered
def generate_difference_report(json1, json2, use_color=True):
"""
Calculate and report the difference between each test of two benchmarks
runs specified as 'json1' and 'json2'.
"""
first_col_width = find_longest_name(json1['benchmarks'])
def find_test(name):
for b in json2['benchmarks']:
if b['name'] == name:
return b
return None
first_col_width = max(first_col_width, len('Benchmark'))
first_line = "{:<{}s}Time CPU Time Old Time New CPU Old CPU New".format(
'Benchmark', 12 + first_col_width)
output_strs = [first_line, '-' * len(first_line)]
gen = (bn for bn in json1['benchmarks'] if 'real_time' in bn and 'cpu_time' in bn)
for bn in gen:
other_bench = find_test(bn['name'])
if not other_bench:
continue
if bn['time_unit'] != other_bench['time_unit']:
continue
def get_color(res):
if res > 0.05:
return BC_FAIL
elif res > -0.07:
return BC_WHITE
else:
return BC_CYAN
fmt_str = "{}{:<{}s}{endc}{}{:+16.4f}{endc}{}{:+16.4f}{endc}{:14.0f}{:14.0f}{endc}{:14.0f}{:14.0f}"
tres = calculate_change(bn['real_time'], other_bench['real_time'])
cpures = calculate_change(bn['cpu_time'], other_bench['cpu_time'])
output_strs += [color_format(use_color, fmt_str,
BC_HEADER, bn['name'], first_col_width,
get_color(tres), tres, get_color(cpures), cpures,
bn['real_time'], other_bench['real_time'],
bn['cpu_time'], other_bench['cpu_time'],
endc=BC_ENDC)]
return output_strs
###############################################################################
# Unit tests
import unittest
class TestReportDifference(unittest.TestCase):
def load_results(self):
import json
testInputs = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Inputs')
testOutput1 = os.path.join(testInputs, 'test1_run1.json')
testOutput2 = os.path.join(testInputs, 'test1_run2.json')
with open(testOutput1, 'r') as f:
json1 = json.load(f)
with open(testOutput2, 'r') as f:
json2 = json.load(f)
return json1, json2
def test_basic(self):
expect_lines = [
['BM_SameTimes', '+0.0000', '+0.0000', '10', '10', '10', '10'],
['BM_2xFaster', '-0.5000', '-0.5000', '50', '25', '50', '25'],
['BM_2xSlower', '+1.0000', '+1.0000', '50', '100', '50', '100'],
['BM_1PercentFaster', '-0.0100', '-0.0100', '100', '99', '100', '99'],
['BM_1PercentSlower', '+0.0100', '+0.0100', '100', '101', '100', '101'],
['BM_10PercentFaster', '-0.1000', '-0.1000', '100', '90', '100', '90'],
['BM_10PercentSlower', '+0.1000', '+0.1000', '100', '110', '100', '110'],
['BM_100xSlower', '+99.0000', '+99.0000', '100', '10000', '100', '10000'],
['BM_100xFaster', '-0.9900', '-0.9900', '10000', '100', '10000', '100'],
['BM_10PercentCPUToTime', '+0.1000', '-0.1000', '100', '110', '100', '90'],
['BM_ThirdFaster', '-0.3333', '-0.3334', '100', '67', '100', '67'],
['BM_BadTimeUnit', '-0.9000', '+0.2000', '0', '0', '0', '1'],
]
json1, json2 = self.load_results()
output_lines_with_header = generate_difference_report(json1, json2, use_color=False)
output_lines = output_lines_with_header[2:]
print("\n".join(output_lines_with_header))
self.assertEqual(len(output_lines), len(expect_lines))
for i in range(0, len(output_lines)):
parts = [x for x in output_lines[i].split(' ') if x]
self.assertEqual(len(parts), 7)
self.assertEqual(parts, expect_lines[i])
class TestReportDifferenceBetweenFamilies(unittest.TestCase):
def load_result(self):
import json
testInputs = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Inputs')
testOutput = os.path.join(testInputs, 'test2_run.json')
with open(testOutput, 'r') as f:
json = json.load(f)
return json
def test_basic(self):
expect_lines = [
['.', '-0.5000', '-0.5000', '10', '5', '10', '5'],
['./4', '-0.5000', '-0.5000', '40', '20', '40', '20'],
['Prefix/.', '-0.5000', '-0.5000', '20', '10', '20', '10'],
['Prefix/./3', '-0.5000', '-0.5000', '30', '15', '30', '15'],
]
json = self.load_result()
json1 = filter_benchmark(json, "BM_Z.ro", ".")
json2 = filter_benchmark(json, "BM_O.e", ".")
output_lines_with_header = generate_difference_report(json1, json2, use_color=False)
output_lines = output_lines_with_header[2:]
print("\n")
print("\n".join(output_lines_with_header))
self.assertEqual(len(output_lines), len(expect_lines))
for i in range(0, len(output_lines)):
parts = [x for x in output_lines[i].split(' ') if x]
self.assertEqual(len(parts), 7)
self.assertEqual(parts, expect_lines[i])
if __name__ == '__main__':
unittest.main()
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
# kate: tab-width: 4; replace-tabs on; indent-width 4; tab-indents: off;
# kate: indent-mode python; remove-trailing-spaces modified;

View File

@@ -0,0 +1,159 @@
"""util.py - General utilities for running, loading, and processing benchmarks
"""
import json
import os
import tempfile
import subprocess
import sys
# Input file type enumeration
IT_Invalid = 0
IT_JSON = 1
IT_Executable = 2
_num_magic_bytes = 2 if sys.platform.startswith('win') else 4
def is_executable_file(filename):
"""
Return 'True' if 'filename' names a valid file which is likely
an executable. A file is considered an executable if it starts with the
magic bytes for a EXE, Mach O, or ELF file.
"""
if not os.path.isfile(filename):
return False
with open(filename, mode='rb') as f:
magic_bytes = f.read(_num_magic_bytes)
if sys.platform == 'darwin':
return magic_bytes in [
b'\xfe\xed\xfa\xce', # MH_MAGIC
b'\xce\xfa\xed\xfe', # MH_CIGAM
b'\xfe\xed\xfa\xcf', # MH_MAGIC_64
b'\xcf\xfa\xed\xfe', # MH_CIGAM_64
b'\xca\xfe\xba\xbe', # FAT_MAGIC
b'\xbe\xba\xfe\xca' # FAT_CIGAM
]
elif sys.platform.startswith('win'):
return magic_bytes == b'MZ'
else:
return magic_bytes == b'\x7FELF'
def is_json_file(filename):
"""
Returns 'True' if 'filename' names a valid JSON output file.
'False' otherwise.
"""
try:
with open(filename, 'r') as f:
json.load(f)
return True
except:
pass
return False
def classify_input_file(filename):
"""
Return a tuple (type, msg) where 'type' specifies the classified type
of 'filename'. If 'type' is 'IT_Invalid' then 'msg' is a human readable
string represeting the error.
"""
ftype = IT_Invalid
err_msg = None
if not os.path.exists(filename):
err_msg = "'%s' does not exist" % filename
elif not os.path.isfile(filename):
err_msg = "'%s' does not name a file" % filename
elif is_executable_file(filename):
ftype = IT_Executable
elif is_json_file(filename):
ftype = IT_JSON
else:
err_msg = "'%s' does not name a valid benchmark executable or JSON file" % filename
return ftype, err_msg
def check_input_file(filename):
"""
Classify the file named by 'filename' and return the classification.
If the file is classified as 'IT_Invalid' print an error message and exit
the program.
"""
ftype, msg = classify_input_file(filename)
if ftype == IT_Invalid:
print("Invalid input file: %s" % msg)
sys.exit(1)
return ftype
def find_benchmark_flag(prefix, benchmark_flags):
"""
Search the specified list of flags for a flag matching `<prefix><arg>` and
if it is found return the arg it specifies. If specified more than once the
last value is returned. If the flag is not found None is returned.
"""
assert prefix.startswith('--') and prefix.endswith('=')
result = None
for f in benchmark_flags:
if f.startswith(prefix):
result = f[len(prefix):]
return result
def remove_benchmark_flags(prefix, benchmark_flags):
"""
Return a new list containing the specified benchmark_flags except those
with the specified prefix.
"""
assert prefix.startswith('--') and prefix.endswith('=')
return [f for f in benchmark_flags if not f.startswith(prefix)]
def load_benchmark_results(fname):
"""
Read benchmark output from a file and return the JSON object.
REQUIRES: 'fname' names a file containing JSON benchmark output.
"""
with open(fname, 'r') as f:
return json.load(f)
def run_benchmark(exe_name, benchmark_flags):
"""
Run a benchmark specified by 'exe_name' with the specified
'benchmark_flags'. The benchmark is run directly as a subprocess to preserve
real time console output.
RETURNS: A JSON object representing the benchmark output
"""
output_name = find_benchmark_flag('--benchmark_out=',
benchmark_flags)
is_temp_output = False
if output_name is None:
is_temp_output = True
thandle, output_name = tempfile.mkstemp()
os.close(thandle)
benchmark_flags = list(benchmark_flags) + \
['--benchmark_out=%s' % output_name]
cmd = [exe_name] + benchmark_flags
print("RUNNING: %s" % ' '.join(cmd))
exitCode = subprocess.call(cmd)
if exitCode != 0:
print('TEST FAILED...')
sys.exit(exitCode)
json_res = load_benchmark_results(output_name)
if is_temp_output:
os.unlink(output_name)
return json_res
def run_or_load_benchmark(filename, benchmark_flags):
"""
Get the results for a specified benchmark. If 'filename' specifies
an executable benchmark then the results are generated by running the
benchmark. Otherwise 'filename' must name a valid JSON output file,
which is loaded and the result returned.
"""
ftype = check_input_file(filename)
if ftype == IT_JSON:
return load_benchmark_results(filename)
elif ftype == IT_Executable:
return run_benchmark(filename, benchmark_flags)
else:
assert False # This branch is unreachable

View File

@@ -0,0 +1,151 @@
#!/usr/bin/env python
"""
strip_asm.py - Cleanup ASM output for the specified file
"""
from argparse import ArgumentParser
import sys
import os
import re
def find_used_labels(asm):
found = set()
label_re = re.compile("\s*j[a-z]+\s+\.L([a-zA-Z0-9][a-zA-Z0-9_]*)")
for l in asm.splitlines():
m = label_re.match(l)
if m:
found.add('.L%s' % m.group(1))
return found
def normalize_labels(asm):
decls = set()
label_decl = re.compile("^[.]{0,1}L([a-zA-Z0-9][a-zA-Z0-9_]*)(?=:)")
for l in asm.splitlines():
m = label_decl.match(l)
if m:
decls.add(m.group(0))
if len(decls) == 0:
return asm
needs_dot = next(iter(decls))[0] != '.'
if not needs_dot:
return asm
for ld in decls:
asm = re.sub("(^|\s+)" + ld + "(?=:|\s)", '\\1.' + ld, asm)
return asm
def transform_labels(asm):
asm = normalize_labels(asm)
used_decls = find_used_labels(asm)
new_asm = ''
label_decl = re.compile("^\.L([a-zA-Z0-9][a-zA-Z0-9_]*)(?=:)")
for l in asm.splitlines():
m = label_decl.match(l)
if not m or m.group(0) in used_decls:
new_asm += l
new_asm += '\n'
return new_asm
def is_identifier(tk):
if len(tk) == 0:
return False
first = tk[0]
if not first.isalpha() and first != '_':
return False
for i in range(1, len(tk)):
c = tk[i]
if not c.isalnum() and c != '_':
return False
return True
def process_identifiers(l):
"""
process_identifiers - process all identifiers and modify them to have
consistent names across all platforms; specifically across ELF and MachO.
For example, MachO inserts an additional understore at the beginning of
names. This function removes that.
"""
parts = re.split(r'([a-zA-Z0-9_]+)', l)
new_line = ''
for tk in parts:
if is_identifier(tk):
if tk.startswith('__Z'):
tk = tk[1:]
elif tk.startswith('_') and len(tk) > 1 and \
tk[1].isalpha() and tk[1] != 'Z':
tk = tk[1:]
new_line += tk
return new_line
def process_asm(asm):
"""
Strip the ASM of unwanted directives and lines
"""
new_contents = ''
asm = transform_labels(asm)
# TODO: Add more things we want to remove
discard_regexes = [
re.compile("\s+\..*$"), # directive
re.compile("\s*#(NO_APP|APP)$"), #inline ASM
re.compile("\s*#.*$"), # comment line
re.compile("\s*\.globa?l\s*([.a-zA-Z_][a-zA-Z0-9$_.]*)"), #global directive
re.compile("\s*\.(string|asciz|ascii|[1248]?byte|short|word|long|quad|value|zero)"),
]
keep_regexes = [
]
fn_label_def = re.compile("^[a-zA-Z_][a-zA-Z0-9_.]*:")
for l in asm.splitlines():
# Remove Mach-O attribute
l = l.replace('@GOTPCREL', '')
add_line = True
for reg in discard_regexes:
if reg.match(l) is not None:
add_line = False
break
for reg in keep_regexes:
if reg.match(l) is not None:
add_line = True
break
if add_line:
if fn_label_def.match(l) and len(new_contents) != 0:
new_contents += '\n'
l = process_identifiers(l)
new_contents += l
new_contents += '\n'
return new_contents
def main():
parser = ArgumentParser(
description='generate a stripped assembly file')
parser.add_argument(
'input', metavar='input', type=str, nargs=1,
help='An input assembly file')
parser.add_argument(
'out', metavar='output', type=str, nargs=1,
help='The output file')
args, unknown_args = parser.parse_known_args()
input = args.input[0]
output = args.out[0]
if not os.path.isfile(input):
print(("ERROR: input file '%s' does not exist") % input)
sys.exit(1)
contents = None
with open(input, 'r') as f:
contents = f.read()
new_contents = process_asm(contents)
with open(output, 'w') as f:
f.write(new_contents)
if __name__ == '__main__':
main()
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
# kate: tab-width: 4; replace-tabs on; indent-width 4; tab-indents: off;
# kate: indent-mode python; remove-trailing-spaces modified;

View File

@@ -1,3 +1,15 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/@NLOHMANN_JSON_TARGETS_EXPORT_NAME@.cmake")
check_required_components("@PROJECT_NAME@")
include(FindPackageHandleStandardArgs)
set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG ${CMAKE_CURRENT_LIST_FILE})
find_package_handle_standard_args(@PROJECT_NAME@ CONFIG_MODE)
if(NOT TARGET @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@)
include("${CMAKE_CURRENT_LIST_DIR}/@NLOHMANN_JSON_TARGETS_EXPORT_NAME@.cmake")
if((NOT TARGET @NLOHMANN_JSON_TARGET_NAME@) AND
(NOT @PROJECT_NAME@_FIND_VERSION OR
@PROJECT_NAME@_FIND_VERSION VERSION_LESS 3.2.0))
add_library(@NLOHMANN_JSON_TARGET_NAME@ INTERFACE IMPORTED)
set_target_properties(@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
INTERFACE_LINK_LIBRARIES @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@
)
endif()
endif()

View File

@@ -1,11 +1,11 @@
# Doxyfile 1.8.15
# Doxyfile 1.8.16
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "JSON for Modern C++"
PROJECT_NUMBER = 3.1.2
PROJECT_NUMBER = 3.6.0
PROJECT_BRIEF =
PROJECT_LOGO =
OUTPUT_DIRECTORY = .
@@ -38,6 +38,7 @@ OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
OPTIMIZE_OUTPUT_SLICE = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 0
@@ -141,7 +142,7 @@ USE_HTAGS = NO
VERBATIM_HEADERS = NO
CLANG_ASSISTED_PARSING = YES
CLANG_OPTIONS = -std=c++11
CLANG_COMPILATION_DATABASE_PATH = 0
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
@@ -214,6 +215,7 @@ GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
LATEX_MAKEINDEX_CMD = \makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
EXTRA_PACKAGES =
@@ -228,6 +230,7 @@ LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
@@ -252,6 +255,7 @@ MAN_LINKS = NO
GENERATE_XML = YES
XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 568 KiB

After

Width:  |  Height:  |  Size: 871 KiB

View File

@@ -1,4 +1,5 @@
#include <iostream>
#include <iomanip>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

View File

@@ -1 +1 @@
<a target="_blank" href="https://wandbox.org/permlink/TarF5pPn9NtHQjhf"><b>online</b></a>
<a target="_blank" href="https://wandbox.org/permlink/0Nf4f9PlA9MpdUeb"><b>online</b></a>

17
doc/examples/contains.cpp Normal file
View File

@@ -0,0 +1,17 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
// create some JSON values
json j_object = R"( {"key": "value"} )"_json;
json j_array = R"( [1, 2, 3] )"_json;
// call contains
std::cout << std::boolalpha <<
"j_object contains 'key': " << j_object.contains("key") << '\n' <<
"j_object contains 'another': " << j_object.contains("another") << '\n' <<
"j_array contains 'key': " << j_array.contains("key") << std::endl;
}

View File

@@ -0,0 +1 @@
<a target="_blank" href="https://wandbox.org/permlink/iHSlXjtjhgO9Q1Tw"><b>online</b></a>

View File

@@ -0,0 +1,3 @@
j_object contains 'key': true
j_object contains 'another': false
j_array contains 'key': false

View File

@@ -1,4 +1,5 @@
#include <iostream>
#include <iomanip>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

View File

@@ -1 +1 @@
<a target="_blank" href="https://wandbox.org/permlink/tfI8DuCuZs3VB9VF"><b>online</b></a>
<a target="_blank" href="https://wandbox.org/permlink/3OPLSVPyweUyEHaX"><b>online</b></a>

Some files were not shown because too many files have changed in this diff Show More