1 //===-- runtime/internal-unit.h ---------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // Fortran internal I/O "units" 10 11 #ifndef FORTRAN_RUNTIME_IO_INTERNAL_UNIT_H_ 12 #define FORTRAN_RUNTIME_IO_INTERNAL_UNIT_H_ 13 14 #include "connection.h" 15 #include "descriptor.h" 16 #include <cinttypes> 17 #include <type_traits> 18 19 namespace Fortran::runtime::io { 20 21 class IoErrorHandler; 22 23 // Points to (but does not own) a CHARACTER scalar or array for internal I/O. 24 // Does not buffer. 25 template <Direction DIR> class InternalDescriptorUnit : public ConnectionState { 26 public: 27 using Scalar = 28 std::conditional_t<DIR == Direction::Input, const char *, char *>; 29 InternalDescriptorUnit(Scalar, std::size_t); 30 InternalDescriptorUnit(const Descriptor &, const Terminator &); 31 void EndIoStatement(); 32 33 bool Emit(const char *, std::size_t, IoErrorHandler &); 34 std::optional<char32_t> GetCurrentChar(IoErrorHandler &); 35 bool AdvanceRecord(IoErrorHandler &); 36 void BackspaceRecord(IoErrorHandler &); 37 38 private: descriptor()39 Descriptor &descriptor() { return staticDescriptor_.descriptor(); } descriptor()40 const Descriptor &descriptor() const { 41 return staticDescriptor_.descriptor(); 42 } CurrentRecord()43 Scalar CurrentRecord() const { 44 return descriptor().template ZeroBasedIndexedElement<char>( 45 currentRecordNumber - 1); 46 } 47 StaticDescriptor<maxRank, true /*addendum*/> staticDescriptor_; 48 }; 49 50 extern template class InternalDescriptorUnit<Direction::Output>; 51 extern template class InternalDescriptorUnit<Direction::Input>; 52 } // namespace Fortran::runtime::io 53 #endif // FORTRAN_RUNTIME_IO_INTERNAL_UNIT_H_ 54