summaryrefslogtreecommitdiff
path: root/include/lib/modernjson/json.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lib/modernjson/json.h')
-rw-r--r--include/lib/modernjson/json.h482
1 files changed, 346 insertions, 136 deletions
diff --git a/include/lib/modernjson/json.h b/include/lib/modernjson/json.h
index 37536ef..4c50e9b 100644
--- a/include/lib/modernjson/json.h
+++ b/include/lib/modernjson/json.h
@@ -1,7 +1,7 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++
-| | |__ | | | | | | version 3.2.0
+| | |__ | | | | | | version 3.4.0
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@@ -31,7 +31,7 @@ SOFTWARE.
#define NLOHMANN_JSON_HPP
#define NLOHMANN_JSON_VERSION_MAJOR 3
-#define NLOHMANN_JSON_VERSION_MINOR 2
+#define NLOHMANN_JSON_VERSION_MINOR 4
#define NLOHMANN_JSON_VERSION_PATCH 0
#include <algorithm> // all_of, find, for_each
@@ -208,6 +208,8 @@ class basic_json
using json_pointer = ::nlohmann::json_pointer<basic_json>;
template<typename T, typename SFINAE>
using json_serializer = JSONSerializer<T, SFINAE>;
+ /// how to treat decoding errors
+ using error_handler_t = detail::error_handler_t;
/// helper type for initializer lists of basic_json values
using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
@@ -947,7 +949,7 @@ class basic_json
object = nullptr; // silence warning, see #821
if (JSON_UNLIKELY(t == value_t::null))
{
- JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.2.0")); // LCOV_EXCL_LINE
+ JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.4.0")); // LCOV_EXCL_LINE
}
break;
}
@@ -1866,7 +1868,7 @@ class basic_json
@since version 1.0.0
*/
- reference& operator=(basic_json other) noexcept (
+ basic_json& operator=(basic_json other) noexcept (
std::is_nothrow_move_constructible<value_t>::value and
std::is_nothrow_move_assignable<value_t>::value and
std::is_nothrow_move_constructible<json_value>::value and
@@ -1932,6 +1934,10 @@ class basic_json
@param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
in the output are escaped with `\uXXXX` sequences, and the result consists
of ASCII characters only.
+ @param[in] error_handler how to react on decoding errors; there are three
+ possible values: `strict` (throws and exception in case a decoding error
+ occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
+ and `ignore` (ignore invalid UTF-8 sequences during serialization).
@return string containing the serialization of the JSON value
@@ -1950,13 +1956,16 @@ class basic_json
@see https://docs.python.org/2/library/json.html#json.dump
@since version 1.0.0; indentation character @a indent_char, option
- @a ensure_ascii and exceptions added in version 3.0.0
+ @a ensure_ascii and exceptions added in version 3.0.0; error
+ handlers added in version 3.4.0.
*/
- string_t dump(const int indent = -1, const char indent_char = ' ',
- const bool ensure_ascii = false) const
+ string_t dump(const int indent = -1,
+ const char indent_char = ' ',
+ const bool ensure_ascii = false,
+ const error_handler_t error_handler = error_handler_t::strict) const
{
string_t result;
- serializer s(detail::output_adapter<char, string_t>(result), indent_char);
+ serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
if (indent >= 0)
{
@@ -2624,17 +2633,64 @@ class basic_json
}
/*!
- @brief get a pointer value (explicit)
+ @brief get a value (explicit)
- Explicit pointer access to the internally stored JSON value. No copies are
+ Explicit type conversion between the JSON value and a compatible value.
+ The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
+ `from_json()` method.
+
+ The function is equivalent to executing
+ @code {.cpp}
+ ValueType v;
+ JSONSerializer<ValueType>::from_json(*this, v);
+ @endcode
+
+ This overloads is chosen if:
+ - @a ValueType is not @ref basic_json,
+ - @ref json_serializer<ValueType> has a `from_json()` method of the form
+ `void from_json(const basic_json&, ValueType&)`, and
+
+ @tparam ValueType the input parameter type.
+
+ @return the input parameter, allowing chaining calls.
+
+ @throw what @ref json_serializer<ValueType> `from_json()` method throws
+
+ @liveexample{The example below shows several conversions from JSON values
+ to other types. There a few things to note: (1) Floating-point numbers can
+ be converted to integers\, (2) A JSON array can be converted to a standard
+ `std::vector<short>`\, (3) A JSON object can be converted to C++
+ associative containers such as `std::unordered_map<std::string\,
+ json>`.,get_to}
+
+ @since version 3.3.0
+ */
+ template<typename ValueType,
+ detail::enable_if_t <
+ not detail::is_basic_json<ValueType>::value and
+ detail::has_from_json<basic_json_t, ValueType>::value,
+ int> = 0>
+ ValueType & get_to(ValueType& v) const noexcept(noexcept(
+ JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
+ {
+ JSONSerializer<ValueType>::from_json(*this, v);
+ return v;
+ }
+
+
+ /*!
+ @brief get a pointer value (implicit)
+
+ Implicit pointer access to the internally stored JSON value. No copies are
made.
- @warning The pointer becomes invalid if the underlying JSON object
- changes.
+ @warning Writing data to the pointee of the result yields an undefined
+ state.
@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
- @ref number_unsigned_t, or @ref number_float_t.
+ @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
+ assertion.
@return pointer to the internally stored JSON value if the requested
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
@@ -2644,45 +2700,43 @@ class basic_json
@liveexample{The example below shows how pointers to internal values of a
JSON value can be requested. Note that no type conversions are made and a
`nullptr` is returned if the value and the requested pointer type does not
- match.,get__PointerType}
-
- @sa @ref get_ptr() for explicit pointer-member access
+ match.,get_ptr}
@since version 1.0.0
*/
template<typename PointerType, typename std::enable_if<
std::is_pointer<PointerType>::value, int>::type = 0>
- PointerType get() noexcept
+ auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
{
- // delegate the call to get_ptr
- return get_ptr<PointerType>();
+ // delegate the call to get_impl_ptr<>()
+ return get_impl_ptr(static_cast<PointerType>(nullptr));
}
/*!
- @brief get a pointer value (explicit)
- @copydoc get()
+ @brief get a pointer value (implicit)
+ @copydoc get_ptr()
*/
template<typename PointerType, typename std::enable_if<
- std::is_pointer<PointerType>::value, int>::type = 0>
- constexpr const PointerType get() const noexcept
+ std::is_pointer<PointerType>::value and
+ std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
+ constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
{
- // delegate the call to get_ptr
- return get_ptr<PointerType>();
+ // delegate the call to get_impl_ptr<>() const
+ return get_impl_ptr(static_cast<PointerType>(nullptr));
}
/*!
- @brief get a pointer value (implicit)
+ @brief get a pointer value (explicit)
- Implicit pointer access to the internally stored JSON value. No copies are
+ Explicit pointer access to the internally stored JSON value. No copies are
made.
- @warning Writing data to the pointee of the result yields an undefined
- state.
+ @warning The pointer becomes invalid if the underlying JSON object
+ changes.
@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
- @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
- assertion.
+ @ref number_unsigned_t, or @ref number_float_t.
@return pointer to the internally stored JSON value if the requested
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
@@ -2692,59 +2746,30 @@ class basic_json
@liveexample{The example below shows how pointers to internal values of a
JSON value can be requested. Note that no type conversions are made and a
`nullptr` is returned if the value and the requested pointer type does not
- match.,get_ptr}
+ match.,get__PointerType}
+
+ @sa @ref get_ptr() for explicit pointer-member access
@since version 1.0.0
*/
template<typename PointerType, typename std::enable_if<
std::is_pointer<PointerType>::value, int>::type = 0>
- PointerType get_ptr() noexcept
- {
- // get the type of the PointerType (remove pointer and const)
- using pointee_t = typename std::remove_const<typename
- std::remove_pointer<typename
- std::remove_const<PointerType>::type>::type>::type;
- // make sure the type matches the allowed types
- static_assert(
- std::is_same<object_t, pointee_t>::value
- or std::is_same<array_t, pointee_t>::value
- or std::is_same<string_t, pointee_t>::value
- or std::is_same<boolean_t, pointee_t>::value
- or std::is_same<number_integer_t, pointee_t>::value
- or std::is_same<number_unsigned_t, pointee_t>::value
- or std::is_same<number_float_t, pointee_t>::value
- , "incompatible pointer type");
-
- // delegate the call to get_impl_ptr<>()
- return get_impl_ptr(static_cast<PointerType>(nullptr));
+ auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
+ {
+ // delegate the call to get_ptr
+ return get_ptr<PointerType>();
}
/*!
- @brief get a pointer value (implicit)
- @copydoc get_ptr()
+ @brief get a pointer value (explicit)
+ @copydoc get()
*/
template<typename PointerType, typename std::enable_if<
- std::is_pointer<PointerType>::value and
- std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
- constexpr const PointerType get_ptr() const noexcept
- {
- // get the type of the PointerType (remove pointer and const)
- using pointee_t = typename std::remove_const<typename
- std::remove_pointer<typename
- std::remove_const<PointerType>::type>::type>::type;
- // make sure the type matches the allowed types
- static_assert(
- std::is_same<object_t, pointee_t>::value
- or std::is_same<array_t, pointee_t>::value
- or std::is_same<string_t, pointee_t>::value
- or std::is_same<boolean_t, pointee_t>::value
- or std::is_same<number_integer_t, pointee_t>::value
- or std::is_same<number_unsigned_t, pointee_t>::value
- or std::is_same<number_float_t, pointee_t>::value
- , "incompatible pointer type");
-
- // delegate the call to get_impl_ptr<>() const
- return get_impl_ptr(static_cast<PointerType>(nullptr));
+ std::is_pointer<PointerType>::value, int>::type = 0>
+ constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
+ {
+ // delegate the call to get_ptr
+ return get_ptr<PointerType>();
}
/*!
@@ -2828,12 +2853,14 @@ class basic_json
not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
not std::is_same<ValueType, typename string_t::value_type>::value and
not detail::is_basic_json<ValueType>::value
+
#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
#if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914
and not std::is_same<ValueType, typename std::string_view>::value
#endif
#endif
+ and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
, int >::type = 0 >
operator ValueType() const
{
@@ -3097,7 +3124,7 @@ class basic_json
return m_value.array->operator[](idx);
}
- JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
}
/*!
@@ -3127,7 +3154,7 @@ class basic_json
return m_value.array->operator[](idx);
}
- JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
}
/*!
@@ -3173,7 +3200,7 @@ class basic_json
return m_value.object->operator[](key);
}
- JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
}
/*!
@@ -3215,7 +3242,7 @@ class basic_json
return m_value.object->find(key)->second;
}
- JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
}
/*!
@@ -3262,7 +3289,7 @@ class basic_json
return m_value.object->operator[](key);
}
- JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
}
/*!
@@ -3305,7 +3332,7 @@ class basic_json
return m_value.object->find(key)->second;
}
- JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
}
/*!
@@ -3378,7 +3405,7 @@ class basic_json
/*!
@brief overload for a default value of type const char*
- @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const
+ @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
*/
string_t value(const typename object_t::key_type& key, const char* default_value) const
{
@@ -4943,6 +4970,26 @@ class basic_json
return {it, res.second};
}
+ /// Helper for insertion of an iterator
+ /// @note: This uses std::distance to support GCC 4.8,
+ /// see https://github.com/nlohmann/json/pull/1257
+ template<typename... Args>
+ iterator insert_iterator(const_iterator pos, Args&& ... args)
+ {
+ iterator result(this);
+ assert(m_value.array != nullptr);
+
+ auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
+ m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
+ result.m_it.array_iterator = m_value.array->begin() + insert_pos;
+
+ // This could have been written as:
+ // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
+ // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
+
+ return result;
+ }
+
/*!
@brief inserts element
@@ -4977,9 +5024,7 @@ class basic_json
}
// insert to array and return iterator
- iterator result(this);
- result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
- return result;
+ return insert_iterator(pos, val);
}
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
@@ -5030,9 +5075,7 @@ class basic_json
}
// insert to array and return iterator
- iterator result(this);
- result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
- return result;
+ return insert_iterator(pos, cnt, val);
}
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
@@ -5094,12 +5137,7 @@ class basic_json
}
// insert to array and return iterator
- iterator result(this);
- result.m_it.array_iterator = m_value.array->insert(
- pos.m_it.array_iterator,
- first.m_it.array_iterator,
- last.m_it.array_iterator);
- return result;
+ return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
}
/*!
@@ -5141,9 +5179,7 @@ class basic_json
}
// insert to array and return iterator
- iterator result(this);
- result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
- return result;
+ return insert_iterator(pos, ilist.begin(), ilist.end());
}
/*!
@@ -5972,6 +6008,8 @@ class basic_json
@param[in] cb a parser callback function of type @ref parser_callback_t
which is used to control the deserialization by filtering unwanted values
(optional)
+ @param[in] allow_exceptions whether to throw exceptions in case of a
+ parse error (optional, true by default)
@return result of the deserialization
@@ -6367,7 +6405,7 @@ class basic_json
vector in CBOR format.,to_cbor}
@sa http://cbor.io
- @sa @ref from_cbor(detail::input_adapter, const bool strict) for the
+ @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
analogous deserialization
@sa @ref to_msgpack(const basic_json&) for the related MessagePack format
@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
@@ -6464,8 +6502,7 @@ class basic_json
vector in MessagePack format.,to_msgpack}
@sa http://msgpack.org
- @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
- analogous deserialization
+ @sa @ref from_msgpack for the analogous deserialization
@sa @ref to_cbor(const basic_json& for the related CBOR format
@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
related UBJSON format
@@ -6562,7 +6599,7 @@ class basic_json
vector in UBJSON format.,to_ubjson}
@sa http://ubjson.org
- @sa @ref from_ubjson(detail::input_adapter, const bool strict) for the
+ @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
analogous deserialization
@sa @ref to_cbor(const basic_json& for the related CBOR format
@sa @ref to_msgpack(const basic_json&) for the related MessagePack format
@@ -6590,6 +6627,91 @@ class basic_json
binary_writer<char>(o).write_ubjson(j, use_size, use_type);
}
+
+ /*!
+ @brief Serializes the given JSON object `j` to BSON and returns a vector
+ containing the corresponding BSON-representation.
+
+ BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
+ stored as a single entity (a so-called document).
+
+ The library uses the following mapping from JSON values types to BSON types:
+
+ JSON value type | value/range | BSON type | marker
+ --------------- | --------------------------------- | ----------- | ------
+ null | `null` | null | 0x0A
+ boolean | `true`, `false` | boolean | 0x08
+ number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
+ number_integer | -2147483648..2147483647 | int32 | 0x10
+ number_integer | 2147483648..9223372036854775807 | int64 | 0x12
+ number_unsigned | 0..2147483647 | int32 | 0x10
+ number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
+ number_unsigned | 9223372036854775808..18446744073709551615| -- | --
+ number_float | *any value* | double | 0x01
+ string | *any value* | string | 0x02
+ array | *any value* | document | 0x04
+ object | *any value* | document | 0x03
+
+ @warning The mapping is **incomplete**, since only JSON-objects (and things
+ contained therein) can be serialized to BSON.
+ Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
+ and the keys may not contain U+0000, since they are serialized a
+ zero-terminated c-strings.
+
+ @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
+ @throw out_of_range.409 if a key in `j` contains a NULL (U+0000)
+ @throw type_error.317 if `!j.is_object()`
+
+ @pre The input `j` is required to be an object: `j.is_object() == true`.
+
+ @note Any BSON output created via @ref to_bson can be successfully parsed
+ by @ref from_bson.
+
+ @param[in] j JSON value to serialize
+ @return BSON serialization as byte vector
+
+ @complexity Linear in the size of the JSON value @a j.
+
+ @liveexample{The example shows the serialization of a JSON value to a byte
+ vector in BSON format.,to_bson}
+
+ @sa http://bsonspec.org/spec.html
+ @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
+ analogous deserialization
+ @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
+ related UBJSON format
+ @sa @ref to_cbor(const basic_json&) for the related CBOR format
+ @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
+ */
+ static std::vector<uint8_t> to_bson(const basic_json& j)
+ {
+ std::vector<uint8_t> result;
+ to_bson(j, result);
+ return result;
+ }
+
+ /*!
+ @brief Serializes the given JSON object `j` to BSON and forwards the
+ corresponding BSON-representation to the given output_adapter `o`.
+ @param j The JSON object to convert to BSON.
+ @param o The output adapter that receives the binary BSON representation.
+ @pre The input `j` shall be an object: `j.is_object() == true`
+ @sa @ref to_bson(const basic_json&)
+ */
+ static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
+ {
+ binary_writer<uint8_t>(o).write_bson(j);
+ }
+
+ /*!
+ @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
+ */
+ static void to_bson(const basic_json& j, detail::output_adapter<char> o)
+ {
+ binary_writer<char>(o).write_bson(j);
+ }
+
+
/*!
@brief create a JSON value from an input in CBOR format
@@ -6631,7 +6753,7 @@ class basic_json
map | object | 0xBF
False | `false` | 0xF4
True | `true` | 0xF5
- Nill | `null` | 0xF6
+ Null | `null` | 0xF6
Half-Precision Float | number_float | 0xF9
Single-Precision Float | number_float | 0xFA
Double-Precision Float | number_float | 0xFB
@@ -6677,14 +6799,14 @@ class basic_json
@sa http://cbor.io
@sa @ref to_cbor(const basic_json&) for the analogous serialization
- @sa @ref from_msgpack(detail::input_adapter, const bool, const bool) for the
+ @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
related MessagePack format
- @sa @ref from_ubjson(detail::input_adapter, const bool, const bool) for the
+ @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
related UBJSON format
@since version 2.0.9; parameter @a start_index since 2.1.1; changed to
consume input adapters, removed start_index parameter, and added
- @a strict parameter since 3.0.0; added @allow_exceptions parameter
+ @a strict parameter since 3.0.0; added @a allow_exceptions parameter
since 3.2.0
*/
static basic_json from_cbor(detail::input_adapter&& i,
@@ -6698,7 +6820,7 @@ class basic_json
}
/*!
- @copydoc from_cbor(detail::input_adapter, const bool, const bool)
+ @copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
*/
template<typename A1, typename A2,
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
@@ -6780,14 +6902,16 @@ class basic_json
@sa http://msgpack.org
@sa @ref to_msgpack(const basic_json&) for the analogous serialization
- @sa @ref from_cbor(detail::input_adapter, const bool, const bool) for the
+ @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
related CBOR format
- @sa @ref from_ubjson(detail::input_adapter, const bool, const bool) for
+ @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
the related UBJSON format
+ @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
+ the related BSON format
@since version 2.0.9; parameter @a start_index since 2.1.1; changed to
consume input adapters, removed start_index parameter, and added
- @a strict parameter since 3.0.0; added @allow_exceptions parameter
+ @a strict parameter since 3.0.0; added @a allow_exceptions parameter
since 3.2.0
*/
static basic_json from_msgpack(detail::input_adapter&& i,
@@ -6801,7 +6925,7 @@ class basic_json
}
/*!
- @copydoc from_msgpack(detail::input_adapter, const bool, const bool)
+ @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
*/
template<typename A1, typename A2,
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
@@ -6865,12 +6989,14 @@ class basic_json
@sa http://ubjson.org
@sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
analogous serialization
- @sa @ref from_cbor(detail::input_adapter, const bool, const bool) for the
+ @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
related CBOR format
- @sa @ref from_msgpack(detail::input_adapter, const bool, const bool) for
+ @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
the related MessagePack format
+ @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
+ the related BSON format
- @since version 3.1.0; added @allow_exceptions parameter since 3.2.0
+ @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
*/
static basic_json from_ubjson(detail::input_adapter&& i,
const bool strict = true,
@@ -6883,7 +7009,7 @@ class basic_json
}
/*!
- @copydoc from_ubjson(detail::input_adapter, const bool, const bool)
+ @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
*/
template<typename A1, typename A2,
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
@@ -6897,6 +7023,91 @@ class basic_json
return res ? result : basic_json(value_t::discarded);
}
+ /*!
+ @brief Create a JSON value from an input in BSON format
+
+ Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
+ serialization format.
+
+ The library maps BSON record types to JSON value types as follows:
+
+ BSON type | BSON marker byte | JSON value type
+ --------------- | ---------------- | ---------------------------
+ double | 0x01 | number_float
+ string | 0x02 | string
+ document | 0x03 | object
+ array | 0x04 | array
+ binary | 0x05 | still unsupported
+ undefined | 0x06 | still unsupported
+ ObjectId | 0x07 | still unsupported
+ boolean | 0x08 | boolean
+ UTC Date-Time | 0x09 | still unsupported
+ null | 0x0A | null
+ Regular Expr. | 0x0B | still unsupported
+ DB Pointer | 0x0C | still unsupported
+ JavaScript Code | 0x0D | still unsupported
+ Symbol | 0x0E | still unsupported
+ JavaScript Code | 0x0F | still unsupported
+ int32 | 0x10 | number_integer
+ Timestamp | 0x11 | still unsupported
+ 128-bit decimal float | 0x13 | still unsupported
+ Max Key | 0x7F | still unsupported
+ Min Key | 0xFF | still unsupported
+
+ @warning The mapping is **incomplete**. The unsupported mappings
+ are indicated in the table above.
+
+ @param[in] i an input in BSON format convertible to an input adapter
+ @param[in] strict whether to expect the input to be consumed until EOF
+ (true by default)
+ @param[in] allow_exceptions whether to throw exceptions in case of a
+ parse error (optional, true by default)
+
+ @return deserialized JSON value
+
+ @throw parse_error.114 if an unsupported BSON record type is encountered
+
+ @complexity Linear in the size of the input @a i.
+
+ @liveexample{The example shows the deserialization of a byte vector in
+ BSON format to a JSON value.,from_bson}
+
+ @sa http://bsonspec.org/spec.html
+ @sa @ref to_bson(const basic_json&) for the analogous serialization
+ @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
+ related CBOR format
+ @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
+ the related MessagePack format
+ @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
+ related UBJSON format
+ */
+ static basic_json from_bson(detail::input_adapter&& i,
+ const bool strict = true,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+ const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
+ return res ? result : basic_json(value_t::discarded);
+ }
+
+ /*!
+ @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
+ */
+ template<typename A1, typename A2,
+ detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
+ static basic_json from_bson(A1 && a1, A2 && a2,
+ const bool strict = true,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+ const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
+ return res ? result : basic_json(value_t::discarded);
+ }
+
+
+
/// @}
//////////////////////////
@@ -7262,11 +7473,9 @@ class basic_json
// avoid undefined behavior
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
}
- else
- {
- // default case: insert add offset
- parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
- }
+
+ // default case: insert add offset
+ parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
}
break;
}
@@ -7642,7 +7851,7 @@ class basic_json
Thereby, `Target` is the current object; that is, the patch is applied to
the current value.
- @param[in] patch the patch to apply
+ @param[in] apply_patch the patch to apply
@complexity Linear in the lengths of @a patch.
@@ -7654,15 +7863,15 @@ class basic_json
@since version 3.0.0
*/
- void merge_patch(const basic_json& patch)
+ void merge_patch(const basic_json& apply_patch)
{
- if (patch.is_object())
+ if (apply_patch.is_object())
{
if (not is_object())
{
*this = object();
}
- for (auto it = patch.begin(); it != patch.end(); ++it)
+ for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
{
if (it.value().is_null())
{
@@ -7676,7 +7885,7 @@ class basic_json
}
else
{
- *this = patch;
+ *this = apply_patch;
}
}
@@ -7691,19 +7900,6 @@ class basic_json
// specialization of std::swap, and std::hash
namespace std
{
-/*!
-@brief exchanges the values of two JSON objects
-
-@since version 1.0.0
-*/
-template<>
-inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
- is_nothrow_move_constructible<nlohmann::json>::value and
- is_nothrow_move_assignable<nlohmann::json>::value
-)
-{
- j1.swap(j2);
-}
/// hash value for JSON objects
template<>
@@ -7739,6 +7935,20 @@ struct less< ::nlohmann::detail::value_t>
}
};
+/*!
+@brief exchanges the values of two JSON objects
+
+@since version 1.0.0
+*/
+template<>
+inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
+ is_nothrow_move_constructible<nlohmann::json>::value and
+ is_nothrow_move_assignable<nlohmann::json>::value
+)
+{
+ j1.swap(j2);
+}
+
} // namespace std
/*!