Defined in header <cparse/Cursor.hh>

explicit Cursor( std::string sourceName = "" );                              // (1)
Cursor( std::string sourceName, std::shared_ptr<stream_type> externalStream ); // (2)

Cursor( Cursor const& other );                                                 // (3)
Cursor( Cursor&& other ) = delete;                                             // (4)

Constructs a Cursor.

  1. Opens sourceName as an std::ifstream in std::ios::in mode with std::ios::skipws disabled. If sourceName is empty, the file backing the cursor is not opened and the resulting cursor is invalid (isValid() returns false).
  2. Wraps a stream you already own. The stream is held by std::shared_ptr and its lifetime is extended for as long as any Cursor holds a reference to it.
  3. Copy constructor. Both cursors share the same underlying stream and filename (via shared_ptr); the copy starts at the source's current line, column and stored position.
  4. Move construction is deleted — see Notes.

Both stream-opening constructors set the stream's exception mask to:

stream_type::failbit | stream_type::eofbit | stream_type::badbit

This is why get() and peek() can throw std::ios_base::failure and the safe variants exist.

Parameters

ParameterDescription
sourceNamePath to the source file (overload 1) or a diagnostic label for the stream (overload 2). Stored and returned by getFilename().
externalStreamA shared pointer to an already-constructed input stream. Any type derived from std::istream (std::ifstream, std::istringstream, etc.).
otherThe Cursor to copy.

Exceptions

  1. May throw if opening the file fails, subject to the stream's exception mask. If sourceName is empty, does not open a file and does not throw.
  2. Does not open a file. May throw only if the shared_ptr operations do.
  3. Copy: does not throw; copies simple members and shares the stream.

Notes

Move construction is deleted deliberately. Parser::storeCursor() returns a Cursor const& aliasing the parser's own cursor, and Parser::extractToken uses Cursor snapshot = *cursor; for backtracking. A move constructor would silently apply here and wreck the "snapshot is independent" invariant.

Copy construction is noexcept-effectively (no noexcept marker in the declaration but the body performs no throwing operation). The underlying stream is not copied; the two cursors share it.

Example

#include <cparse/Cursor.hh>
#include <sstream>

int main()
{
    // (1) empty — invalid cursor
    fedem::parser::Cursor invalid;
    // invalid.isValid() == false

    // (1) file-backed
    fedem::parser::Cursor fromFile("input.txt");

    // (2) memory-backed
    auto ss = std::make_shared<std::istringstream>("key = value");
    fedem::parser::Cursor fromMemory("<memory>", ss);

    // (3) copy
    fedem::parser::Cursor snapshot = fromMemory;
}

See also