1//===-- lib/runtime/edit-output.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#ifndef FLANG_RT_RUNTIME_EDIT_OUTPUT_H_
10#define FLANG_RT_RUNTIME_EDIT_OUTPUT_H_
11
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.
20
21#include "flang-rt/runtime/format.h"
22#include "flang-rt/runtime/io-stmt.h"
23#include "flang/Common/uint128.h"
24#include "flang/Decimal/decimal.h"
25
26namespace Fortran::runtime::io {
27
28RT_OFFLOAD_API_GROUP_BEGIN
29
30// I, B, O, Z, and G output editing for INTEGER.
31// The DataEdit reference is const here (and elsewhere in this header) so that
32// one edit descriptor with a repeat factor may safely serve to edit
33// multiple elements of an array.
34template <int KIND>
35RT_API_ATTRS bool EditIntegerOutput(IoStatementState &, const DataEdit &,
36 common::HostSignedIntType<8 * KIND>, bool isSigned);
37
38// Encapsulates the state of a REAL output conversion.
39class RealOutputEditingBase {
40protected:
41 explicit RT_API_ATTRS RealOutputEditingBase(IoStatementState &io) : io_{io} {}
42
43 // Returns null when the exponent overflows a fixed-size output field.
44 RT_API_ATTRS const char *FormatExponent(
45 int, const DataEdit &edit, int &length);
46 RT_API_ATTRS bool EmitPrefix(
47 const DataEdit &, std::size_t length, std::size_t width);
48 RT_API_ATTRS bool EmitSuffix(const DataEdit &);
49
50 IoStatementState &io_;
51 int trailingBlanks_{0}; // created when Gw editing maps to Fw
52 char exponent_[16];
53};
54
55template <int KIND> class RealOutputEditing : public RealOutputEditingBase {
56public:
57 RT_VAR_GROUP_BEGIN
58 static constexpr int binaryPrecision{common::PrecisionOfRealKind(KIND)};
59 RT_VAR_GROUP_END
60 using BinaryFloatingPoint =
61 decimal::BinaryFloatingPointNumber<binaryPrecision>;
62 template <typename A>
63 RT_API_ATTRS RealOutputEditing(IoStatementState &io, A x)
64 : RealOutputEditingBase{io}, x_{x} {}
65 RT_API_ATTRS bool Edit(const DataEdit &);
66
67private:
68 // The DataEdit arguments here are const references or copies so that
69 // the original DataEdit can safely serve multiple array elements when
70 // it has a repeat count.
71 RT_API_ATTRS bool EditEorDOutput(const DataEdit &);
72 RT_API_ATTRS bool EditFOutput(const DataEdit &);
73 RT_API_ATTRS DataEdit EditForGOutput(DataEdit); // returns an E or F edit
74 RT_API_ATTRS bool EditEXOutput(const DataEdit &);
75 RT_API_ATTRS bool EditListDirectedOutput(const DataEdit &);
76
77 RT_API_ATTRS bool IsZero() const { return x_.IsZero(); }
78
79 RT_API_ATTRS decimal::ConversionToDecimalResult ConvertToDecimal(
80 int significantDigits, enum decimal::FortranRounding, int flags = 0);
81
82 struct ConvertToHexadecimalResult {
83 const char *str;
84 int length;
85 int exponent;
86 };
87 RT_API_ATTRS ConvertToHexadecimalResult ConvertToHexadecimal(
88 int significantDigits, enum decimal::FortranRounding, int flags = 0);
89
90 BinaryFloatingPoint x_;
91 char buffer_[BinaryFloatingPoint::maxDecimalConversionDigits +
92 EXTRA_DECIMAL_CONVERSION_SPACE];
93};
94
95RT_API_ATTRS bool ListDirectedLogicalOutput(
96 IoStatementState &, ListDirectedStatementState<Direction::Output> &, bool);
97RT_API_ATTRS bool EditLogicalOutput(IoStatementState &, const DataEdit &, bool);
98
99template <typename CHAR>
100RT_API_ATTRS bool ListDirectedCharacterOutput(IoStatementState &,
101 ListDirectedStatementState<Direction::Output> &, const CHAR *,
102 std::size_t chars);
103extern template RT_API_ATTRS bool ListDirectedCharacterOutput(
104 IoStatementState &, ListDirectedStatementState<Direction::Output> &,
105 const char *, std::size_t chars);
106extern template RT_API_ATTRS bool ListDirectedCharacterOutput(
107 IoStatementState &, ListDirectedStatementState<Direction::Output> &,
108 const char16_t *, std::size_t chars);
109extern template RT_API_ATTRS bool ListDirectedCharacterOutput(
110 IoStatementState &, ListDirectedStatementState<Direction::Output> &,
111 const char32_t *, std::size_t chars);
112
113template <typename CHAR>
114RT_API_ATTRS bool EditCharacterOutput(
115 IoStatementState &, const DataEdit &, const CHAR *, std::size_t chars);
116extern template RT_API_ATTRS bool EditCharacterOutput(
117 IoStatementState &, const DataEdit &, const char *, std::size_t chars);
118extern template RT_API_ATTRS bool EditCharacterOutput(
119 IoStatementState &, const DataEdit &, const char16_t *, std::size_t chars);
120extern template RT_API_ATTRS bool EditCharacterOutput(
121 IoStatementState &, const DataEdit &, const char32_t *, std::size_t chars);
122
123extern template RT_API_ATTRS bool EditIntegerOutput<1>(
124 IoStatementState &, const DataEdit &, std::int8_t, bool);
125extern template RT_API_ATTRS bool EditIntegerOutput<2>(
126 IoStatementState &, const DataEdit &, std::int16_t, bool);
127extern template RT_API_ATTRS bool EditIntegerOutput<4>(
128 IoStatementState &, const DataEdit &, std::int32_t, bool);
129extern template RT_API_ATTRS bool EditIntegerOutput<8>(
130 IoStatementState &, const DataEdit &, std::int64_t, bool);
131extern template RT_API_ATTRS bool EditIntegerOutput<16>(
132 IoStatementState &, const DataEdit &, common::int128_t, bool);
133
134extern template class RealOutputEditing<2>;
135extern template class RealOutputEditing<3>;
136extern template class RealOutputEditing<4>;
137extern template class RealOutputEditing<8>;
138extern template class RealOutputEditing<10>;
139// TODO: double/double
140extern template class RealOutputEditing<16>;
141
142RT_OFFLOAD_API_GROUP_END
143
144} // namespace Fortran::runtime::io
145#endif // FLANG_RT_RUNTIME_EDIT_OUTPUT_H_
146

source code of flang-rt/lib/runtime/edit-output.h