mirror of
https://github.com/nlohmann/json.git
synced 2026-02-17 17:14:00 +00:00
Compare commits
16 Commits
issue2615
...
feature/op
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ffd3ae400 | ||
|
|
384442e8e5 | ||
|
|
f1913fe7a9 | ||
|
|
ebb63bd1fa | ||
|
|
5e55158d60 | ||
|
|
fedf82c904 | ||
|
|
b61d563ebe | ||
|
|
f25bf312fc | ||
|
|
007c6c4bc5 | ||
|
|
71c80ccfd8 | ||
|
|
6b31375c7c | ||
|
|
a2fea87ef6 | ||
|
|
1b846c9d81 | ||
|
|
713038fa27 | ||
|
|
1359c56137 | ||
|
|
df30a0ea07 |
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013-2021 Niels Lohmann
|
||||
Copyright (c) 2013-2020 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
|
||||
|
||||
74
README.md
74
README.md
@@ -76,7 +76,6 @@ You can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nl
|
||||
- [Stefan Hagen](https://github.com/sthagen)
|
||||
- [Steve Sperandeo](https://github.com/homer6)
|
||||
- [Robert Jefe Lindstädt](https://github.com/eljefedelrodeodeljefe)
|
||||
- [Steve Wagner](https://github.com/ciroque)
|
||||
|
||||
Thanks everyone!
|
||||
|
||||
@@ -1199,11 +1198,11 @@ auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE
|
||||
|
||||
## Supported compilers
|
||||
|
||||
Though it's 2021 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
|
||||
Though it's 2020 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
|
||||
|
||||
- GCC 4.8 - 11.0 (and possibly later)
|
||||
- Clang 3.4 - 11.0 (and possibly later)
|
||||
- Apple Clang 9.1 - 12.3 (and possibly later)
|
||||
- GCC 4.8 - 10.1 (and possibly later)
|
||||
- Clang 3.4 - 10.0 (and possibly later)
|
||||
- Apple Clang 9.1 - 12.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)
|
||||
@@ -1230,37 +1229,37 @@ Please note:
|
||||
|
||||
The following compilers are currently used in continuous integration at [Travis](https://travis-ci.org/nlohmann/json), [AppVeyor](https://ci.appveyor.com/project/nlohmann/json), [GitHub Actions](https://github.com/nlohmann/json/actions), and [CircleCI](https://circleci.com/gh/nlohmann/json):
|
||||
|
||||
| Compiler | Operating System | CI Provider |
|
||||
|-------------------------------------------------------------------|--------------------|----------------|
|
||||
| Apple Clang 10.0.1 (clang-1001.0.46.4); Xcode 10.2.1 | macOS 10.14.4 | Travis |
|
||||
| Apple Clang 11.0.0 (clang-1100.0.33.12); Xcode 11.2.1 | macOS 10.14.6 | Travis |
|
||||
| Apple Clang 11.0.3 (clang-1103.0.32.59); Xcode 11.4.1 | macOS 10.15.4 | GitHub Actions |
|
||||
| Apple Clang 12.0.0 (clang-1200.0.22.7); Xcode 11.4.1 | macOS 10.15.5 | Travis |
|
||||
| Clang 3.5.0 (3.5.0-4ubuntu2\~trusty2) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 3.6.2 (3.6.2-svn240577-1\~exp1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 3.7.1 (3.7.1-svn253571-1\~exp1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 3.8.0 (3.8.0-2ubuntu3\~trusty5) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 3.9.1 (3.9.1-4ubuntu3\~14.04.3) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 4.0.1 (4.0.1-svn305264-1\~exp1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 5.0.2 (version 5.0.2-svn328729-1\~exp1\~20180509123505.100) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 6.0.1 (6.0.1-svn334776-1\~exp1\~20190309042707.121) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 7.1.0 (7.1.0-svn353565-1\~exp1\~20190419134007.64) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 7.5.0 (Ubuntu 7.5.0-3ubuntu1\~18.04) | Ubuntu 18.04.4 LTS | Travis |
|
||||
| Clang 9.0.0 (x86_64-pc-windows-msvc) | Windows-10.0.17763 | GitHub Actions |
|
||||
| Clang 10.0.0 (x86_64-pc-windows-msvc) | Windows-10.0.17763 | GitHub Actions |
|
||||
| GCC 4.8.5 (Ubuntu 4.8.5-4ubuntu8\~14.04.2) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 4.9.4 (Ubuntu 4.9.4-2ubuntu1\~14.04.1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 5.5.0 (Ubuntu 5.5.0-12ubuntu1\~14.04) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 6.3.0 (Debian 6.3.0-18+deb9u1) | Debian 9 | Circle CI |
|
||||
| GCC 6.5.0 (Ubuntu 6.5.0-2ubuntu1\~14.04.1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 7.3.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) | Windows-6.3.9600 | AppVeyor |
|
||||
| GCC 7.5.0 (Ubuntu 7.5.0-3ubuntu1\~14.04.1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 7.5.0 (Ubuntu 7.5.0-3ubuntu1\~18.04) | Ubuntu 18.04.4 LTS | GitHub Actions |
|
||||
| GCC 8.4.0 (Ubuntu 8.4.0-1ubuntu1\~14.04) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 9.3.0 (Ubuntu 9.3.0-11ubuntu0\~14.04) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 10.1.0 (Arch Linux latest) | Arch Linux | Circle CI |
|
||||
| MSVC 19.0.24241.7 (Build Engine version 14.0.25420.1) | Windows-6.3.9600 | AppVeyor |
|
||||
| MSVC 19.16.27035.0 (15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | AppVeyor |
|
||||
| Compiler | Operating System | CI Provider |
|
||||
|-----------------------------------------------------------------|--------------------|----------------|
|
||||
| Apple Clang 10.0.1 (clang-1001.0.46.4); Xcode 10.2.1 | macOS 10.14.4 | Travis |
|
||||
| Apple Clang 11.0.0 (clang-1100.0.33.12); Xcode 11.2.1 | macOS 10.14.6 | Travis |
|
||||
| Apple Clang 11.0.3 (clang-1103.0.32.59); Xcode 11.4.1 | macOS 10.15.4 | GitHub Actions |
|
||||
| Apple Clang 12.0.0 (clang-1200.0.22.7); Xcode 11.4.1 | macOS 10.15.5 | Travis |
|
||||
| Clang 3.5.0 (3.5.0-4ubuntu2~trusty2) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 3.6.2 (3.6.2-svn240577-1~exp1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 3.7.1 (3.7.1-svn253571-1~exp1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 3.8.0 (3.8.0-2ubuntu3~trusty5) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 3.9.1 (3.9.1-4ubuntu3~14.04.3) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 4.0.1 (4.0.1-svn305264-1~exp1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 5.0.2 (version 5.0.2-svn328729-1~exp1~20180509123505.100) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 6.0.1 (6.0.1-svn334776-1~exp1~20190309042707.121) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 7.1.0 (7.1.0-svn353565-1~exp1~20190419134007.64) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| Clang 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) | Ubuntu 18.04.4 LTS | Travis |
|
||||
| Clang 9.0.0 (x86_64-pc-windows-msvc) | Windows-10.0.17763 | GitHub Actions |
|
||||
| Clang 10.0.0 (x86_64-pc-windows-msvc) | Windows-10.0.17763 | GitHub Actions |
|
||||
| GCC 4.8.5 (Ubuntu 4.8.5-4ubuntu8~14.04.2) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 4.9.4 (Ubuntu 4.9.4-2ubuntu1~14.04.1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 5.5.0 (Ubuntu 5.5.0-12ubuntu1~14.04) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 6.3.0 (Debian 6.3.0-18+deb9u1) | Debian 9 | Circle CI |
|
||||
| GCC 6.5.0 (Ubuntu 6.5.0-2ubuntu1~14.04.1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 7.3.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) | Windows-6.3.9600 | AppVeyor |
|
||||
| GCC 7.5.0 (Ubuntu 7.5.0-3ubuntu1~14.04.1) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) | Ubuntu 18.04.4 LTS | GitHub Actions |
|
||||
| GCC 8.4.0 (Ubuntu 8.4.0-1ubuntu1~14.04) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 9.3.0 (Ubuntu 9.3.0-11ubuntu0~14.04) | Ubuntu 14.04.5 LTS | Travis |
|
||||
| GCC 10.1.0 (Arch Linux latest) | Arch Linux | Circle CI |
|
||||
| MSVC 19.0.24241.7 (Build Engine version 14.0.25420.1) | Windows-6.3.9600 | AppVeyor |
|
||||
| MSVC 19.16.27035.0 (15.9.21+g9802d43bc3 for .NET Framework) | Windows-10.0.14393 | AppVeyor |
|
||||
| MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) | Windows-10.0.17763 | AppVeyor |
|
||||
| MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) | Windows-10.0.17763 | GitHub Actions |
|
||||
| MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) with ClangCL 10.0.0 | Windows-10.0.17763 | GitHub Actions |
|
||||
@@ -1271,7 +1270,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 © 2013-2021 [Niels Lohmann](https://nlohmann.me)
|
||||
Copyright © 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:
|
||||
|
||||
@@ -1528,7 +1527,6 @@ I deeply appreciate the help of the following people.
|
||||
- [KonanM](https://github.com/KonanM) proposed an implementation for the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros.
|
||||
- [Guillaume Racicot](https://github.com/gracicot) implemented `string_view` support and allowed C++20 support.
|
||||
- [Alex Reinking](https://github.com/alexreinking) improved CMake support for `FetchContent`.
|
||||
- [Hannes Domani](https://github.com/ssbssa) provided a GDB pretty printer.
|
||||
|
||||
Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"compiler": {
|
||||
"c++": "201103",
|
||||
"family": "clang",
|
||||
"version": "12.0.0 (clang-1200.0.32.28)"
|
||||
"version": "12.0.0 (clang-1200.0.22.19)"
|
||||
},
|
||||
"copyright": "(C) 2013-2021 Niels Lohmann",
|
||||
"copyright": "(C) 2013-2020 Niels Lohmann",
|
||||
"name": "JSON for Modern C++",
|
||||
"platform": "apple",
|
||||
"url": "https://github.com/nlohmann/json",
|
||||
|
||||
@@ -327,7 +327,7 @@ Note that this table only lists those exceptions thrown due to the type. For ins
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@copyright Copyright © 2013-2021 Niels Lohmann. The code is licensed under the [MIT License](http://opensource.org/licenses/MIT).
|
||||
@copyright Copyright © 2013-2020 Niels Lohmann. The code is licensed under the [MIT License](http://opensource.org/licenses/MIT).
|
||||
|
||||
@author [Niels Lohmann](http://nlohmann.me)
|
||||
@see https://github.com/nlohmann/json to download the source code
|
||||
|
||||
@@ -32,6 +32,21 @@ void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
|
||||
n = nullptr;
|
||||
}
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
template<typename BasicJsonType, typename T>
|
||||
void from_json(const BasicJsonType& j, std::optional<T>& opt)
|
||||
{
|
||||
if (j.is_null())
|
||||
{
|
||||
opt = std::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
opt = j.template get<T>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// overloads for basic_json template parameters
|
||||
template < typename BasicJsonType, typename ArithmeticType,
|
||||
enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
|
||||
|
||||
@@ -490,49 +490,51 @@ inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
|
||||
return 10;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
if (n >= 100000000)
|
||||
else if (n >= 100000000)
|
||||
{
|
||||
pow10 = 100000000;
|
||||
return 9;
|
||||
}
|
||||
if (n >= 10000000)
|
||||
else if (n >= 10000000)
|
||||
{
|
||||
pow10 = 10000000;
|
||||
return 8;
|
||||
}
|
||||
if (n >= 1000000)
|
||||
else if (n >= 1000000)
|
||||
{
|
||||
pow10 = 1000000;
|
||||
return 7;
|
||||
}
|
||||
if (n >= 100000)
|
||||
else if (n >= 100000)
|
||||
{
|
||||
pow10 = 100000;
|
||||
return 6;
|
||||
}
|
||||
if (n >= 10000)
|
||||
else if (n >= 10000)
|
||||
{
|
||||
pow10 = 10000;
|
||||
return 5;
|
||||
}
|
||||
if (n >= 1000)
|
||||
else if (n >= 1000)
|
||||
{
|
||||
pow10 = 1000;
|
||||
return 4;
|
||||
}
|
||||
if (n >= 100)
|
||||
else if (n >= 100)
|
||||
{
|
||||
pow10 = 100;
|
||||
return 3;
|
||||
}
|
||||
if (n >= 10)
|
||||
else if (n >= 10)
|
||||
{
|
||||
pow10 = 10;
|
||||
return 2;
|
||||
}
|
||||
|
||||
pow10 = 1;
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
pow10 = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
|
||||
|
||||
@@ -219,6 +219,22 @@ struct external_constructor<value_t::object>
|
||||
// to_json //
|
||||
/////////////
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
template<typename BasicJsonType, typename T,
|
||||
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
||||
void to_json(BasicJsonType& j, const std::optional<T>& opt)
|
||||
{
|
||||
if (opt.has_value())
|
||||
{
|
||||
j = *opt;
|
||||
}
|
||||
else
|
||||
{
|
||||
j = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename BasicJsonType, typename T,
|
||||
enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
|
||||
void to_json(BasicJsonType& j, T b) noexcept
|
||||
|
||||
@@ -135,8 +135,10 @@ class iterator_input_adapter
|
||||
std::advance(current, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
return std::char_traits<char_type>::eof();
|
||||
else
|
||||
{
|
||||
return std::char_traits<char_type>::eof();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -393,62 +393,62 @@ class parser
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_array, "array")));
|
||||
}
|
||||
|
||||
// states.back() is false -> object
|
||||
|
||||
// comma -> next value
|
||||
if (get_token() == token_type::value_separator)
|
||||
else // object
|
||||
{
|
||||
// parse key
|
||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
|
||||
// comma -> next value
|
||||
if (get_token() == token_type::value_separator)
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::value_string, "object key")));
|
||||
// parse key
|
||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::value_string, "object key")));
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse separator (:)
|
||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::name_separator, "object separator")));
|
||||
}
|
||||
|
||||
// parse values
|
||||
get_token();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
|
||||
// closing }
|
||||
if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
|
||||
{
|
||||
return false;
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// We are done with this object. Before we can parse a
|
||||
// new value, we need to evaluate the new state first.
|
||||
// By setting skip_to_state_evaluation to false, we
|
||||
// are effectively jumping to the beginning of this if.
|
||||
JSON_ASSERT(!states.empty());
|
||||
states.pop_back();
|
||||
skip_to_state_evaluation = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse separator (:)
|
||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::name_separator, "object separator")));
|
||||
}
|
||||
|
||||
// parse values
|
||||
get_token();
|
||||
continue;
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_object, "object")));
|
||||
}
|
||||
|
||||
// closing }
|
||||
if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// We are done with this object. Before we can parse a
|
||||
// new value, we need to evaluate the new state first.
|
||||
// By setting skip_to_state_evaluation to false, we
|
||||
// are effectively jumping to the beginning of this if.
|
||||
JSON_ASSERT(!states.empty());
|
||||
states.pop_back();
|
||||
skip_to_state_evaluation = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_object, "object")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ template<typename IteratorType> class iteration_proxy_value
|
||||
/// a string representation of the array index
|
||||
mutable string_type array_index_str = "0";
|
||||
/// an empty string (to return a reference for primitive values)
|
||||
const string_type empty_str;
|
||||
const string_type empty_str = "";
|
||||
|
||||
public:
|
||||
explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
#define JSON_HAS_CPP_14
|
||||
#endif
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#include <optional>
|
||||
#endif
|
||||
|
||||
// disable float-equal warnings on GCC/clang
|
||||
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
||||
#pragma GCC diagnostic push
|
||||
|
||||
@@ -351,7 +351,7 @@ class basic_json
|
||||
{
|
||||
basic_json result;
|
||||
|
||||
result["copyright"] = "(C) 2013-2021 Niels Lohmann";
|
||||
result["copyright"] = "(C) 2013-2020 Niels Lohmann";
|
||||
result["name"] = "JSON for Modern C++";
|
||||
result["url"] = "https://github.com/nlohmann/json";
|
||||
result["version"]["string"] =
|
||||
|
||||
@@ -2108,6 +2108,10 @@ JSON_HEDLEY_DIAGNOSTIC_POP
|
||||
#define JSON_HAS_CPP_14
|
||||
#endif
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#include <optional>
|
||||
#endif
|
||||
|
||||
// disable float-equal warnings on GCC/clang
|
||||
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
||||
#pragma GCC diagnostic push
|
||||
@@ -3518,6 +3522,21 @@ void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
|
||||
n = nullptr;
|
||||
}
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
template<typename BasicJsonType, typename T>
|
||||
void from_json(const BasicJsonType& j, std::optional<T>& opt)
|
||||
{
|
||||
if (j.is_null())
|
||||
{
|
||||
opt = std::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
opt = j.template get<T>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// overloads for basic_json template parameters
|
||||
template < typename BasicJsonType, typename ArithmeticType,
|
||||
enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
|
||||
@@ -3944,7 +3963,7 @@ template<typename IteratorType> class iteration_proxy_value
|
||||
/// a string representation of the array index
|
||||
mutable string_type array_index_str = "0";
|
||||
/// an empty string (to return a reference for primitive values)
|
||||
const string_type empty_str;
|
||||
const string_type empty_str = "";
|
||||
|
||||
public:
|
||||
explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
|
||||
@@ -4294,6 +4313,22 @@ struct external_constructor<value_t::object>
|
||||
// to_json //
|
||||
/////////////
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
template<typename BasicJsonType, typename T,
|
||||
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
||||
void to_json(BasicJsonType& j, const std::optional<T>& opt)
|
||||
{
|
||||
if (opt.has_value())
|
||||
{
|
||||
j = *opt;
|
||||
}
|
||||
else
|
||||
{
|
||||
j = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename BasicJsonType, typename T,
|
||||
enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
|
||||
void to_json(BasicJsonType& j, T b) noexcept
|
||||
@@ -4947,8 +4982,10 @@ class iterator_input_adapter
|
||||
std::advance(current, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
return std::char_traits<char_type>::eof();
|
||||
else
|
||||
{
|
||||
return std::char_traits<char_type>::eof();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -10616,62 +10653,62 @@ class parser
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_array, "array")));
|
||||
}
|
||||
|
||||
// states.back() is false -> object
|
||||
|
||||
// comma -> next value
|
||||
if (get_token() == token_type::value_separator)
|
||||
else // object
|
||||
{
|
||||
// parse key
|
||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
|
||||
// comma -> next value
|
||||
if (get_token() == token_type::value_separator)
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::value_string, "object key")));
|
||||
// parse key
|
||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::value_string, "object key")));
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse separator (:)
|
||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::name_separator, "object separator")));
|
||||
}
|
||||
|
||||
// parse values
|
||||
get_token();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
|
||||
// closing }
|
||||
if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
|
||||
{
|
||||
return false;
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// We are done with this object. Before we can parse a
|
||||
// new value, we need to evaluate the new state first.
|
||||
// By setting skip_to_state_evaluation to false, we
|
||||
// are effectively jumping to the beginning of this if.
|
||||
JSON_ASSERT(!states.empty());
|
||||
states.pop_back();
|
||||
skip_to_state_evaluation = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse separator (:)
|
||||
if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::name_separator, "object separator")));
|
||||
}
|
||||
|
||||
// parse values
|
||||
get_token();
|
||||
continue;
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_object, "object")));
|
||||
}
|
||||
|
||||
// closing }
|
||||
if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// We are done with this object. Before we can parse a
|
||||
// new value, we need to evaluate the new state first.
|
||||
// By setting skip_to_state_evaluation to false, we
|
||||
// are effectively jumping to the beginning of this if.
|
||||
JSON_ASSERT(!states.empty());
|
||||
states.pop_back();
|
||||
skip_to_state_evaluation = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_object, "object")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14946,49 +14983,51 @@ inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
|
||||
return 10;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
if (n >= 100000000)
|
||||
else if (n >= 100000000)
|
||||
{
|
||||
pow10 = 100000000;
|
||||
return 9;
|
||||
}
|
||||
if (n >= 10000000)
|
||||
else if (n >= 10000000)
|
||||
{
|
||||
pow10 = 10000000;
|
||||
return 8;
|
||||
}
|
||||
if (n >= 1000000)
|
||||
else if (n >= 1000000)
|
||||
{
|
||||
pow10 = 1000000;
|
||||
return 7;
|
||||
}
|
||||
if (n >= 100000)
|
||||
else if (n >= 100000)
|
||||
{
|
||||
pow10 = 100000;
|
||||
return 6;
|
||||
}
|
||||
if (n >= 10000)
|
||||
else if (n >= 10000)
|
||||
{
|
||||
pow10 = 10000;
|
||||
return 5;
|
||||
}
|
||||
if (n >= 1000)
|
||||
else if (n >= 1000)
|
||||
{
|
||||
pow10 = 1000;
|
||||
return 4;
|
||||
}
|
||||
if (n >= 100)
|
||||
else if (n >= 100)
|
||||
{
|
||||
pow10 = 100;
|
||||
return 3;
|
||||
}
|
||||
if (n >= 10)
|
||||
else if (n >= 10)
|
||||
{
|
||||
pow10 = 10;
|
||||
return 2;
|
||||
}
|
||||
|
||||
pow10 = 1;
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
pow10 = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
|
||||
@@ -16971,7 +17010,7 @@ class basic_json
|
||||
{
|
||||
basic_json result;
|
||||
|
||||
result["copyright"] = "(C) 2013-2021 Niels Lohmann";
|
||||
result["copyright"] = "(C) 2013-2020 Niels Lohmann";
|
||||
result["name"] = "JSON for Modern C++";
|
||||
result["url"] = "https://github.com/nlohmann/json";
|
||||
result["version"]["string"] =
|
||||
|
||||
@@ -1703,6 +1703,65 @@ TEST_CASE("JSON to enum mapping")
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
TEST_CASE("std::optional")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j_null;
|
||||
std::optional<std::string> opt_null;
|
||||
|
||||
CHECK(json(opt_null) == j_null);
|
||||
CHECK(std::optional<std::string>(j_null) == std::nullopt);
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
json j_string = "string";
|
||||
std::optional<std::string> opt_string = "string";
|
||||
|
||||
CHECK(json(opt_string) == j_string);
|
||||
CHECK(std::optional<std::string>(j_string) == opt_string);
|
||||
}
|
||||
|
||||
SECTION("bool")
|
||||
{
|
||||
json j_bool = true;
|
||||
std::optional<bool> opt_bool = true;
|
||||
|
||||
CHECK(json(opt_bool) == j_bool);
|
||||
CHECK(std::optional<bool>(j_bool) == opt_bool);
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j_number = 1;
|
||||
std::optional<int> opt_int = 1;
|
||||
|
||||
CHECK(json(opt_int) == j_number);
|
||||
CHECK(std::optional<int>(j_number) == opt_int);
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j_array = {1, 2, nullptr};
|
||||
std::vector<std::optional<int>> opt_array = {{1, 2, std::nullopt}};
|
||||
|
||||
CHECK(json(opt_array) == j_array);
|
||||
CHECK(std::vector<std::optional<int>>(j_array) == opt_array);
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j_object = {{"one", 1}, {"two", 2}, {"zero", nullptr}};
|
||||
std::map<std::string, std::optional<int>> opt_object {{"one", 1}, {"two", 2}, {"zero", std::nullopt}};
|
||||
|
||||
CHECK(json(opt_object) == j_object);
|
||||
CHECK(std::map<std::string, std::optional<int>>(j_object) == opt_object);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#undef JSON_HAS_CPP_17
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ TEST_CASE("version information")
|
||||
json j = json::meta();
|
||||
|
||||
CHECK(j["name"] == "JSON for Modern C++");
|
||||
CHECK(j["copyright"] == "(C) 2013-2021 Niels Lohmann");
|
||||
CHECK(j["copyright"] == "(C) 2013-2020 Niels Lohmann");
|
||||
CHECK(j["url"] == "https://github.com/nlohmann/json");
|
||||
CHECK(j["version"] == json(
|
||||
{
|
||||
|
||||
77
third_party/gdb_pretty_printer/README.md
vendored
77
third_party/gdb_pretty_printer/README.md
vendored
@@ -1,77 +0,0 @@
|
||||
# GDB Pretty Printer
|
||||
|
||||
File [nlohmann-json.py](nlohmann-json.py) contains a pretty printer for GDB for JSON values of this library. It was originally published as [Gist](https://gist.github.com/ssbssa/60da5339c6e6036b2afce17de06050ea#file-nlohmann-json-py) by [Hannes Domani](https://github.com/ssbssa).
|
||||
|
||||
## How to use
|
||||
|
||||
- Add line
|
||||
|
||||
```
|
||||
source /path/to/nlohmann-json.py
|
||||
```
|
||||
|
||||
to `~/.gdbinit`. Note you must replace `/path/to` with whatever path you stored file `nlohmann-json.py`.
|
||||
- In GDB, debug as usual. When you want to pretty-print a JSON value `var`, type
|
||||
|
||||
```
|
||||
p -pretty on -array on -- var
|
||||
```
|
||||
|
||||
The result should look like
|
||||
|
||||
```
|
||||
$1 = std::map with 5 elements = {
|
||||
["Baptiste"] = std::map with 1 element = {
|
||||
["first"] = "second"
|
||||
},
|
||||
["Emmanuel"] = std::vector of length 3, capacity 3 = {
|
||||
3,
|
||||
"25",
|
||||
0.5
|
||||
},
|
||||
["Jean"] = 0.7,
|
||||
["Zorg"] = std::map with 8 elements = {
|
||||
["array"] = std::vector of length 3, capacity 3 = {
|
||||
1,
|
||||
0,
|
||||
2
|
||||
},
|
||||
["awesome_str"] = "bleh",
|
||||
["bool"] = true,
|
||||
["flex"] = 0.2,
|
||||
["float"] = 5.22,
|
||||
["int"] = 5,
|
||||
["nested"] = std::map with 1 element = {
|
||||
["bar"] = "barz"
|
||||
},
|
||||
["trap "] = "you fell"
|
||||
},
|
||||
["empty"] = nlohmann::detail::value_t::null
|
||||
}
|
||||
```
|
||||
|
||||
Tested with GDB 9.2. See [#1952](https://github.com/nlohmann/json/issues/1952) for more information. Please post questions there.
|
||||
|
||||
## Copyright
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2020 [Hannes Domani](https://github.com/ssbssa)
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
28
third_party/gdb_pretty_printer/nlohmann-json.py
vendored
28
third_party/gdb_pretty_printer/nlohmann-json.py
vendored
@@ -1,28 +0,0 @@
|
||||
import gdb
|
||||
import re
|
||||
|
||||
class JsonValuePrinter:
|
||||
"Print a json-value"
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
if self.val.type.strip_typedefs().code == gdb.TYPE_CODE_FLT:
|
||||
return ("%.6f" % float(self.val)).rstrip("0")
|
||||
return self.val
|
||||
|
||||
def json_lookup_function(val):
|
||||
if re.search("^nlohmann::basic_json<.*>$", val.type.strip_typedefs().name):
|
||||
t = str(val['m_type'])
|
||||
if t.startswith("nlohmann::detail::value_t::"):
|
||||
try:
|
||||
union_val = val['m_value'][t[27:]]
|
||||
if union_val.type.code == gdb.TYPE_CODE_PTR:
|
||||
return gdb.default_visualizer(union_val.dereference())
|
||||
else:
|
||||
return JsonValuePrinter(union_val)
|
||||
except:
|
||||
return JsonValuePrinter(val['m_type'])
|
||||
|
||||
gdb.pretty_printers.append(json_lookup_function)
|
||||
Reference in New Issue
Block a user