Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitHub Actions <action@github.com>2020-06-28 14:43:48 +0300
committerGitHub Actions <action@github.com>2020-06-28 14:43:48 +0300
commit4fa69c9cd14b78d3491364f3c6a7967e5c3bb9fe (patch)
tree48f9862f4e4da4193b8888bea5931b36f09af7e5
parentff779d0d7e570880709d8c00cea732e6d6c067a6 (diff)
Upstream release v2.0.8v2.0.8
-rw-r--r--README.md2
-rw-r--r--include/nlohmann/json.hpp253
2 files changed, 178 insertions, 77 deletions
diff --git a/README.md b/README.md
index 7c42bb9..9ee713b 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ include(FetchContent)
FetchContent_Declare(json
GIT_REPOSITORY https://github.com/ArthurSonzogni/nlohman_json
- GIT_TAG v2.0.7)
+ GIT_TAG v2.0.8)
FetchContent_GetProperties(json)
if(NOT json_POPULATED)
diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp
index 4447412..6fed0a1 100644
--- a/include/nlohmann/json.hpp
+++ b/include/nlohmann/json.hpp
@@ -1,7 +1,7 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++
-| | |__ | | | | | | version 2.0.7
+| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@@ -29,32 +29,32 @@ SOFTWARE.
#ifndef NLOHMANN_JSON_HPP
#define NLOHMANN_JSON_HPP
-#include <algorithm>
-#include <array>
-#include <cassert>
-#include <cctype>
-#include <ciso646>
-#include <cmath>
-#include <cstddef>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
-#include <functional>
-#include <initializer_list>
-#include <iomanip>
-#include <iostream>
-#include <iterator>
-#include <limits>
-#include <locale>
-#include <map>
-#include <memory>
-#include <numeric>
-#include <sstream>
-#include <stdexcept>
-#include <string>
-#include <type_traits>
-#include <utility>
-#include <vector>
+#include <algorithm> // all_of, for_each, transform
+#include <array> // array
+#include <cassert> // assert
+#include <cctype> // isdigit
+#include <ciso646> // and, not, or
+#include <cmath> // isfinite, signbit
+#include <cstddef> // nullptr_t, ptrdiff_t, size_t
+#include <cstdint> // int64_t, uint64_t
+#include <cstdlib> // strtod, strtof, strtold, strtoul
+#include <cstring> // strlen
+#include <functional> // function, hash, less
+#include <initializer_list> // initializer_list
+#include <iomanip> // setw
+#include <iostream> // istream, ostream
+#include <iterator> // advance, begin, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
+#include <limits> // numeric_limits
+#include <locale> // locale
+#include <map> // map
+#include <memory> // addressof, allocator, allocator_traits, unique_ptr
+#include <numeric> // accumulate
+#include <sstream> // stringstream
+#include <stdexcept> // domain_error, invalid_argument, out_of_range
+#include <string> // getline, stoi, string, to_string
+#include <type_traits> // add_pointer, enable_if, is_arithmetic, is_base_of, is_const, is_constructible, is_convertible, is_floating_point, is_integral, is_nothrow_move_assignable, std::is_nothrow_move_constructible, std::is_pointer, std::is_reference, std::is_same, remove_const, remove_pointer, remove_reference
+#include <utility> // declval, forward, make_pair, move, pair, swap
+#include <vector> // vector
// exclude unsupported compilers
#if defined(__clang__)
@@ -122,26 +122,6 @@ struct has_mapped_type
std::is_integral<decltype(detect(std::declval<T>()))>::value;
};
-/*!
-@brief helper class to create locales with decimal point
-
-This struct is used a default locale during the JSON serialization. JSON
-requires the decimal point to be `.`, so this function overloads the
-`do_decimal_point()` function to return `.`. This function is called by
-float-to-string conversions to retrieve the decimal separator between integer
-and fractional parts.
-
-@sa https://github.com/nlohmann/json/issues/51#issuecomment-86869315
-@since version 2.0.0
-*/
-struct DecimalSeparator : std::numpunct<char>
-{
- char do_decimal_point() const
- {
- return '.';
- }
-};
-
}
/*!
@@ -2201,8 +2181,7 @@ class basic_json
{
std::stringstream ss;
// fix locale problems
- const static std::locale loc(std::locale(), new DecimalSeparator);
- ss.imbue(loc);
+ ss.imbue(std::locale::classic());
// 6, 15 or 16 digits of precision allows round-trip IEEE 754
// string->float->string, string->double->string or string->long
@@ -5054,6 +5033,102 @@ class basic_json
}
/*!
+ @brief add an object to an array
+
+ Creates a JSON value from the passed parameters @a args to the end of the
+ JSON value. If the function is called on a JSON null value, an empty array
+ is created before appending the value created from @a args.
+
+ @param[in] args arguments to forward to a constructor of @ref basic_json
+ @tparam Args compatible types to create a @ref basic_json object
+
+ @throw std::domain_error when called on a type other than JSON array or
+ null; example: `"cannot use emplace_back() with number"`
+
+ @complexity Amortized constant.
+
+ @liveexample{The example shows how `push_back()` can be used to add
+ elements to a JSON array. Note how the `null` value was silently converted
+ to a JSON array.,emplace_back}
+
+ @since version 2.0.8
+ */
+ template<class... Args>
+ void emplace_back(Args&& ... args)
+ {
+ // emplace_back only works for null objects or arrays
+ if (not(is_null() or is_array()))
+ {
+ throw std::domain_error("cannot use emplace_back() with " + type_name());
+ }
+
+ // transform null object into an array
+ if (is_null())
+ {
+ m_type = value_t::array;
+ m_value = value_t::array;
+ assert_invariant();
+ }
+
+ // add element to array (perfect forwarding)
+ m_value.array->emplace_back(std::forward<Args>(args)...);
+ }
+
+ /*!
+ @brief add an object to an object if key does not exist
+
+ Inserts a new element into a JSON object constructed in-place with the given
+ @a args if there is no element with the key in the container. If the
+ function is called on a JSON null value, an empty object is created before
+ appending the value created from @a args.
+
+ @param[in] args arguments to forward to a constructor of @ref basic_json
+ @tparam Args compatible types to create a @ref basic_json object
+
+ @return a pair consisting of an iterator to the inserted element, or the
+ already-existing element if no insertion happened, and a bool
+ denoting whether the insertion took place.
+
+ @throw std::domain_error when called on a type other than JSON object or
+ null; example: `"cannot use emplace() with number"`
+
+ @complexity Logarithmic in the size of the container, O(log(`size()`)).
+
+ @liveexample{The example shows how `emplace()` can be used to add elements
+ to a JSON object. Note how the `null` value was silently converted to a
+ JSON object. Further note how no value is added if there was already one
+ value stored with the same key.,emplace}
+
+ @since version 2.0.8
+ */
+ template<class... Args>
+ std::pair<iterator, bool> emplace(Args&& ... args)
+ {
+ // emplace only works for null objects or arrays
+ if (not(is_null() or is_object()))
+ {
+ throw std::domain_error("cannot use emplace() with " + type_name());
+ }
+
+ // transform null object into an object
+ if (is_null())
+ {
+ m_type = value_t::object;
+ m_value = value_t::object;
+ assert_invariant();
+ }
+
+ // add element to array (perfect forwarding)
+ auto res = m_value.object->emplace(std::forward<Args>(args)...);
+ // create result iterator and set iterator to the result of emplace
+ auto it = begin();
+ it.m_it.object_iterator = res.first;
+
+ // return pair of iterator and boolean
+ return {it, res.second};
+ }
+
+ /*!
@brief inserts element
Inserts element @a val before iterator @a pos.
@@ -5829,7 +5904,7 @@ class basic_json
o.width(0);
// fix locale problems
- const auto old_locale = o.imbue(std::locale(std::locale(), new DecimalSeparator));
+ const auto old_locale = o.imbue(std::locale::classic());
// set precision
// 6, 15 or 16 digits of precision allows round-trip IEEE 754
@@ -7618,6 +7693,12 @@ class basic_json
explicit lexer(std::istream& s)
: m_stream(&s), m_line_buffer()
{
+ // immediately abort if stream is erroneous
+ if (s.fail())
+ {
+ throw std::invalid_argument("stream error: " + std::string(strerror(errno)));
+ }
+
// fill buffer
fill_line_buffer();
@@ -8740,8 +8821,22 @@ basic_json_parser_66:
*/
void fill_line_buffer(size_t n = 0)
{
+ // if line buffer is used, m_content points to its data
+ assert(m_line_buffer.empty()
+ or m_content == reinterpret_cast<const lexer_char_t*>(m_line_buffer.data()));
+
+ // if line buffer is used, m_limit is set past the end of its data
+ assert(m_line_buffer.empty()
+ or m_limit == m_content + m_line_buffer.size());
+
+ // pointer relationships
+ assert(m_content <= m_start);
+ assert(m_start <= m_cursor);
+ assert(m_cursor <= m_limit);
+ assert(m_marker == nullptr or m_marker <= m_limit);
+
// number of processed characters (p)
- const auto offset_start = m_start - m_content;
+ const size_t num_processed_chars = static_cast<size_t>(m_start - m_content);
// offset for m_marker wrt. to m_start
const auto offset_marker = (m_marker == nullptr) ? 0 : m_marker - m_start;
// number of unprocessed characters (u)
@@ -8750,35 +8845,34 @@ basic_json_parser_66:
// no stream is used or end of file is reached
if (m_stream == nullptr or m_stream->eof())
{
- // skip this part if we are already using the line buffer
- if (m_start != reinterpret_cast<const lexer_char_t*>(m_line_buffer.data()))
- {
- // copy unprocessed characters to line buffer
- m_line_buffer.clear();
- for (m_cursor = m_start; m_cursor != m_limit; ++m_cursor)
- {
- m_line_buffer.append(1, static_cast<const char>(*m_cursor));
- }
- }
+ // m_start may or may not be pointing into m_line_buffer at
+ // this point. We trust the standand library to do the right
+ // thing. See http://stackoverflow.com/q/28142011/266378
+ m_line_buffer.assign(m_start, m_limit);
// append n characters to make sure that there is sufficient
// space between m_cursor and m_limit
m_line_buffer.append(1, '\x00');
- m_line_buffer.append(n - 1, '\x01');
+ if (n > 0)
+ {
+ m_line_buffer.append(n - 1, '\x01');
+ }
}
else
{
// delete processed characters from line buffer
- m_line_buffer.erase(0, static_cast<size_t>(offset_start));
+ m_line_buffer.erase(0, num_processed_chars);
// read next line from input stream
- std::string line;
- std::getline(*m_stream, line, '\n');
+ m_line_buffer_tmp.clear();
+ std::getline(*m_stream, m_line_buffer_tmp, '\n');
+
// add line with newline symbol to the line buffer
- m_line_buffer += line + "\n";
+ m_line_buffer += m_line_buffer_tmp;
+ m_line_buffer.push_back('\n');
}
// set pointers
- m_content = reinterpret_cast<const lexer_char_t*>(m_line_buffer.c_str());
+ m_content = reinterpret_cast<const lexer_char_t*>(m_line_buffer.data());
assert(m_content != nullptr);
m_start = m_content;
m_marker = m_start + offset_marker;
@@ -8861,9 +8955,20 @@ basic_json_parser_66:
// iterate the result between the quotes
for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
{
- // process escaped characters
- if (*i == '\\')
+ // find next escape character
+ auto e = std::find(i, m_cursor - 1, '\\');
+ if (e != i)
+ {
+ // see https://github.com/nlohmann/json/issues/365#issuecomment-262874705
+ for (auto k = i; k < e; k++)
+ {
+ result.push_back(static_cast<typename string_t::value_type>(*k));
+ }
+ i = e - 1; // -1 because of ++i
+ }
+ else
{
+ // processing escaped character
// read next character
++i;
@@ -8950,12 +9055,6 @@ basic_json_parser_66:
}
}
}
- else
- {
- // all other characters are just copied to the end of the
- // string
- result.append(1, static_cast<typename string_t::value_type>(*i));
- }
}
return result;
@@ -9139,6 +9238,8 @@ basic_json_parser_66:
std::istream* m_stream = nullptr;
/// line buffer buffer for m_stream
string_t m_line_buffer {};
+ /// used for filling m_line_buffer
+ string_t m_line_buffer_tmp {};
/// the buffer pointer
const lexer_char_t* m_content = nullptr;
/// pointer to the beginning of the current symbol
@@ -9164,7 +9265,7 @@ basic_json_parser_66:
/// a parser reading from a string literal
parser(const char* buff, const parser_callback_t cb = nullptr)
: callback(cb),
- m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), strlen(buff))
+ m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), std::strlen(buff))
{}
/// a parser reading from an input stream