xref: /llvm-project/flang/runtime/edit-output.h (revision fc97d2e68b03bc2979395e84b645e5b3ba35aecd)
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