1 //===-- runtime/edit-output.h -----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef FORTRAN_RUNTIME_EDIT_OUTPUT_H_
10 #define FORTRAN_RUNTIME_EDIT_OUTPUT_H_
12 // Output data editing templates implementing the FORMAT data editing
13 // descriptors E, EN, ES, EX, D, F, and G for REAL data (and COMPLEX
14 // components, I and G for INTEGER, and B/O/Z for both.
15 // See subclauses in 13.7.2.3 of Fortran 2018 for the
16 // detailed specifications of these descriptors.
17 // List-directed output (13.10.4) for numeric types is also done here.
18 // Drives the same fast binary-to-decimal formatting templates used
19 // in the f18 front-end.
23 #include "flang/Common/uint128.h"
24 #include "flang/Decimal/decimal.h"
26 namespace Fortran::runtime::io
{
28 // I, B, O, Z, and G output editing for INTEGER.
29 // The DataEdit reference is const here (and elsewhere in this header) so that
30 // one edit descriptor with a repeat factor may safely serve to edit
31 // multiple elements of an array.
33 RT_API_ATTRS
bool EditIntegerOutput(
34 IoStatementState
&, const DataEdit
&, common::HostSignedIntType
<8 * KIND
>);
36 // Encapsulates the state of a REAL output conversion.
37 class RealOutputEditingBase
{
39 explicit RT_API_ATTRS
RealOutputEditingBase(IoStatementState
&io
) : io_
{io
} {}
41 // Returns null when the exponent overflows a fixed-size output field.
42 RT_API_ATTRS
const char *FormatExponent(
43 int, const DataEdit
&edit
, int &length
);
44 RT_API_ATTRS
bool EmitPrefix(
45 const DataEdit
&, std::size_t length
, std::size_t width
);
46 RT_API_ATTRS
bool EmitSuffix(const DataEdit
&);
48 IoStatementState
&io_
;
49 int trailingBlanks_
{0}; // created when Gw editing maps to Fw
53 template <int KIND
> class RealOutputEditing
: public RealOutputEditingBase
{
56 static constexpr int binaryPrecision
{common::PrecisionOfRealKind(KIND
)};
58 using BinaryFloatingPoint
=
59 decimal::BinaryFloatingPointNumber
<binaryPrecision
>;
61 RT_API_ATTRS
RealOutputEditing(IoStatementState
&io
, A x
)
62 : RealOutputEditingBase
{io
}, x_
{x
} {}
63 RT_API_ATTRS
bool Edit(const DataEdit
&);
66 // The DataEdit arguments here are const references or copies so that
67 // the original DataEdit can safely serve multiple array elements when
68 // it has a repeat count.
69 RT_API_ATTRS
bool EditEorDOutput(const DataEdit
&);
70 RT_API_ATTRS
bool EditFOutput(const DataEdit
&);
71 RT_API_ATTRS DataEdit
EditForGOutput(DataEdit
); // returns an E or F edit
72 RT_API_ATTRS
bool EditEXOutput(const DataEdit
&);
73 RT_API_ATTRS
bool EditListDirectedOutput(const DataEdit
&);
75 RT_API_ATTRS
bool IsZero() const { return x_
.IsZero(); }
77 RT_API_ATTRS
decimal::ConversionToDecimalResult
ConvertToDecimal(
78 int significantDigits
, enum decimal::FortranRounding
, int flags
= 0);
80 struct ConvertToHexadecimalResult
{
85 RT_API_ATTRS ConvertToHexadecimalResult
ConvertToHexadecimal(
86 int significantDigits
, enum decimal::FortranRounding
, int flags
= 0);
88 BinaryFloatingPoint x_
;
89 char buffer_
[BinaryFloatingPoint::maxDecimalConversionDigits
+
90 EXTRA_DECIMAL_CONVERSION_SPACE
];
93 RT_API_ATTRS
bool ListDirectedLogicalOutput(
94 IoStatementState
&, ListDirectedStatementState
<Direction::Output
> &, bool);
95 RT_API_ATTRS
bool EditLogicalOutput(IoStatementState
&, const DataEdit
&, bool);
97 template <typename CHAR
>
98 RT_API_ATTRS
bool ListDirectedCharacterOutput(IoStatementState
&,
99 ListDirectedStatementState
<Direction::Output
> &, const CHAR
*,
101 extern template RT_API_ATTRS
bool ListDirectedCharacterOutput(
102 IoStatementState
&, ListDirectedStatementState
<Direction::Output
> &,
103 const char *, std::size_t chars
);
104 extern template RT_API_ATTRS
bool ListDirectedCharacterOutput(
105 IoStatementState
&, ListDirectedStatementState
<Direction::Output
> &,
106 const char16_t
*, std::size_t chars
);
107 extern template RT_API_ATTRS
bool ListDirectedCharacterOutput(
108 IoStatementState
&, ListDirectedStatementState
<Direction::Output
> &,
109 const char32_t
*, std::size_t chars
);
111 template <typename CHAR
>
112 RT_API_ATTRS
bool EditCharacterOutput(
113 IoStatementState
&, const DataEdit
&, const CHAR
*, std::size_t chars
);
114 extern template RT_API_ATTRS
bool EditCharacterOutput(
115 IoStatementState
&, const DataEdit
&, const char *, std::size_t chars
);
116 extern template RT_API_ATTRS
bool EditCharacterOutput(
117 IoStatementState
&, const DataEdit
&, const char16_t
*, std::size_t chars
);
118 extern template RT_API_ATTRS
bool EditCharacterOutput(
119 IoStatementState
&, const DataEdit
&, const char32_t
*, std::size_t chars
);
121 extern template RT_API_ATTRS
bool EditIntegerOutput
<1>(
122 IoStatementState
&, const DataEdit
&, std::int8_t);
123 extern template RT_API_ATTRS
bool EditIntegerOutput
<2>(
124 IoStatementState
&, const DataEdit
&, std::int16_t);
125 extern template RT_API_ATTRS
bool EditIntegerOutput
<4>(
126 IoStatementState
&, const DataEdit
&, std::int32_t);
127 extern template RT_API_ATTRS
bool EditIntegerOutput
<8>(
128 IoStatementState
&, const DataEdit
&, std::int64_t);
129 extern template RT_API_ATTRS
bool EditIntegerOutput
<16>(
130 IoStatementState
&, const DataEdit
&, common::int128_t
);
132 extern template class RealOutputEditing
<2>;
133 extern template class RealOutputEditing
<3>;
134 extern template class RealOutputEditing
<4>;
135 extern template class RealOutputEditing
<8>;
136 extern template class RealOutputEditing
<10>;
137 // TODO: double/double
138 extern template class RealOutputEditing
<16>;
140 } // namespace Fortran::runtime::io
141 #endif // FORTRAN_RUNTIME_EDIT_OUTPUT_H_