146 lines · c
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-exception6//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 editing13// descriptors E, EN, ES, EX, D, F, and G for REAL data (and COMPLEX14// components, I and G for INTEGER, and B/O/Z for both.15// See subclauses in 13.7.2.3 of Fortran 2018 for the16// 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 used19// 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_BEGIN29 30// I, B, O, Z, and G output editing for INTEGER.31// The DataEdit reference is const here (and elsewhere in this header) so that32// one edit descriptor with a repeat factor may safely serve to edit33// 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 Fw52 char exponent_[16];53};54 55template <int KIND> class RealOutputEditing : public RealOutputEditingBase {56public:57 RT_VAR_GROUP_BEGIN58 static constexpr int binaryPrecision{common::PrecisionOfRealKind(KIND)};59 RT_VAR_GROUP_END60 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 that69 // the original DataEdit can safely serve multiple array elements when70 // 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 edit74 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/double140extern template class RealOutputEditing<16>;141 142RT_OFFLOAD_API_GROUP_END143 144} // namespace Fortran::runtime::io145#endif // FLANG_RT_RUNTIME_EDIT_OUTPUT_H_146