mirror of
https://github.com/nlohmann/json.git
synced 2026-10-17 03:28:12 +00:00
Copy const rvalue strings and document the accepted inputs
json_document::parse(std::move(const_string)) failed to compile with "no matching read_kind": only a non-const rvalue std::string can be moved from. Treat a const rvalue as a copied byte container. parse() does not accept everything BasicJsonType::parse() does: a FILE* and pointers to or arrays of wide characters are rejected at compile time. List the supported inputs instead. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
3 files changed
+37
-15
No files matched your search
@@ -19,24 +19,33 @@ static basic_json_document parse(IteratorType first, IteratorType last,
|
|||||||
1. Deserialize from a compatible input, borrowing or owning it depending on its value category and type (see Notes).
|
1. Deserialize from a compatible input, borrowing or owning it depending on its value category and type (see Notes).
|
||||||
2. Deserialize from a pair of input iterators.
|
2. Deserialize from a pair of input iterators.
|
||||||
|
|
||||||
Both overloads accept exactly what [`BasicJsonType::parse()`](../basic_json/parse.md) accepts, with the same
|
Both overloads accept the same JSON text as [`BasicJsonType::parse()`](../basic_json/parse.md), with the same
|
||||||
`ignore_comments`/`ignore_trailing_commas` options, but build a [`basic_json_document`](index.md) (a flat index into
|
`ignore_comments`/`ignore_trailing_commas` options, but build a [`basic_json_document`](index.md) (a flat index into
|
||||||
the input) instead of a tree of `BasicJsonType` values.
|
the input) instead of a tree of `BasicJsonType` values. The input must be byte-oriented (see the template parameters
|
||||||
|
below): not every input type of `BasicJsonType::parse()` is supported.
|
||||||
|
|
||||||
## Template parameters
|
## Template parameters
|
||||||
|
|
||||||
`InputType`
|
`InputType`
|
||||||
: A compatible input, for instance:
|
: A byte-oriented input, one of:
|
||||||
|
|
||||||
- a `#!cpp std::string`, `#!cpp std::string_view`, or a C-style array of characters
|
- a `#!cpp std::string`, `#!cpp std::string_view`, or a C-style array of single-byte characters
|
||||||
- a pointer to a null-terminated string of single byte characters
|
- a pointer to a null-terminated string of single-byte characters (`#!cpp char`, `#!cpp signed char`,
|
||||||
|
`#!cpp unsigned char`, `#!cpp std::uint8_t`)
|
||||||
- a container for which `#!cpp obj.data()` and `#!cpp obj.size()` give contiguous single-byte access, e.g.
|
- a container for which `#!cpp obj.data()` and `#!cpp obj.size()` give contiguous single-byte access, e.g.
|
||||||
`#!cpp std::vector<char>` or `#!cpp std::vector<std::uint8_t>`
|
`#!cpp std::vector<char>` or `#!cpp std::vector<std::uint8_t>`
|
||||||
- an `#!cpp std::istream` object, or anything else [`BasicJsonType::parse()`](../basic_json/parse.md) accepts
|
- an `#!cpp std::istream` object
|
||||||
|
- a wide string object (`#!cpp std::wstring`, `#!cpp std::u16string`, `#!cpp std::u32string`), which is converted
|
||||||
|
to UTF-8
|
||||||
|
|
||||||
|
Other inputs are not supported: a `#!cpp FILE*`, and pointers to or arrays of wide characters (`#!cpp wchar_t`,
|
||||||
|
`#!cpp char16_t`, `#!cpp char32_t`) are rejected at compile time by a `#!cpp static_assert`. (Use
|
||||||
|
[`BasicJsonType::parse()`](../basic_json/parse.md) for these.)
|
||||||
|
|
||||||
`IteratorType`
|
`IteratorType`
|
||||||
: a compatible iterator type, for instance a pair of pointers such as `ptr` and `ptr + len`, or a pair of
|
: an input iterator type, for instance a pair of pointers such as `ptr` and `ptr + len`, or a pair of
|
||||||
`#!cpp std::string::iterator`
|
`#!cpp std::string::iterator`; the iterators of single-byte characters are borrowed or read like the byte inputs
|
||||||
|
above, those of wide characters are converted to UTF-8
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
@@ -84,8 +93,8 @@ Linear in the length of the input.
|
|||||||
| `input` | ownership |
|
| `input` | ownership |
|
||||||
|--------------------------------------------------------------------------------------|--------------------------------------------------------------|
|
|--------------------------------------------------------------------------------------|--------------------------------------------------------------|
|
||||||
| lvalue byte container (`std::string`, `std::vector<char>`, ...), `std::string_view`, C string, character array | **borrowed** -- `input` must outlive the document |
|
| lvalue byte container (`std::string`, `std::vector<char>`, ...), `std::string_view`, C string, character array | **borrowed** -- `input` must outlive the document |
|
||||||
| rvalue `#!cpp std::string` | **owned**, moved in without a copy |
|
| non-const rvalue `#!cpp std::string` | **owned**, moved in without a copy |
|
||||||
| rvalue byte container other than `#!cpp std::string` | **owned**, copied |
|
| other rvalue byte container (including a `#!cpp const` rvalue `#!cpp std::string`) | **owned**, copied |
|
||||||
| stream, wide string, or anything else read through the general input adapter | **owned**, read into a buffer (a stream is read to its end) |
|
| stream, wide string, or anything else read through the general input adapter | **owned**, read into a buffer (a stream is read to its end) |
|
||||||
|
|
||||||
For overload (2), a pair of pointers to single-byte integers (e.g. `#!cpp const char*`, `#!cpp std::uint8_t*`) is
|
For overload (2), a pair of pointers to single-byte integers (e.g. `#!cpp const char*`, `#!cpp std::uint8_t*`) is
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string> // basic_string, char_traits, string
|
#include <string> // basic_string, char_traits, string
|
||||||
#include <type_traits> // decay, integral_constant, is_array, is_lvalue_reference, is_pointer, is_same, remove_reference
|
#include <type_traits> // decay, integral_constant, is_array, is_const, is_integral, is_lvalue_reference, is_pointer, is_same, remove_reference
|
||||||
#include <utility> // forward
|
#include <utility> // forward
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
@@ -28,12 +28,12 @@ namespace view
|
|||||||
/// how a document takes its input
|
/// how a document takes its input
|
||||||
enum class input_kind
|
enum class input_kind
|
||||||
{
|
{
|
||||||
move_string, ///< rvalue std::string: owned without a copy
|
move_string, ///< non-const rvalue std::string: owned without a copy
|
||||||
c_string, ///< const char* (NUL-terminated): borrowed
|
c_string, ///< const char* (NUL-terminated): borrowed
|
||||||
char_array, ///< char array (e.g. a string literal): borrowed
|
char_array, ///< char array (e.g. a string literal): borrowed
|
||||||
borrow_range, ///< lvalue contiguous byte container, or std::string_view: borrowed
|
borrow_range, ///< lvalue contiguous byte container, or std::string_view: borrowed
|
||||||
copy_range, ///< rvalue contiguous byte container: copied
|
copy_range, ///< rvalue contiguous byte container (a const rvalue std::string too): copied
|
||||||
adapter, ///< anything else parse() accepts (streams, wide strings, ...): read into a buffer
|
adapter, ///< streams, wide strings, and the rest of what the library's input adapter reads: read into a buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename InputType>
|
template<typename InputType>
|
||||||
@@ -52,7 +52,7 @@ struct classify_input
|
|||||||
static constexpr input_kind value =
|
static constexpr input_kind value =
|
||||||
std::is_array<R>::value ? input_kind::char_array
|
std::is_array<R>::value ? input_kind::char_array
|
||||||
: std::is_pointer<D>::value ? input_kind::c_string
|
: std::is_pointer<D>::value ? input_kind::c_string
|
||||||
: (is_rvalue && std::is_same<D, std::string>::value) ? input_kind::move_string
|
: (is_rvalue && !std::is_const<R>::value && std::is_same<D, std::string>::value) ? input_kind::move_string
|
||||||
: (is_bytes && (!is_rvalue || is_string_view)) ? input_kind::borrow_range
|
: (is_bytes && (!is_rvalue || is_string_view)) ? input_kind::borrow_range
|
||||||
: is_bytes ? input_kind::copy_range
|
: is_bytes ? input_kind::copy_range
|
||||||
: input_kind::adapter;
|
: input_kind::adapter;
|
||||||
|
|||||||
@@ -314,6 +314,19 @@ TEST_CASE("json_view")
|
|||||||
CHECK(from_rvalue.owns_source());
|
CHECK(from_rvalue.owns_source());
|
||||||
CHECK(from_rvalue.root().materialize() == expected);
|
CHECK(from_rvalue.root().materialize() == expected);
|
||||||
CHECK(json_document::parse(std::vector<char>(text.begin(), text.end())).owns_source());
|
CHECK(json_document::parse(std::vector<char>(text.begin(), text.end())).owns_source());
|
||||||
|
// a const rvalue cannot be moved from, and is not borrowed (it may be a
|
||||||
|
// temporary): it is copied, as is a const rvalue of any container
|
||||||
|
const std::string const_text = text;
|
||||||
|
const json_document from_const_rvalue = json_document::parse(std::move(const_text)); // NOLINT(performance-move-const-arg,hicpp-move-const-arg)
|
||||||
|
CHECK(from_const_rvalue.owns_source());
|
||||||
|
CHECK(from_const_rvalue.source().data() != const_text.data());
|
||||||
|
CHECK(from_const_rvalue.root().materialize() == expected);
|
||||||
|
json_document read_const_rvalue;
|
||||||
|
read_const_rvalue.read(std::move(const_text)); // NOLINT(performance-move-const-arg,hicpp-move-const-arg)
|
||||||
|
CHECK(read_const_rvalue.owns_source());
|
||||||
|
CHECK(read_const_rvalue.root().materialize() == expected);
|
||||||
|
const std::vector<char> const_chars(text.begin(), text.end());
|
||||||
|
CHECK(json_document::parse(std::move(const_chars)).owns_source()); // NOLINT(performance-move-const-arg,hicpp-move-const-arg)
|
||||||
CHECK(json_document::parse_copy(text).owns_source());
|
CHECK(json_document::parse_copy(text).owns_source());
|
||||||
CHECK(json_document::parse_copy(text).root().materialize() == expected);
|
CHECK(json_document::parse_copy(text).root().materialize() == expected);
|
||||||
std::istringstream stream(text);
|
std::istringstream stream(text);
|
||||||
|
|||||||
Reference in new issue
Block a user