JSON Voorhees
Killer JSON for C++
Loading...
Searching...
No Matches
jsonv::documents Class Referencefinal

The JSON documents in one input, read one after another, each through a reader of its own. More...

#include <jsonv/reader.hpp>

+ Inheritance diagram for jsonv::documents:
+ Collaboration diagram for jsonv::documents:

Public Types

using iterator_concept = std::input_iterator_tag
 What this models in C++20 terms: an input iterator, since each document is parsed onto the tape of the last.
 
using value_type = reader
 What dereferencing gives a reference to.
 
using difference_type = std::ptrdiff_t
 What every iterator has to name, although stepping through documents never measures a distance.
 

Public Member Functions

 documents (const documents &)=delete
 
documents & operator= (const documents &)=delete
 
iterator begin ()
 Get an iterator on the first document which has not been passed yet.
 
std::default_sentinel_t end () const noexcept
 The end of the documents, which an iterator compares equal to once it has passed the last one.
 
 iterator () noexcept=default
 Create an iterator which is already at the end.
 
reader & operator* () const
 Get the reader for the document this is on.
 
 documents (std::string_view source)
 Read the documents in JSON source.
 
 documents (std::string_view source, const parse_options &parse_options)
 Read the documents in JSON source.
 
 documents (const char *source)
 Read the documents in JSON source.
 
 documents (const char *source, const parse_options &parse_options)
 Read the documents in JSON source.
 
 documents (std::string &&source)
 Read the documents in JSON source.
 
 documents (std::string &&source, const parse_options &parse_options)
 Read the documents in JSON source.
 
 documents (std::istream &source)
 Read the documents in what is left of the source stream, as reader(std::istream&) reads one.
 
 documents (std::istream &source, const parse_options &parse_options)
 Read the documents in what is left of the source stream, as reader(std::istream&) reads one.
 
 documents (documents &&) noexcept
 Moving transfers the source and the position in it.
 
documents & operator= (documents &&) noexcept
 Moving transfers the source and the position in it.
 
iterator & operator++ ()
 Parse the next document and move onto it, or onto the end if there is no other.
 
void operator++ (int)
 Parse the next document and move onto it, or onto the end if there is no other.
 

Friends

bool operator== (const iterator &self, std::default_sentinel_t) noexcept
 Is self at the end of its documents?
 

Detailed Description

The JSON documents in one input, read one after another, each through a reader of its own.

An input iterator over documents.

Every other way of reading JSON text takes all of it as one document, and refuses anything after its value. This takes it as a sequence of documents instead: JSON Lines, with one to a line; concatenated JSON as jq reads and writes it, as in {"a":1}{"a":2}; or a run of pretty-printed documents. Any whitespace may separate two documents, as may comments where parse_options::comments allows them, or nothing at all where the first ends with a character the second could not have continued: [1][2] and "a""b" are two documents each, while 12 is one.

std::ifstream file("records.jsonl");
for (jsonv::reader& doc : jsonv::documents(file))
records.push_back(jsonv::deserialize<record>(doc));
The JSON documents in one input, read one after another, each through a reader of its own.
Definition reader.hpp:509
A reader instance reads from some form of JSON source (probably a string) and converts it into a JSON...
Definition reader.hpp:108
T deserialize(const value &from, const formats &fmts)
Deserialize a C++ value from from using the provided fmts.

Each document is handed out as a reader on its ast_node_type::document_start, as a freshly-created one is, so jsonv::deserialize reads it as a whole document and anything else which takes a reader takes it. It is parsed with the parse_options this was created with as though it were the only document: parse_options::require_document and parse_options::max_structure_depth apply to each one. Nothing is parsed until the iterator reaches it, and then onto the tape the document before it was read from, so many small documents cost one tape the size of the largest rather than one each. That is also why the reader for a document is valid only until the iterator moves on, wherever it has been moved to: by then its tape holds the next document.

Whitespace and comments after the last document end the sequence, so input with no value in it holds no documents.

Parsing text never throws, here as elsewhere. A document which is not valid JSON is still handed out, as a reader whose reader::validate throws parse_error and from which jsonv::deserialize throws a deserialization_error saying so, and the sequence ends with it: the parse stopped at the error, and nothing says where that document would have ended and the next begun. The position in a parse_error counts from the start of the whole input, not of the document it is in.

A std::string_view deserialized from a document views the source. A source given as a std::string rvalue or a std::istream is kept by this instance, so such a view is valid for as long as it is; any other is the caller's, and valid for as long as the caller keeps it.

Dereferencing it gives the reader for the document it is on, and incrementing it parses the next one. Once it has passed the last, it compares equal to std::default_sentinel.

Definition at line 508 of file reader.hpp.

Member Typedef Documentation

◆ difference_type

using jsonv::documents::difference_type = std::ptrdiff_t

What every iterator has to name, although stepping through documents never measures a distance.

Definition at line 590 of file reader.hpp.

◆ iterator_concept

using jsonv::documents::iterator_concept = std::input_iterator_tag

What this models in C++20 terms: an input iterator, since each document is parsed onto the tape of the last.

Definition at line 584 of file reader.hpp.

◆ value_type

What dereferencing gives a reference to.

Definition at line 587 of file reader.hpp.

Constructor & Destructor Documentation

◆ documents() [1/9]

jsonv::documents::documents ( std::string_view  source)
explicit

Read the documents in JSON source.

The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.

◆ documents() [2/9]

jsonv::documents::documents ( std::string_view  source,
const parse_options &  parse_options 
)
explicit

Read the documents in JSON source.

The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.

◆ documents() [3/9]

jsonv::documents::documents ( const char *  source)
explicit

Read the documents in JSON source.

The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.

◆ documents() [4/9]

jsonv::documents::documents ( const char *  source,
const parse_options &  parse_options 
)
explicit

Read the documents in JSON source.

The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.

◆ documents() [5/9]

jsonv::documents::documents ( std::string &&  source)
explicit

Read the documents in JSON source.

The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.

◆ documents() [6/9]

jsonv::documents::documents ( std::string &&  source,
const parse_options &  parse_options 
)
explicit

Read the documents in JSON source.

The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.

◆ documents() [7/9]

jsonv::documents::documents ( std::istream &  source)
explicit

Read the documents in what is left of the source stream, as reader(std::istream&) reads one.

The stream is read to its end here, and this instance keeps the text, so nothing reads source again once this returns. A parse_error position counts from where source was when this was called.

◆ documents() [8/9]

jsonv::documents::documents ( std::istream &  source,
const parse_options &  parse_options 
)
explicit

Read the documents in what is left of the source stream, as reader(std::istream&) reads one.

The stream is read to its end here, and this instance keeps the text, so nothing reads source again once this returns. A parse_error position counts from where source was when this was called.

◆ documents() [9/9]

jsonv::documents::documents ( documents &&  )
noexcept

Moving transfers the source and the position in it.

Iterators and readers already handed out are unaffected, and go on belonging to the instance moved to. The moved-from instance has no documents to give: begin throws std::invalid_argument, as using a moved-from reader does.

Member Function Documentation

◆ begin()

iterator jsonv::documents::begin ( )

Get an iterator on the first document which has not been passed yet.

The first call parses the first document; any later call returns an iterator wherever the earlier ones have got to, since this is an input range and can only be walked once.

Exceptions
std::invalid_argumentif this instance has been moved-from, or if the parse_options ask for a parse_options::max_structure_depth beyond the limit, as parse_index::parse does.

◆ end()

std::default_sentinel_t jsonv::documents::end ( ) const
inlinenoexcept

The end of the documents, which an iterator compares equal to once it has passed the last one.

Definition at line 566 of file reader.hpp.

◆ operator*()

reader & jsonv::documents::operator* ( ) const

Get the reader for the document this is on.

It reads the tape every document of the documents is parsed onto, so it is valid until this iterator, or any other from the same documents, is incremented.

Exceptions
std::logic_errorif this iterator is at the end.

◆ operator++() [1/2]

iterator & jsonv::documents::operator++ ( )

Parse the next document and move onto it, or onto the end if there is no other.

Exceptions
std::bad_allocif the tape cannot grow to hold the next document, which ends the sequence there.

◆ operator++() [2/2]

void jsonv::documents::operator++ ( int  )
inline

Parse the next document and move onto it, or onto the end if there is no other.

Exceptions
std::bad_allocif the tape cannot grow to hold the next document, which ends the sequence there.

Definition at line 609 of file reader.hpp.

◆ operator=()

documents & jsonv::documents::operator= ( documents &&  )
noexcept

Moving transfers the source and the position in it.

Iterators and readers already handed out are unaffected, and go on belonging to the instance moved to. The moved-from instance has no documents to give: begin throws std::invalid_argument, as using a moved-from reader does.

Friends And Related Symbol Documentation

◆ documents

friend class documents
friend

Definition at line 620 of file reader.hpp.

◆ operator==

bool operator== ( const iterator &  self,
std::default_sentinel_t   
)
friend

Is self at the end of its documents?

Definition at line 614 of file reader.hpp.


The documentation for this class was generated from the following file: