13b635714Speter klausler //===-- runtime/edit-output.h -----------------------------------*- C++ -*-===// 23b635714Speter klausler // 33b635714Speter klausler // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43b635714Speter klausler // See https://llvm.org/LICENSE.txt for license information. 53b635714Speter klausler // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63b635714Speter klausler // 73b635714Speter klausler //===----------------------------------------------------------------------===// 83b635714Speter klausler 93b635714Speter klausler #ifndef FORTRAN_RUNTIME_EDIT_OUTPUT_H_ 103b635714Speter klausler #define FORTRAN_RUNTIME_EDIT_OUTPUT_H_ 113b635714Speter klausler 123b635714Speter klausler // Output data editing templates implementing the FORMAT data editing 133b635714Speter klausler // descriptors E, EN, ES, EX, D, F, and G for REAL data (and COMPLEX 143b635714Speter klausler // components, I and G for INTEGER, and B/O/Z for both. 153b635714Speter klausler // See subclauses in 13.7.2.3 of Fortran 2018 for the 163b635714Speter klausler // detailed specifications of these descriptors. 173b635714Speter klausler // List-directed output (13.10.4) for numeric types is also done here. 183b635714Speter klausler // Drives the same fast binary-to-decimal formatting templates used 193b635714Speter klausler // in the f18 front-end. 203b635714Speter klausler 213b635714Speter klausler #include "format.h" 223b635714Speter klausler #include "io-stmt.h" 233b635714Speter klausler #include "flang/Common/uint128.h" 243b635714Speter klausler #include "flang/Decimal/decimal.h" 253b635714Speter klausler 263b635714Speter klausler namespace Fortran::runtime::io { 273b635714Speter klausler 283b635714Speter klausler // I, B, O, Z, and G output editing for INTEGER. 293b635714Speter klausler // The DataEdit reference is const here (and elsewhere in this header) so that 303b635714Speter klausler // one edit descriptor with a repeat factor may safely serve to edit 313b635714Speter klausler // multiple elements of an array. 32f65f830eSpeter klausler template <int KIND> 33*fc97d2e6SPeter Klausler RT_API_ATTRS bool EditIntegerOutput(IoStatementState &, const DataEdit &, 34*fc97d2e6SPeter Klausler common::HostSignedIntType<8 * KIND>, bool isSigned); 353b635714Speter klausler 363b635714Speter klausler // Encapsulates the state of a REAL output conversion. 373b635714Speter klausler class RealOutputEditingBase { 383b635714Speter klausler protected: 398ebf7411SSlava Zakharin explicit RT_API_ATTRS RealOutputEditingBase(IoStatementState &io) : io_{io} {} 403b635714Speter klausler 41db52dda8SPeter Klausler // Returns null when the exponent overflows a fixed-size output field. 428ebf7411SSlava Zakharin RT_API_ATTRS const char *FormatExponent( 438ebf7411SSlava Zakharin int, const DataEdit &edit, int &length); 448ebf7411SSlava Zakharin RT_API_ATTRS bool EmitPrefix( 458ebf7411SSlava Zakharin const DataEdit &, std::size_t length, std::size_t width); 468ebf7411SSlava Zakharin RT_API_ATTRS bool EmitSuffix(const DataEdit &); 473b635714Speter klausler 483b635714Speter klausler IoStatementState &io_; 493b635714Speter klausler int trailingBlanks_{0}; // created when Gw editing maps to Fw 503b635714Speter klausler char exponent_[16]; 513b635714Speter klausler }; 523b635714Speter klausler 53d56fdc8eSpeter klausler template <int KIND> class RealOutputEditing : public RealOutputEditingBase { 543b635714Speter klausler public: 558ebf7411SSlava Zakharin RT_VAR_GROUP_BEGIN 56d56fdc8eSpeter klausler static constexpr int binaryPrecision{common::PrecisionOfRealKind(KIND)}; 578ebf7411SSlava Zakharin RT_VAR_GROUP_END 58d56fdc8eSpeter klausler using BinaryFloatingPoint = 59d56fdc8eSpeter klausler decimal::BinaryFloatingPointNumber<binaryPrecision>; 603b635714Speter klausler template <typename A> 618ebf7411SSlava Zakharin RT_API_ATTRS RealOutputEditing(IoStatementState &io, A x) 623b635714Speter klausler : RealOutputEditingBase{io}, x_{x} {} 638ebf7411SSlava Zakharin RT_API_ATTRS bool Edit(const DataEdit &); 643b635714Speter klausler 653b635714Speter klausler private: 663b635714Speter klausler // The DataEdit arguments here are const references or copies so that 673b635714Speter klausler // the original DataEdit can safely serve multiple array elements when 683b635714Speter klausler // it has a repeat count. 698ebf7411SSlava Zakharin RT_API_ATTRS bool EditEorDOutput(const DataEdit &); 708ebf7411SSlava Zakharin RT_API_ATTRS bool EditFOutput(const DataEdit &); 718ebf7411SSlava Zakharin RT_API_ATTRS DataEdit EditForGOutput(DataEdit); // returns an E or F edit 728ebf7411SSlava Zakharin RT_API_ATTRS bool EditEXOutput(const DataEdit &); 738ebf7411SSlava Zakharin RT_API_ATTRS bool EditListDirectedOutput(const DataEdit &); 743b635714Speter klausler 758ebf7411SSlava Zakharin RT_API_ATTRS bool IsZero() const { return x_.IsZero(); } 763b635714Speter klausler 778ebf7411SSlava Zakharin RT_API_ATTRS decimal::ConversionToDecimalResult ConvertToDecimal( 78ea7e50cdSPeter Klausler int significantDigits, enum decimal::FortranRounding, int flags = 0); 79ea7e50cdSPeter Klausler 80ea7e50cdSPeter Klausler struct ConvertToHexadecimalResult { 81ea7e50cdSPeter Klausler const char *str; 82ea7e50cdSPeter Klausler int length; 83ea7e50cdSPeter Klausler int exponent; 84ea7e50cdSPeter Klausler }; 858ebf7411SSlava Zakharin RT_API_ATTRS ConvertToHexadecimalResult ConvertToHexadecimal( 86d1b09adeSPeter Klausler int significantDigits, enum decimal::FortranRounding, int flags = 0); 873b635714Speter klausler 883b635714Speter klausler BinaryFloatingPoint x_; 893b635714Speter klausler char buffer_[BinaryFloatingPoint::maxDecimalConversionDigits + 903b635714Speter klausler EXTRA_DECIMAL_CONVERSION_SPACE]; 913b635714Speter klausler }; 923b635714Speter klausler 938ebf7411SSlava Zakharin RT_API_ATTRS bool ListDirectedLogicalOutput( 943b635714Speter klausler IoStatementState &, ListDirectedStatementState<Direction::Output> &, bool); 958ebf7411SSlava Zakharin RT_API_ATTRS bool EditLogicalOutput(IoStatementState &, const DataEdit &, bool); 96bafbae23SPeter Klausler 97bafbae23SPeter Klausler template <typename CHAR> 988ebf7411SSlava Zakharin RT_API_ATTRS bool ListDirectedCharacterOutput(IoStatementState &, 99bafbae23SPeter Klausler ListDirectedStatementState<Direction::Output> &, const CHAR *, 100bafbae23SPeter Klausler std::size_t chars); 1018ebf7411SSlava Zakharin extern template RT_API_ATTRS bool ListDirectedCharacterOutput( 1028ebf7411SSlava Zakharin IoStatementState &, ListDirectedStatementState<Direction::Output> &, 1038ebf7411SSlava Zakharin const char *, std::size_t chars); 1048ebf7411SSlava Zakharin extern template RT_API_ATTRS bool ListDirectedCharacterOutput( 1058ebf7411SSlava Zakharin IoStatementState &, ListDirectedStatementState<Direction::Output> &, 1068ebf7411SSlava Zakharin const char16_t *, std::size_t chars); 1078ebf7411SSlava Zakharin extern template RT_API_ATTRS bool ListDirectedCharacterOutput( 1088ebf7411SSlava Zakharin IoStatementState &, ListDirectedStatementState<Direction::Output> &, 1098ebf7411SSlava Zakharin const char32_t *, std::size_t chars); 110bafbae23SPeter Klausler 111bafbae23SPeter Klausler template <typename CHAR> 1128ebf7411SSlava Zakharin RT_API_ATTRS bool EditCharacterOutput( 113bafbae23SPeter Klausler IoStatementState &, const DataEdit &, const CHAR *, std::size_t chars); 1148ebf7411SSlava Zakharin extern template RT_API_ATTRS bool EditCharacterOutput( 115bafbae23SPeter Klausler IoStatementState &, const DataEdit &, const char *, std::size_t chars); 1168ebf7411SSlava Zakharin extern template RT_API_ATTRS bool EditCharacterOutput( 117bafbae23SPeter Klausler IoStatementState &, const DataEdit &, const char16_t *, std::size_t chars); 1188ebf7411SSlava Zakharin extern template RT_API_ATTRS bool EditCharacterOutput( 119bafbae23SPeter Klausler IoStatementState &, const DataEdit &, const char32_t *, std::size_t chars); 1203b635714Speter klausler 1218ebf7411SSlava Zakharin extern template RT_API_ATTRS bool EditIntegerOutput<1>( 122*fc97d2e6SPeter Klausler IoStatementState &, const DataEdit &, std::int8_t, bool); 1238ebf7411SSlava Zakharin extern template RT_API_ATTRS bool EditIntegerOutput<2>( 124*fc97d2e6SPeter Klausler IoStatementState &, const DataEdit &, std::int16_t, bool); 1258ebf7411SSlava Zakharin extern template RT_API_ATTRS bool EditIntegerOutput<4>( 126*fc97d2e6SPeter Klausler IoStatementState &, const DataEdit &, std::int32_t, bool); 1278ebf7411SSlava Zakharin extern template RT_API_ATTRS bool EditIntegerOutput<8>( 128*fc97d2e6SPeter Klausler IoStatementState &, const DataEdit &, std::int64_t, bool); 1298ebf7411SSlava Zakharin extern template RT_API_ATTRS bool EditIntegerOutput<16>( 130*fc97d2e6SPeter Klausler IoStatementState &, const DataEdit &, common::int128_t, bool); 1313b635714Speter klausler 132d56fdc8eSpeter klausler extern template class RealOutputEditing<2>; 133d56fdc8eSpeter klausler extern template class RealOutputEditing<3>; 134d56fdc8eSpeter klausler extern template class RealOutputEditing<4>; 1353b635714Speter klausler extern template class RealOutputEditing<8>; 136d56fdc8eSpeter klausler extern template class RealOutputEditing<10>; 137d56fdc8eSpeter klausler // TODO: double/double 138d56fdc8eSpeter klausler extern template class RealOutputEditing<16>; 1393b635714Speter klausler 1401f879005STim Keith } // namespace Fortran::runtime::io 1413b635714Speter klausler #endif // FORTRAN_RUNTIME_EDIT_OUTPUT_H_ 142