unit.SetDirection(DIR, handler);
IoStatementState &io{unit.BeginIoStatement<ExternalListIoStatementState<DIR>>(
unit, sourceFile, sourceLine)};
- if constexpr (DIR == Direction::Input) {
- unit.BeginReadingRecord(handler);
- }
return &io;
}
IoStatementState &io{
unit.BeginIoStatement<ExternalFormattedIoStatementState<DIR>>(
unit, format, formatLength, sourceFile, sourceLine)};
- if constexpr (DIR == Direction::Input) {
- unit.BeginReadingRecord(handler);
- }
return &io;
}
unit, sourceFile, sourceLine)};
IoErrorHandler handler{terminator};
unit.SetDirection(DIR, handler);
- if constexpr (DIR == Direction::Input) {
- unit.BeginReadingRecord(handler);
- } else {
+ if constexpr (DIR == Direction::Output) {
if (unit.access == Access::Sequential && !unit.isFixedRecordLength) {
// Create space for (sub)record header to be completed by
// UnformattedIoStatementState<Direction::Output>::EndIoStatement()
bool IONAME(InputDescriptor)(Cookie cookie, const Descriptor &) {
IoStatementState &io{*cookie};
+ io.BeginReadingRecord();
io.GetIoErrorHandler().Crash("InputDescriptor: not yet implemented"); // TODO
}
bool IONAME(InputUnformattedBlock)(
Cookie cookie, char *x, std::size_t length, std::size_t elementBytes) {
IoStatementState &io{*cookie};
+ io.BeginReadingRecord();
if (auto *unf{io.get_if<UnformattedIoStatementState<Direction::Input>>()}) {
return unf->Receive(x, length, elementBytes);
}
"InputInteger64() called for a non-input I/O statement");
return false;
}
+ io.BeginReadingRecord();
if (auto edit{io.GetNextDataEdit()}) {
if (edit->descriptor == DataEdit::ListDirectedNullValue) {
return true;
"InputReal() called for a non-input I/O statement");
return false;
}
+ io.BeginReadingRecord();
if (auto edit{io.GetNextDataEdit()}) {
if (edit->descriptor == DataEdit::ListDirectedNullValue) {
return true;
"InputComplex() called for a non-input I/O statement");
return false;
}
+ io.BeginReadingRecord();
for (int j{0}; j < 2; ++j) {
if (auto edit{io.GetNextDataEdit()}) {
if (edit->descriptor == DataEdit::ListDirectedNullValue) {
"InputAscii() called for a non-input I/O statement");
return false;
}
+ io.BeginReadingRecord();
if (auto edit{io.GetNextDataEdit()}) {
if (edit->descriptor == DataEdit::ListDirectedNullValue) {
return true;
"InputLogical() called for a non-input I/O statement");
return false;
}
+ io.BeginReadingRecord();
if (auto edit{io.GetNextDataEdit()}) {
if (edit->descriptor == DataEdit::ListDirectedNullValue) {
return true;
}
template <Direction DIR> int ExternalIoStatementState<DIR>::EndIoStatement() {
- if (!unit().nonAdvancing) {
+ if constexpr (DIR == Direction::Input) {
+ BeginReadingRecord(); // in case of READ with no data items
+ }
+ if (!unit().nonAdvancing && GetIoStat() != IostatEnd) {
unit().AdvanceRecord(*this);
}
if constexpr (DIR == Direction::Output) {
return unit().HandleRelativePosition(n);
}
+template <Direction DIR>
+void ExternalIoStatementState<DIR>::BeginReadingRecord() {
+ if constexpr (DIR == Direction::Input) {
+ if (!beganReading_) {
+ beganReading_ = true;
+ unit().BeginReadingRecord(*this);
+ }
+ }
+}
+
template <Direction DIR, typename CHAR>
ExternalFormattedIoStatementState<DIR, CHAR>::ExternalFormattedIoStatementState(
ExternalFileUnit &unit, const CHAR *format, std::size_t formatLength,
[](auto &x) -> MutableModes & { return x.get().mutableModes(); }, u_);
}
+void IoStatementState::BeginReadingRecord() {
+ std::visit([](auto &x) { return x.get().BeginReadingRecord(); }, u_);
+}
+
IoErrorHandler &IoStatementState::GetIoErrorHandler() const {
return std::visit(
[](auto &x) -> IoErrorHandler & {
IoErrorHandler &GetIoErrorHandler() const;
ExternalFileUnit *GetExternalFileUnit() const; // null if internal unit
MutableModes &mutableModes();
+ void BeginReadingRecord();
// N.B.: this also works with base classes
template <typename A> A *get_if() const {
int EndIoStatement();
std::optional<DataEdit> GetNextDataEdit(IoStatementState &, int = 1);
ExternalFileUnit *GetExternalFileUnit() const { return nullptr; }
+ void BeginReadingRecord() {}
};
struct InputStatementState {};
void BackspaceRecord();
void HandleRelativePosition(std::int64_t);
void HandleAbsolutePosition(std::int64_t);
+ void BeginReadingRecord();
+
+private:
+ bool beganReading_{false};
};
template <Direction DIR, typename CHAR>