mirror of
https://github.com/intel/llvm.git
synced 2026-01-17 06:40:01 +08:00
[flang][runtime] Added Fortran::common::optional for use on device.
This is a simplified implementation of std::optional that can be used in the offload builds for the device code. The methods are properly marked with RT_API_ATTRS so that the device compilation succedes. Reviewers: klausler, jeanPerier Reviewed By: jeanPerier Pull Request: https://github.com/llvm/llvm-project/pull/85177
This commit is contained in:
243
flang/include/flang/Common/optional.h
Normal file
243
flang/include/flang/Common/optional.h
Normal file
@@ -0,0 +1,243 @@
|
||||
//===-- include/flang/Common/optional.h -------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implementation of std::optional borrowed from LLVM's
|
||||
// libc/src/__support/CPP/optional.h with modifications (e.g. value_or, emplace
|
||||
// methods were added).
|
||||
//
|
||||
// The implementation defines optional in Fortran::common namespace.
|
||||
// This standalone implementation may be used if the target
|
||||
// does not support std::optional implementation (e.g. CUDA device env),
|
||||
// otherwise, Fortran::common::optional is an alias for std::optional.
|
||||
//
|
||||
// TODO: using libcu++ is the best option for CUDA, but there is a couple
|
||||
// of issues:
|
||||
// * Older CUDA toolkits' libcu++ implementations do not support optional.
|
||||
// * The include paths need to be set up such that all STD header files
|
||||
// are taken from libcu++.
|
||||
// * cuda:: namespace need to be forced for all std:: references.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef FORTRAN_COMMON_OPTIONAL_H
|
||||
#define FORTRAN_COMMON_OPTIONAL_H
|
||||
|
||||
#include "flang/Runtime/api-attrs.h"
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(STD_OPTIONAL_UNSUPPORTED) && \
|
||||
(defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
|
||||
#define STD_OPTIONAL_UNSUPPORTED 1
|
||||
#endif
|
||||
|
||||
#define FORTRAN_OPTIONAL_INLINE_WITH_ATTRS inline RT_API_ATTRS
|
||||
#define FORTRAN_OPTIONAL_INLINE inline
|
||||
#define FORTRAN_OPTIONAL_INLINE_VAR inline
|
||||
|
||||
namespace Fortran::common {
|
||||
|
||||
#if STD_OPTIONAL_UNSUPPORTED
|
||||
// Trivial nullopt_t struct.
|
||||
struct nullopt_t {
|
||||
constexpr explicit nullopt_t() = default;
|
||||
};
|
||||
|
||||
// nullopt that can be used and returned.
|
||||
FORTRAN_OPTIONAL_INLINE_VAR constexpr nullopt_t nullopt{};
|
||||
|
||||
// This is very simple implementation of the std::optional class. It makes
|
||||
// several assumptions that the underlying type is trivially constructible,
|
||||
// copyable, or movable.
|
||||
template <typename T> class optional {
|
||||
template <typename U, bool = !std::is_trivially_destructible<U>::value>
|
||||
struct OptionalStorage {
|
||||
union {
|
||||
char empty;
|
||||
U stored_value;
|
||||
};
|
||||
|
||||
bool in_use = false;
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS ~OptionalStorage() { reset(); }
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr OptionalStorage() : empty() {}
|
||||
|
||||
template <typename... Args>
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr explicit OptionalStorage(
|
||||
std::in_place_t, Args &&...args)
|
||||
: stored_value(std::forward<Args>(args)...) {}
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr void reset() {
|
||||
if (in_use)
|
||||
stored_value.~U();
|
||||
in_use = false;
|
||||
}
|
||||
};
|
||||
|
||||
// The only difference is that this type U doesn't have a nontrivial
|
||||
// destructor.
|
||||
template <typename U> struct OptionalStorage<U, false> {
|
||||
union {
|
||||
char empty;
|
||||
U stored_value;
|
||||
};
|
||||
|
||||
bool in_use = false;
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr OptionalStorage() : empty() {}
|
||||
|
||||
template <typename... Args>
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr explicit OptionalStorage(
|
||||
std::in_place_t, Args &&...args)
|
||||
: stored_value(std::forward<Args>(args)...) {}
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr void reset() {
|
||||
in_use = false;
|
||||
}
|
||||
};
|
||||
|
||||
OptionalStorage<T> storage;
|
||||
|
||||
public:
|
||||
// The default methods do not use RT_API_ATTRS, which causes
|
||||
// warnings in CUDA compilation of form:
|
||||
// __device__/__host__ annotation is ignored on a function .* that is
|
||||
// explicitly defaulted on its first declaration
|
||||
FORTRAN_OPTIONAL_INLINE constexpr optional() = default;
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr optional(nullopt_t) {}
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr optional(const T &t)
|
||||
: storage(std::in_place, t) {
|
||||
storage.in_use = true;
|
||||
}
|
||||
FORTRAN_OPTIONAL_INLINE constexpr optional(const optional &) = default;
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr optional(T &&t)
|
||||
: storage(std::in_place, std::move(t)) {
|
||||
storage.in_use = true;
|
||||
}
|
||||
FORTRAN_OPTIONAL_INLINE constexpr optional(optional &&O) = default;
|
||||
|
||||
template <typename... ArgTypes>
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr optional(
|
||||
std::in_place_t, ArgTypes &&...Args)
|
||||
: storage(std::in_place, std::forward<ArgTypes>(Args)...) {
|
||||
storage.in_use = true;
|
||||
}
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr optional &operator=(T &&t) {
|
||||
storage.stored_value = std::move(t);
|
||||
storage.in_use = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE constexpr optional &operator=(optional &&) = default;
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr optional &operator=(const T &t) {
|
||||
storage.stored_value = t;
|
||||
storage.in_use = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE constexpr optional &operator=(
|
||||
const optional &) = default;
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr void reset() { storage.reset(); }
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr const T &value() const & {
|
||||
return storage.stored_value;
|
||||
}
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr T &value() & {
|
||||
return storage.stored_value;
|
||||
}
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr explicit operator bool() const {
|
||||
return storage.in_use;
|
||||
}
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr bool has_value() const {
|
||||
return storage.in_use;
|
||||
}
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr const T *operator->() const {
|
||||
return &storage.stored_value;
|
||||
}
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr T *operator->() {
|
||||
return &storage.stored_value;
|
||||
}
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr const T &operator*() const & {
|
||||
return storage.stored_value;
|
||||
}
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr T &operator*() & {
|
||||
return storage.stored_value;
|
||||
}
|
||||
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr T &&value() && {
|
||||
return std::move(storage.stored_value);
|
||||
}
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr T &&operator*() && {
|
||||
return std::move(storage.stored_value);
|
||||
}
|
||||
|
||||
template <typename VT>
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr T value_or(
|
||||
VT &&default_value) const & {
|
||||
return storage.in_use ? storage.stored_value
|
||||
: static_cast<T>(std::forward<VT>(default_value));
|
||||
}
|
||||
|
||||
template <typename VT>
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr T value_or(
|
||||
VT &&default_value) && {
|
||||
return storage.in_use ? std::move(storage.stored_value)
|
||||
: static_cast<T>(std::forward<VT>(default_value));
|
||||
}
|
||||
|
||||
template <typename... ArgTypes>
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
|
||||
std::enable_if_t<std::is_constructible_v<T, ArgTypes &&...>, T &>
|
||||
emplace(ArgTypes &&...args) {
|
||||
reset();
|
||||
new (reinterpret_cast<void *>(std::addressof(storage.stored_value)))
|
||||
T(std::forward<ArgTypes>(args)...);
|
||||
storage.in_use = true;
|
||||
return value();
|
||||
}
|
||||
|
||||
template <typename U = T,
|
||||
std::enable_if_t<(std::is_constructible_v<T, U &&> &&
|
||||
!std::is_same_v<std::decay_t<U>, std::in_place_t> &&
|
||||
!std::is_same_v<std::decay_t<U>, optional> &&
|
||||
std::is_convertible_v<U &&, T>),
|
||||
bool> = true>
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS constexpr optional(U &&value) {
|
||||
new (reinterpret_cast<void *>(std::addressof(storage.stored_value)))
|
||||
T(std::forward<U>(value));
|
||||
storage.in_use = true;
|
||||
}
|
||||
|
||||
template <typename U = T,
|
||||
std::enable_if_t<(std::is_constructible_v<T, U &&> &&
|
||||
!std::is_same_v<std::decay_t<U>, std::in_place_t> &&
|
||||
!std::is_same_v<std::decay_t<U>, optional> &&
|
||||
!std::is_convertible_v<U &&, T>),
|
||||
bool> = false>
|
||||
FORTRAN_OPTIONAL_INLINE_WITH_ATTRS explicit constexpr optional(U &&value) {
|
||||
new (reinterpret_cast<void *>(std::addressof(storage.stored_value)))
|
||||
T(std::forward<U>(value));
|
||||
storage.in_use = true;
|
||||
}
|
||||
};
|
||||
#else // !STD_OPTIONAL_UNSUPPORTED
|
||||
using std::nullopt;
|
||||
using std::nullopt_t;
|
||||
using std::optional;
|
||||
#endif // !STD_OPTIONAL_UNSUPPORTED
|
||||
|
||||
} // namespace Fortran::common
|
||||
|
||||
#endif // FORTRAN_COMMON_OPTIONAL_H
|
||||
@@ -10,6 +10,7 @@
|
||||
#define FORTRAN_RUNTIME_TYPE_CODE_H_
|
||||
|
||||
#include "flang/Common/Fortran.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/ISO_Fortran_binding_wrapper.h"
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
@@ -54,7 +55,7 @@ public:
|
||||
return IsValid() && !IsDerived();
|
||||
}
|
||||
|
||||
RT_API_ATTRS std::optional<std::pair<TypeCategory, int>>
|
||||
RT_API_ATTRS Fortran::common::optional<std::pair<TypeCategory, int>>
|
||||
GetCategoryAndKind() const;
|
||||
|
||||
RT_API_ATTRS bool operator==(TypeCode that) const {
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#define FORTRAN_RUNTIME_IO_CONNECTION_H_
|
||||
|
||||
#include "format.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include <cinttypes>
|
||||
#include <optional>
|
||||
|
||||
namespace Fortran::runtime::io {
|
||||
|
||||
@@ -26,10 +26,10 @@ enum class Access { Sequential, Direct, Stream };
|
||||
// established in an OPEN statement.
|
||||
struct ConnectionAttributes {
|
||||
Access access{Access::Sequential}; // ACCESS='SEQUENTIAL', 'DIRECT', 'STREAM'
|
||||
std::optional<bool> isUnformatted; // FORM='UNFORMATTED' if true
|
||||
Fortran::common::optional<bool> isUnformatted; // FORM='UNFORMATTED' if true
|
||||
bool isUTF8{false}; // ENCODING='UTF-8'
|
||||
unsigned char internalIoCharKind{0}; // 0->external, 1/2/4->internal
|
||||
std::optional<std::int64_t> openRecl; // RECL= on OPEN
|
||||
Fortran::common::optional<std::int64_t> openRecl; // RECL= on OPEN
|
||||
|
||||
bool IsRecordFile() const {
|
||||
// Formatted stream files are viewed as having records, at least on input
|
||||
@@ -63,14 +63,14 @@ struct ConnectionState : public ConnectionAttributes {
|
||||
unterminatedRecord = false;
|
||||
}
|
||||
|
||||
std::optional<std::int64_t> EffectiveRecordLength() const {
|
||||
Fortran::common::optional<std::int64_t> EffectiveRecordLength() const {
|
||||
// When an input record is longer than an explicit RECL= from OPEN
|
||||
// it is effectively truncated on input.
|
||||
return openRecl && recordLength && *openRecl < *recordLength ? openRecl
|
||||
: recordLength;
|
||||
}
|
||||
|
||||
std::optional<std::int64_t> recordLength;
|
||||
Fortran::common::optional<std::int64_t> recordLength;
|
||||
|
||||
std::int64_t currentRecordNumber{1}; // 1 is first
|
||||
|
||||
@@ -86,11 +86,12 @@ struct ConnectionState : public ConnectionAttributes {
|
||||
std::int64_t furthestPositionInRecord{0}; // max(position+bytes)
|
||||
|
||||
// Set at end of non-advancing I/O data transfer
|
||||
std::optional<std::int64_t> leftTabLimit; // offset in current record
|
||||
Fortran::common::optional<std::int64_t>
|
||||
leftTabLimit; // offset in current record
|
||||
|
||||
// currentRecordNumber value captured after ENDFILE/REWIND/BACKSPACE statement
|
||||
// or an end-of-file READ condition on a sequential access file
|
||||
std::optional<std::int64_t> endfileRecordNumber;
|
||||
Fortran::common::optional<std::int64_t> endfileRecordNumber;
|
||||
|
||||
// Mutable modes set at OPEN() that can be overridden in READ/WRITE & FORMAT
|
||||
MutableModes modes; // BLANK=, DECIMAL=, SIGN=, ROUND=, PAD=, DELIM=, kP
|
||||
|
||||
@@ -12,11 +12,12 @@
|
||||
namespace Fortran::runtime::io::descr {
|
||||
|
||||
// Defined formatted I/O (maybe)
|
||||
std::optional<bool> DefinedFormattedIo(IoStatementState &io,
|
||||
Fortran::common::optional<bool> DefinedFormattedIo(IoStatementState &io,
|
||||
const Descriptor &descriptor, const typeInfo::DerivedType &derived,
|
||||
const typeInfo::SpecialBinding &special,
|
||||
const SubscriptValue subscripts[]) {
|
||||
std::optional<DataEdit> peek{io.GetNextDataEdit(0 /*to peek at it*/)};
|
||||
Fortran::common::optional<DataEdit> peek{
|
||||
io.GetNextDataEdit(0 /*to peek at it*/)};
|
||||
if (peek &&
|
||||
(peek->descriptor == DataEdit::DefinedDerivedType ||
|
||||
peek->descriptor == DataEdit::ListDirected)) {
|
||||
@@ -55,7 +56,7 @@ std::optional<bool> DefinedFormattedIo(IoStatementState &io,
|
||||
int unit{external->unitNumber()};
|
||||
int ioStat{IostatOk};
|
||||
char ioMsg[100];
|
||||
std::optional<std::int64_t> startPos;
|
||||
Fortran::common::optional<std::int64_t> startPos;
|
||||
if (edit.descriptor == DataEdit::DefinedDerivedType &&
|
||||
special.which() == typeInfo::SpecialBinding::Which::ReadFormatted) {
|
||||
// DT is an edit descriptor so everything that the child
|
||||
@@ -96,7 +97,7 @@ std::optional<bool> DefinedFormattedIo(IoStatementState &io,
|
||||
// There's a defined I/O subroutine, but there's a FORMAT present and
|
||||
// it does not have a DT data edit descriptor, so apply default formatting
|
||||
// to the components of the derived type as usual.
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "terminator.h"
|
||||
#include "type-info.h"
|
||||
#include "unit.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Common/uint128.h"
|
||||
#include "flang/Runtime/cpp-type.h"
|
||||
#include "flang/Runtime/descriptor.h"
|
||||
@@ -321,9 +322,9 @@ static bool DefaultComponentwiseUnformattedIO(IoStatementState &io,
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> DefinedFormattedIo(IoStatementState &, const Descriptor &,
|
||||
const typeInfo::DerivedType &, const typeInfo::SpecialBinding &,
|
||||
const SubscriptValue[]);
|
||||
Fortran::common::optional<bool> DefinedFormattedIo(IoStatementState &,
|
||||
const Descriptor &, const typeInfo::DerivedType &,
|
||||
const typeInfo::SpecialBinding &, const SubscriptValue[]);
|
||||
|
||||
template <Direction DIR>
|
||||
static bool FormattedDerivedTypeIO(IoStatementState &io,
|
||||
@@ -334,7 +335,7 @@ static bool FormattedDerivedTypeIO(IoStatementState &io,
|
||||
RUNTIME_CHECK(handler, addendum != nullptr);
|
||||
const typeInfo::DerivedType *type{addendum->derivedType()};
|
||||
RUNTIME_CHECK(handler, type != nullptr);
|
||||
std::optional<typeInfo::SpecialBinding> nonTbpSpecial;
|
||||
Fortran::common::optional<typeInfo::SpecialBinding> nonTbpSpecial;
|
||||
const typeInfo::SpecialBinding *special{nullptr};
|
||||
if (table) {
|
||||
if (const auto *definedIo{table->Find(*type,
|
||||
@@ -365,7 +366,7 @@ static bool FormattedDerivedTypeIO(IoStatementState &io,
|
||||
std::size_t numElements{descriptor.Elements()};
|
||||
for (std::size_t j{0}; j < numElements;
|
||||
++j, descriptor.IncrementSubscripts(subscripts)) {
|
||||
std::optional<bool> result;
|
||||
Fortran::common::optional<bool> result;
|
||||
if (special) {
|
||||
result = DefinedFormattedIo(io, descriptor, *type, *special, subscripts);
|
||||
}
|
||||
@@ -406,7 +407,7 @@ static bool UnformattedDescriptorIO(IoStatementState &io,
|
||||
: typeInfo::SpecialBinding::Which::WriteUnformatted,
|
||||
definedIo->subroutine, definedIo->isDtvArgPolymorphic, false,
|
||||
false};
|
||||
if (std::optional<bool> wasDefined{
|
||||
if (Fortran::common::optional<bool> wasDefined{
|
||||
DefinedUnformattedIo(io, descriptor, *type, special)}) {
|
||||
return *wasDefined;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "edit-input.h"
|
||||
#include "namelist.h"
|
||||
#include "utf.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Common/real.h"
|
||||
#include "flang/Common/uint128.h"
|
||||
#include <algorithm>
|
||||
@@ -54,9 +55,9 @@ template <int LOG2_BASE>
|
||||
static bool EditBOZInput(
|
||||
IoStatementState &io, const DataEdit &edit, void *n, std::size_t bytes) {
|
||||
// Skip leading white space & zeroes
|
||||
std::optional<int> remaining{io.CueUpInput(edit)};
|
||||
Fortran::common::optional<int> remaining{io.CueUpInput(edit)};
|
||||
auto start{io.GetConnectionState().positionInRecord};
|
||||
std::optional<char32_t> next{io.NextInField(remaining, edit)};
|
||||
Fortran::common::optional<char32_t> next{io.NextInField(remaining, edit)};
|
||||
if (next.value_or('?') == '0') {
|
||||
do {
|
||||
start = io.GetConnectionState().positionInRecord;
|
||||
@@ -156,7 +157,8 @@ static inline char32_t GetRadixPointChar(const DataEdit &edit) {
|
||||
|
||||
// Prepares input from a field, and returns the sign, if any, else '\0'.
|
||||
static char ScanNumericPrefix(IoStatementState &io, const DataEdit &edit,
|
||||
std::optional<char32_t> &next, std::optional<int> &remaining) {
|
||||
Fortran::common::optional<char32_t> &next,
|
||||
Fortran::common::optional<int> &remaining) {
|
||||
remaining = io.CueUpInput(edit);
|
||||
next = io.NextInField(remaining, edit);
|
||||
char sign{'\0'};
|
||||
@@ -198,8 +200,8 @@ bool EditIntegerInput(
|
||||
edit.descriptor);
|
||||
return false;
|
||||
}
|
||||
std::optional<int> remaining;
|
||||
std::optional<char32_t> next;
|
||||
Fortran::common::optional<int> remaining;
|
||||
Fortran::common::optional<char32_t> next;
|
||||
char sign{ScanNumericPrefix(io, edit, next, remaining)};
|
||||
common::UnsignedInt128 value{0};
|
||||
bool any{!!sign};
|
||||
@@ -279,10 +281,10 @@ struct ScannedRealInput {
|
||||
};
|
||||
static ScannedRealInput ScanRealInput(
|
||||
char *buffer, int bufferSize, IoStatementState &io, const DataEdit &edit) {
|
||||
std::optional<int> remaining;
|
||||
std::optional<char32_t> next;
|
||||
Fortran::common::optional<int> remaining;
|
||||
Fortran::common::optional<char32_t> next;
|
||||
int got{0};
|
||||
std::optional<int> radixPointOffset;
|
||||
Fortran::common::optional<int> radixPointOffset;
|
||||
auto Put{[&](char ch) -> void {
|
||||
if (got < bufferSize) {
|
||||
buffer[got] = ch;
|
||||
@@ -833,8 +835,8 @@ bool EditLogicalInput(IoStatementState &io, const DataEdit &edit, bool &x) {
|
||||
edit.descriptor);
|
||||
return false;
|
||||
}
|
||||
std::optional<int> remaining{io.CueUpInput(edit)};
|
||||
std::optional<char32_t> next{io.NextInField(remaining, edit)};
|
||||
Fortran::common::optional<int> remaining{io.CueUpInput(edit)};
|
||||
Fortran::common::optional<char32_t> next{io.NextInField(remaining, edit)};
|
||||
if (next && *next == '.') { // skip optional period
|
||||
next = io.NextInField(remaining, edit);
|
||||
}
|
||||
@@ -916,8 +918,9 @@ static bool EditListDirectedCharacterInput(
|
||||
// or the end of the current record. Subtlety: the "remaining" count
|
||||
// here is a dummy that's used to avoid the interpretation of separators
|
||||
// in NextInField.
|
||||
std::optional<int> remaining{length > 0 ? maxUTF8Bytes : 0};
|
||||
while (std::optional<char32_t> next{io.NextInField(remaining, edit)}) {
|
||||
Fortran::common::optional<int> remaining{length > 0 ? maxUTF8Bytes : 0};
|
||||
while (Fortran::common::optional<char32_t> next{
|
||||
io.NextInField(remaining, edit)}) {
|
||||
bool isSep{false};
|
||||
switch (*next) {
|
||||
case ' ':
|
||||
|
||||
@@ -49,7 +49,8 @@ static void SetEnvironmentDefaults(const EnvironmentDefaultList *envDefaults) {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Convert> GetConvertFromString(const char *x, std::size_t n) {
|
||||
Fortran::common::optional<Convert> GetConvertFromString(
|
||||
const char *x, std::size_t n) {
|
||||
static const char *keywords[]{
|
||||
"UNKNOWN", "NATIVE", "LITTLE_ENDIAN", "BIG_ENDIAN", "SWAP", nullptr};
|
||||
switch (IdentifyValue(x, n, keywords)) {
|
||||
@@ -64,7 +65,7 @@ std::optional<Convert> GetConvertFromString(const char *x, std::size_t n) {
|
||||
case 4:
|
||||
return Convert::Swap;
|
||||
default:
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
#ifndef FORTRAN_RUNTIME_ENVIRONMENT_H_
|
||||
#define FORTRAN_RUNTIME_ENVIRONMENT_H_
|
||||
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Decimal/decimal.h"
|
||||
#include "flang/Runtime/api-attrs.h"
|
||||
#include <optional>
|
||||
|
||||
struct EnvironmentDefaultList;
|
||||
|
||||
@@ -30,7 +29,8 @@ constexpr bool isHostLittleEndian{true};
|
||||
// External unformatted I/O data conversions
|
||||
enum class Convert { Unknown, Native, LittleEndian, BigEndian, Swap };
|
||||
|
||||
std::optional<Convert> GetConvertFromString(const char *, std::size_t);
|
||||
Fortran::common::optional<Convert> GetConvertFromString(
|
||||
const char *, std::size_t);
|
||||
|
||||
struct ExecutionEnvironment {
|
||||
#if !defined(_OPENMP)
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <cfloat>
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Fortran::runtime {
|
||||
|
||||
@@ -60,7 +60,7 @@ static int openfile_mkstemp(IoErrorHandler &handler) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
void OpenFile::Open(OpenStatus status, std::optional<Action> action,
|
||||
void OpenFile::Open(OpenStatus status, Fortran::common::optional<Action> action,
|
||||
Position position, IoErrorHandler &handler) {
|
||||
if (fd_ >= 0 &&
|
||||
(status == OpenStatus::Old || status == OpenStatus::Unknown)) {
|
||||
@@ -322,7 +322,7 @@ int OpenFile::WriteAsynchronously(FileOffset at, const char *buffer,
|
||||
}
|
||||
|
||||
void OpenFile::Wait(int id, IoErrorHandler &handler) {
|
||||
std::optional<int> ioStat;
|
||||
Fortran::common::optional<int> ioStat;
|
||||
Pending *prev{nullptr};
|
||||
for (Pending *p{pending_.get()}; p; p = (prev = p)->next.get()) {
|
||||
if (p->id == id) {
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
#define FORTRAN_RUNTIME_FILE_H_
|
||||
|
||||
#include "io-error.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Runtime/memory.h"
|
||||
#include <cinttypes>
|
||||
#include <optional>
|
||||
|
||||
namespace Fortran::runtime::io {
|
||||
|
||||
@@ -37,10 +37,11 @@ public:
|
||||
void set_mayAsynchronous(bool yes) { mayAsynchronous_ = yes; }
|
||||
bool isTerminal() const { return isTerminal_; }
|
||||
bool isWindowsTextFile() const { return isWindowsTextFile_; }
|
||||
std::optional<FileOffset> knownSize() const { return knownSize_; }
|
||||
Fortran::common::optional<FileOffset> knownSize() const { return knownSize_; }
|
||||
|
||||
bool IsConnected() const { return fd_ >= 0; }
|
||||
void Open(OpenStatus, std::optional<Action>, Position, IoErrorHandler &);
|
||||
void Open(OpenStatus, Fortran::common::optional<Action>, Position,
|
||||
IoErrorHandler &);
|
||||
void Predefine(int fd);
|
||||
void Close(CloseStatus, IoErrorHandler &);
|
||||
|
||||
@@ -94,9 +95,10 @@ private:
|
||||
bool mayWrite_{false};
|
||||
bool mayPosition_{false};
|
||||
bool mayAsynchronous_{false};
|
||||
std::optional<Position> openPosition_; // from Open(); reset after positioning
|
||||
Fortran::common::optional<Position>
|
||||
openPosition_; // from Open(); reset after positioning
|
||||
FileOffset position_{0};
|
||||
std::optional<FileOffset> knownSize_;
|
||||
Fortran::common::optional<FileOffset> knownSize_;
|
||||
bool isTerminal_{false};
|
||||
bool isWindowsTextFile_{false}; // expands LF to CR+LF on write
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
|
||||
}
|
||||
}
|
||||
while (true) {
|
||||
std::optional<int> repeat;
|
||||
Fortran::common::optional<int> repeat;
|
||||
bool unlimited{false};
|
||||
auto maybeReversionPoint{offset_};
|
||||
CharType ch{GetNextChar(context)};
|
||||
@@ -419,7 +419,7 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
|
||||
|
||||
// Returns the next data edit descriptor
|
||||
template <typename CONTEXT>
|
||||
std::optional<DataEdit> FormatControl<CONTEXT>::GetNextDataEdit(
|
||||
Fortran::common::optional<DataEdit> FormatControl<CONTEXT>::GetNextDataEdit(
|
||||
Context &context, int maxRepeat) {
|
||||
int repeat{CueUpNextDataEdit(context)};
|
||||
auto start{offset_};
|
||||
@@ -451,7 +451,7 @@ std::optional<DataEdit> FormatControl<CONTEXT>::GetNextDataEdit(
|
||||
}
|
||||
if (edit.ioTypeChars >= edit.maxIoTypeChars) {
|
||||
ReportBadFormat(context, "Excessive DT'iotype' in FORMAT", start);
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
edit.ioType[edit.ioTypeChars++] = ch;
|
||||
if (ch == quote) {
|
||||
@@ -460,7 +460,7 @@ std::optional<DataEdit> FormatControl<CONTEXT>::GetNextDataEdit(
|
||||
}
|
||||
if (!ok) {
|
||||
ReportBadFormat(context, "Unclosed DT'iotype' in FORMAT", start);
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
}
|
||||
if (PeekNext() == '(') {
|
||||
@@ -475,7 +475,7 @@ std::optional<DataEdit> FormatControl<CONTEXT>::GetNextDataEdit(
|
||||
}
|
||||
if (edit.vListEntries >= edit.maxVListEntries) {
|
||||
ReportBadFormat(context, "Excessive DT(v_list) in FORMAT", start);
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
edit.vList[edit.vListEntries++] = n;
|
||||
auto ch{static_cast<char>(GetNextChar(context))};
|
||||
@@ -486,7 +486,7 @@ std::optional<DataEdit> FormatControl<CONTEXT>::GetNextDataEdit(
|
||||
}
|
||||
if (!ok) {
|
||||
ReportBadFormat(context, "Unclosed DT(v_list) in FORMAT", start);
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
}
|
||||
} else { // not DT'iotype'
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
#include "environment.h"
|
||||
#include "io-error.h"
|
||||
#include "flang/Common/Fortran.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Decimal/decimal.h"
|
||||
#include <cinttypes>
|
||||
#include <optional>
|
||||
|
||||
namespace Fortran::runtime {
|
||||
class Descriptor;
|
||||
@@ -64,9 +64,9 @@ struct DataEdit {
|
||||
static constexpr char DefinedDerivedType{'d'}; // DT defined I/O
|
||||
|
||||
char variation{'\0'}; // N, S, or X for EN, ES, EX; G/l for original G/list
|
||||
std::optional<int> width; // the 'w' field; optional for A
|
||||
std::optional<int> digits; // the 'm' or 'd' field
|
||||
std::optional<int> expoDigits; // 'Ee' field
|
||||
Fortran::common::optional<int> width; // the 'w' field; optional for A
|
||||
Fortran::common::optional<int> digits; // the 'm' or 'd' field
|
||||
Fortran::common::optional<int> expoDigits; // 'Ee' field
|
||||
MutableModes modes;
|
||||
int repeat{1};
|
||||
|
||||
@@ -102,7 +102,8 @@ public:
|
||||
// Extracts the next data edit descriptor, handling control edit descriptors
|
||||
// along the way. If maxRepeat==0, this is a peek at the next data edit
|
||||
// descriptor.
|
||||
std::optional<DataEdit> GetNextDataEdit(Context &, int maxRepeat = 1);
|
||||
Fortran::common::optional<DataEdit> GetNextDataEdit(
|
||||
Context &, int maxRepeat = 1);
|
||||
|
||||
// Emit any remaining character literals after the last data item (on output)
|
||||
// and perform remaining record positioning actions.
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "terminator.h"
|
||||
#include "tools.h"
|
||||
#include "unit.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Runtime/descriptor.h"
|
||||
#include "flang/Runtime/memory.h"
|
||||
#include <cstdlib>
|
||||
@@ -168,7 +169,7 @@ static Cookie NoopUnit(const Terminator &terminator, int unitNumber,
|
||||
}
|
||||
|
||||
static ExternalFileUnit *GetOrCreateUnit(int unitNumber, Direction direction,
|
||||
std::optional<bool> isUnformatted, const Terminator &terminator,
|
||||
Fortran::common::optional<bool> isUnformatted, const Terminator &terminator,
|
||||
Cookie &errorCookie) {
|
||||
if (ExternalFileUnit *
|
||||
unit{ExternalFileUnit::LookUpOrCreateAnonymous(
|
||||
@@ -472,8 +473,8 @@ Cookie IONAME(BeginEndfile)(
|
||||
Terminator terminator{sourceFile, sourceLine};
|
||||
Cookie errorCookie{nullptr};
|
||||
if (ExternalFileUnit *
|
||||
unit{GetOrCreateUnit(unitNumber, Direction::Output, std::nullopt,
|
||||
terminator, errorCookie)}) {
|
||||
unit{GetOrCreateUnit(unitNumber, Direction::Output,
|
||||
Fortran::common::nullopt, terminator, errorCookie)}) {
|
||||
if (ChildIo * child{unit->GetChildIo()}) {
|
||||
return &child->BeginIoStatement<ErroneousIoStatementState>(
|
||||
IostatBadOpOnChildUnit, nullptr /* no unit */, sourceFile,
|
||||
@@ -492,8 +493,8 @@ Cookie IONAME(BeginRewind)(
|
||||
Terminator terminator{sourceFile, sourceLine};
|
||||
Cookie errorCookie{nullptr};
|
||||
if (ExternalFileUnit *
|
||||
unit{GetOrCreateUnit(unitNumber, Direction::Input, std::nullopt,
|
||||
terminator, errorCookie)}) {
|
||||
unit{GetOrCreateUnit(unitNumber, Direction::Input,
|
||||
Fortran::common::nullopt, terminator, errorCookie)}) {
|
||||
if (ChildIo * child{unit->GetChildIo()}) {
|
||||
return &child->BeginIoStatement<ErroneousIoStatementState>(
|
||||
IostatBadOpOnChildUnit, nullptr /* no unit */, sourceFile,
|
||||
@@ -801,7 +802,7 @@ bool IONAME(SetAction)(Cookie cookie, const char *keyword, std::size_t length) {
|
||||
io.GetIoErrorHandler().Crash(
|
||||
"SetAction() called after GetNewUnit() for an OPEN statement");
|
||||
}
|
||||
std::optional<Action> action;
|
||||
Fortran::common::optional<Action> action;
|
||||
static const char *keywords[]{"READ", "WRITE", "READWRITE", nullptr};
|
||||
switch (IdentifyValue(keyword, length, keywords)) {
|
||||
case 0:
|
||||
|
||||
@@ -39,9 +39,9 @@ bool IoStatementBase::Receive(char *, std::size_t, std::size_t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<DataEdit> IoStatementBase::GetNextDataEdit(
|
||||
Fortran::common::optional<DataEdit> IoStatementBase::GetNextDataEdit(
|
||||
IoStatementState &, int) {
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
|
||||
ExternalFileUnit *IoStatementBase::GetExternalFileUnit() const {
|
||||
@@ -466,7 +466,7 @@ int ExternalFormattedIoStatementState<DIR, CHAR>::EndIoStatement() {
|
||||
return ExternalIoStatementState<DIR>::EndIoStatement();
|
||||
}
|
||||
|
||||
std::optional<DataEdit> IoStatementState::GetNextDataEdit(int n) {
|
||||
Fortran::common::optional<DataEdit> IoStatementState::GetNextDataEdit(int n) {
|
||||
return common::visit(
|
||||
[&](auto &x) { return x.get().GetNextDataEdit(*this, n); }, u_);
|
||||
}
|
||||
@@ -541,13 +541,13 @@ ExternalFileUnit *IoStatementState::GetExternalFileUnit() const {
|
||||
[](auto &x) { return x.get().GetExternalFileUnit(); }, u_);
|
||||
}
|
||||
|
||||
std::optional<char32_t> IoStatementState::GetCurrentChar(
|
||||
Fortran::common::optional<char32_t> IoStatementState::GetCurrentChar(
|
||||
std::size_t &byteCount) {
|
||||
const char *p{nullptr};
|
||||
std::size_t bytes{GetNextInputBytes(p)};
|
||||
if (bytes == 0) {
|
||||
byteCount = 0;
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
} else {
|
||||
const ConnectionState &connection{GetConnectionState()};
|
||||
if (connection.isUTF8) {
|
||||
@@ -573,8 +573,8 @@ std::optional<char32_t> IoStatementState::GetCurrentChar(
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<char32_t> IoStatementState::NextInField(
|
||||
std::optional<int> &remaining, const DataEdit &edit) {
|
||||
Fortran::common::optional<char32_t> IoStatementState::NextInField(
|
||||
Fortran::common::optional<int> &remaining, const DataEdit &edit) {
|
||||
std::size_t byteCount{0};
|
||||
if (!remaining) { // Stream, list-directed, or NAMELIST
|
||||
if (auto next{GetCurrentChar(byteCount)}) {
|
||||
@@ -590,21 +590,21 @@ std::optional<char32_t> IoStatementState::NextInField(
|
||||
case '"':
|
||||
case '*':
|
||||
case '\n': // for stream access
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
case '&':
|
||||
case '$':
|
||||
if (edit.IsNamelist()) {
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
break;
|
||||
case ',':
|
||||
if (!(edit.modes.editingFlags & decimalComma)) {
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
break;
|
||||
case ';':
|
||||
if (edit.modes.editingFlags & decimalComma) {
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -618,7 +618,7 @@ std::optional<char32_t> IoStatementState::NextInField(
|
||||
} else if (*remaining > 0) {
|
||||
if (auto next{GetCurrentChar(byteCount)}) {
|
||||
if (byteCount > static_cast<std::size_t>(*remaining)) {
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
*remaining -= byteCount;
|
||||
HandleRelativePosition(byteCount);
|
||||
@@ -627,10 +627,10 @@ std::optional<char32_t> IoStatementState::NextInField(
|
||||
}
|
||||
if (CheckForEndOfRecord(0)) { // do padding
|
||||
--*remaining;
|
||||
return std::optional<char32_t>{' '};
|
||||
return Fortran::common::optional<char32_t>{' '};
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
|
||||
bool IoStatementState::CheckForEndOfRecord(std::size_t afterReading) {
|
||||
@@ -722,7 +722,7 @@ bool ListDirectedStatementState<Direction::Output>::EmitLeadingSpaceOrAdvance(
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<DataEdit>
|
||||
Fortran::common::optional<DataEdit>
|
||||
ListDirectedStatementState<Direction::Output>::GetNextDataEdit(
|
||||
IoStatementState &io, int maxRepeat) {
|
||||
DataEdit edit;
|
||||
@@ -739,7 +739,7 @@ int ListDirectedStatementState<Direction::Input>::EndIoStatement() {
|
||||
return IostatOk;
|
||||
}
|
||||
|
||||
std::optional<DataEdit>
|
||||
Fortran::common::optional<DataEdit>
|
||||
ListDirectedStatementState<Direction::Input>::GetNextDataEdit(
|
||||
IoStatementState &io, int maxRepeat) {
|
||||
// N.B. list-directed transfers cannot be nonadvancing (C1221)
|
||||
@@ -795,7 +795,7 @@ ListDirectedStatementState<Direction::Input>::GetNextDataEdit(
|
||||
}
|
||||
eatComma_ = true;
|
||||
if (!ch) {
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
if (*ch == '/') {
|
||||
hitSlash_ = true;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "format.h"
|
||||
#include "internal-unit.h"
|
||||
#include "io-error.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Common/visit.h"
|
||||
#include "flang/Runtime/descriptor.h"
|
||||
#include "flang/Runtime/io-api.h"
|
||||
@@ -94,7 +95,7 @@ public:
|
||||
void BackspaceRecord();
|
||||
void HandleRelativePosition(std::int64_t byteOffset);
|
||||
void HandleAbsolutePosition(std::int64_t byteOffset); // for r* in list I/O
|
||||
std::optional<DataEdit> GetNextDataEdit(int maxRepeat = 1);
|
||||
Fortran::common::optional<DataEdit> GetNextDataEdit(int maxRepeat = 1);
|
||||
ExternalFileUnit *GetExternalFileUnit() const; // null if internal unit
|
||||
bool BeginReadingRecord();
|
||||
void FinishReadingRecord();
|
||||
@@ -122,7 +123,7 @@ public:
|
||||
}
|
||||
|
||||
// Vacant after the end of the current record
|
||||
std::optional<char32_t> GetCurrentChar(std::size_t &byteCount);
|
||||
Fortran::common::optional<char32_t> GetCurrentChar(std::size_t &byteCount);
|
||||
|
||||
// The "remaining" arguments to CueUpInput(), SkipSpaces(), & NextInField()
|
||||
// are always in units of bytes, not characters; the distinction matters
|
||||
@@ -130,8 +131,8 @@ public:
|
||||
|
||||
// For fixed-width fields, return the number of remaining bytes.
|
||||
// Skip over leading blanks.
|
||||
std::optional<int> CueUpInput(const DataEdit &edit) {
|
||||
std::optional<int> remaining;
|
||||
Fortran::common::optional<int> CueUpInput(const DataEdit &edit) {
|
||||
Fortran::common::optional<int> remaining;
|
||||
if (edit.IsListDirected()) {
|
||||
std::size_t byteCount{0};
|
||||
GetNextNonBlank(byteCount);
|
||||
@@ -148,7 +149,8 @@ public:
|
||||
return remaining;
|
||||
}
|
||||
|
||||
std::optional<char32_t> SkipSpaces(std::optional<int> &remaining) {
|
||||
Fortran::common::optional<char32_t> SkipSpaces(
|
||||
Fortran::common::optional<int> &remaining) {
|
||||
while (!remaining || *remaining > 0) {
|
||||
std::size_t byteCount{0};
|
||||
if (auto ch{GetCurrentChar(byteCount)}) {
|
||||
@@ -167,27 +169,27 @@ public:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
|
||||
// Acquires the next input character, respecting any applicable field width
|
||||
// or separator character.
|
||||
std::optional<char32_t> NextInField(
|
||||
std::optional<int> &remaining, const DataEdit &);
|
||||
Fortran::common::optional<char32_t> NextInField(
|
||||
Fortran::common::optional<int> &remaining, const DataEdit &);
|
||||
|
||||
// Detect and signal any end-of-record condition after input.
|
||||
// Returns true if at EOR and remaining input should be padded with blanks.
|
||||
bool CheckForEndOfRecord(std::size_t afterReading);
|
||||
|
||||
// Skips spaces, advances records, and ignores NAMELIST comments
|
||||
std::optional<char32_t> GetNextNonBlank(std::size_t &byteCount) {
|
||||
Fortran::common::optional<char32_t> GetNextNonBlank(std::size_t &byteCount) {
|
||||
auto ch{GetCurrentChar(byteCount)};
|
||||
bool inNamelist{mutableModes().inNamelist};
|
||||
while (!ch || *ch == ' ' || *ch == '\t' || (inNamelist && *ch == '!')) {
|
||||
if (ch && (*ch == ' ' || *ch == '\t')) {
|
||||
HandleRelativePosition(byteCount);
|
||||
} else if (!AdvanceRecord()) {
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
ch = GetCurrentChar(byteCount);
|
||||
}
|
||||
@@ -262,7 +264,7 @@ public:
|
||||
void BackspaceRecord();
|
||||
void HandleRelativePosition(std::int64_t);
|
||||
void HandleAbsolutePosition(std::int64_t);
|
||||
std::optional<DataEdit> GetNextDataEdit(
|
||||
Fortran::common::optional<DataEdit> GetNextDataEdit(
|
||||
IoStatementState &, int maxRepeat = 1);
|
||||
ExternalFileUnit *GetExternalFileUnit() const;
|
||||
bool BeginReadingRecord();
|
||||
@@ -287,7 +289,7 @@ class ListDirectedStatementState<Direction::Output>
|
||||
public:
|
||||
bool EmitLeadingSpaceOrAdvance(
|
||||
IoStatementState &, std::size_t = 1, bool isCharacter = false);
|
||||
std::optional<DataEdit> GetNextDataEdit(
|
||||
Fortran::common::optional<DataEdit> GetNextDataEdit(
|
||||
IoStatementState &, int maxRepeat = 1);
|
||||
bool lastWasUndelimitedCharacter() const {
|
||||
return lastWasUndelimitedCharacter_;
|
||||
@@ -309,7 +311,7 @@ public:
|
||||
// Skips value separators, handles repetition and null values.
|
||||
// Vacant when '/' appears; present with descriptor == ListDirectedNullValue
|
||||
// when a null value appears.
|
||||
std::optional<DataEdit> GetNextDataEdit(
|
||||
Fortran::common::optional<DataEdit> GetNextDataEdit(
|
||||
IoStatementState &, int maxRepeat = 1);
|
||||
|
||||
// Each NAMELIST input item is treated like a distinct list-directed
|
||||
@@ -328,7 +330,7 @@ public:
|
||||
|
||||
private:
|
||||
int remaining_{0}; // for "r*" repetition
|
||||
std::optional<SavedPosition> repeatPosition_;
|
||||
Fortran::common::optional<SavedPosition> repeatPosition_;
|
||||
bool eatComma_{false}; // consume comma after previously read item
|
||||
bool hitSlash_{false}; // once '/' is seen, nullify further items
|
||||
bool realPart_{false};
|
||||
@@ -380,7 +382,7 @@ public:
|
||||
IoStatementState &ioStatementState() { return ioStatementState_; }
|
||||
void CompleteOperation();
|
||||
int EndIoStatement();
|
||||
std::optional<DataEdit> GetNextDataEdit(
|
||||
Fortran::common::optional<DataEdit> GetNextDataEdit(
|
||||
IoStatementState &, int maxRepeat = 1) {
|
||||
return format_.GetNextDataEdit(*this, maxRepeat);
|
||||
}
|
||||
@@ -465,7 +467,7 @@ public:
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
void CompleteOperation();
|
||||
int EndIoStatement();
|
||||
std::optional<DataEdit> GetNextDataEdit(
|
||||
Fortran::common::optional<DataEdit> GetNextDataEdit(
|
||||
IoStatementState &, int maxRepeat = 1) {
|
||||
return format_.GetNextDataEdit(*this, maxRepeat);
|
||||
}
|
||||
@@ -523,7 +525,7 @@ public:
|
||||
void CompleteOperation();
|
||||
int EndIoStatement();
|
||||
bool AdvanceRecord(int = 1);
|
||||
std::optional<DataEdit> GetNextDataEdit(
|
||||
Fortran::common::optional<DataEdit> GetNextDataEdit(
|
||||
IoStatementState &, int maxRepeat = 1) {
|
||||
return format_.GetNextDataEdit(*this, maxRepeat);
|
||||
}
|
||||
@@ -571,14 +573,14 @@ public:
|
||||
private:
|
||||
bool wasExtant_;
|
||||
bool isNewUnit_;
|
||||
std::optional<OpenStatus> status_;
|
||||
std::optional<Position> position_;
|
||||
std::optional<Action> action_;
|
||||
Fortran::common::optional<OpenStatus> status_;
|
||||
Fortran::common::optional<Position> position_;
|
||||
Fortran::common::optional<Action> action_;
|
||||
Convert convert_{Convert::Unknown};
|
||||
OwningPtr<char> path_;
|
||||
std::size_t pathLength_;
|
||||
std::optional<bool> isUnformatted_;
|
||||
std::optional<Access> access_;
|
||||
Fortran::common::optional<bool> isUnformatted_;
|
||||
Fortran::common::optional<Access> access_;
|
||||
};
|
||||
|
||||
class CloseStatementState : public ExternalIoStatementBase {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "flang/Runtime/matmul-transpose.h"
|
||||
#include "terminator.h"
|
||||
#include "tools.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Runtime/c-or-cpp.h"
|
||||
#include "flang/Runtime/cpp-type.h"
|
||||
#include "flang/Runtime/descriptor.h"
|
||||
@@ -96,8 +97,8 @@ template <TypeCategory RCAT, int RKIND, typename XT, typename YT>
|
||||
inline static RT_API_ATTRS void MatrixTransposedTimesMatrixHelper(
|
||||
CppTypeFor<RCAT, RKIND> *RESTRICT product, SubscriptValue rows,
|
||||
SubscriptValue cols, const XT *RESTRICT x, const YT *RESTRICT y,
|
||||
SubscriptValue n, std::optional<std::size_t> xColumnByteStride,
|
||||
std::optional<std::size_t> yColumnByteStride) {
|
||||
SubscriptValue n, Fortran::common::optional<std::size_t> xColumnByteStride,
|
||||
Fortran::common::optional<std::size_t> yColumnByteStride) {
|
||||
if (!xColumnByteStride) {
|
||||
if (!yColumnByteStride) {
|
||||
MatrixTransposedTimesMatrix<RCAT, RKIND, XT, YT, false, false>(
|
||||
@@ -163,7 +164,7 @@ template <TypeCategory RCAT, int RKIND, typename XT, typename YT>
|
||||
inline static RT_API_ATTRS void MatrixTransposedTimesVectorHelper(
|
||||
CppTypeFor<RCAT, RKIND> *RESTRICT product, SubscriptValue rows,
|
||||
SubscriptValue n, const XT *RESTRICT x, const YT *RESTRICT y,
|
||||
std::optional<std::size_t> xColumnByteStride) {
|
||||
Fortran::common::optional<std::size_t> xColumnByteStride) {
|
||||
if (!xColumnByteStride) {
|
||||
MatrixTransposedTimesVector<RCAT, RKIND, XT, YT, false>(
|
||||
product, rows, n, x, y);
|
||||
@@ -229,7 +230,7 @@ inline static RT_API_ATTRS void DoMatmulTranspose(
|
||||
(IS_ALLOCATING || result.IsContiguous())) {
|
||||
// Contiguous numeric matrices (maybe with columns
|
||||
// separated by a stride).
|
||||
std::optional<std::size_t> xColumnByteStride;
|
||||
Fortran::common::optional<std::size_t> xColumnByteStride;
|
||||
if (!x.IsContiguous()) {
|
||||
// X's columns are strided.
|
||||
SubscriptValue xAt[2]{};
|
||||
@@ -237,7 +238,7 @@ inline static RT_API_ATTRS void DoMatmulTranspose(
|
||||
xAt[1]++;
|
||||
xColumnByteStride = x.SubscriptsToByteOffset(xAt);
|
||||
}
|
||||
std::optional<std::size_t> yColumnByteStride;
|
||||
Fortran::common::optional<std::size_t> yColumnByteStride;
|
||||
if (!y.IsContiguous()) {
|
||||
// Y's columns are strided.
|
||||
SubscriptValue yAt[2]{};
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "flang/Runtime/matmul.h"
|
||||
#include "terminator.h"
|
||||
#include "tools.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Runtime/c-or-cpp.h"
|
||||
#include "flang/Runtime/cpp-type.h"
|
||||
#include "flang/Runtime/descriptor.h"
|
||||
@@ -116,8 +117,8 @@ template <TypeCategory RCAT, int RKIND, typename XT, typename YT>
|
||||
inline RT_API_ATTRS void MatrixTimesMatrixHelper(
|
||||
CppTypeFor<RCAT, RKIND> *RESTRICT product, SubscriptValue rows,
|
||||
SubscriptValue cols, const XT *RESTRICT x, const YT *RESTRICT y,
|
||||
SubscriptValue n, std::optional<std::size_t> xColumnByteStride,
|
||||
std::optional<std::size_t> yColumnByteStride) {
|
||||
SubscriptValue n, Fortran::common::optional<std::size_t> xColumnByteStride,
|
||||
Fortran::common::optional<std::size_t> yColumnByteStride) {
|
||||
if (!xColumnByteStride) {
|
||||
if (!yColumnByteStride) {
|
||||
MatrixTimesMatrix<RCAT, RKIND, XT, YT, false, false>(
|
||||
@@ -183,7 +184,7 @@ template <TypeCategory RCAT, int RKIND, typename XT, typename YT>
|
||||
inline RT_API_ATTRS void MatrixTimesVectorHelper(
|
||||
CppTypeFor<RCAT, RKIND> *RESTRICT product, SubscriptValue rows,
|
||||
SubscriptValue n, const XT *RESTRICT x, const YT *RESTRICT y,
|
||||
std::optional<std::size_t> xColumnByteStride) {
|
||||
Fortran::common::optional<std::size_t> xColumnByteStride) {
|
||||
if (!xColumnByteStride) {
|
||||
MatrixTimesVector<RCAT, RKIND, XT, YT, false>(product, rows, n, x, y);
|
||||
} else {
|
||||
@@ -240,7 +241,7 @@ template <TypeCategory RCAT, int RKIND, typename XT, typename YT,
|
||||
inline RT_API_ATTRS void VectorTimesMatrixHelper(
|
||||
CppTypeFor<RCAT, RKIND> *RESTRICT product, SubscriptValue n,
|
||||
SubscriptValue cols, const XT *RESTRICT x, const YT *RESTRICT y,
|
||||
std::optional<std::size_t> yColumnByteStride) {
|
||||
Fortran::common::optional<std::size_t> yColumnByteStride) {
|
||||
if (!yColumnByteStride) {
|
||||
VectorTimesMatrix<RCAT, RKIND, XT, YT, false>(product, n, cols, x, y);
|
||||
} else {
|
||||
@@ -301,7 +302,7 @@ static inline RT_API_ATTRS void DoMatmul(
|
||||
(IS_ALLOCATING || result.IsContiguous())) {
|
||||
// Contiguous numeric matrices (maybe with columns
|
||||
// separated by a stride).
|
||||
std::optional<std::size_t> xColumnByteStride;
|
||||
Fortran::common::optional<std::size_t> xColumnByteStride;
|
||||
if (!x.IsContiguous()) {
|
||||
// X's columns are strided.
|
||||
SubscriptValue xAt[2]{};
|
||||
@@ -309,7 +310,7 @@ static inline RT_API_ATTRS void DoMatmul(
|
||||
xAt[1]++;
|
||||
xColumnByteStride = x.SubscriptsToByteOffset(xAt);
|
||||
}
|
||||
std::optional<std::size_t> yColumnByteStride;
|
||||
Fortran::common::optional<std::size_t> yColumnByteStride;
|
||||
if (!y.IsContiguous()) {
|
||||
// Y's columns are strided.
|
||||
SubscriptValue yAt[2]{};
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
#include "flang/Runtime/misc-intrinsic.h"
|
||||
#include "terminator.h"
|
||||
#include "tools.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Runtime/descriptor.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
|
||||
namespace Fortran::runtime {
|
||||
|
||||
static RT_API_ATTRS void TransferImpl(Descriptor &result,
|
||||
const Descriptor &source, const Descriptor &mold, const char *sourceFile,
|
||||
int line, std::optional<std::int64_t> resultExtent) {
|
||||
int line, Fortran::common::optional<std::int64_t> resultExtent) {
|
||||
int rank{resultExtent.has_value() ? 1 : 0};
|
||||
std::size_t elementBytes{mold.ElementBytes()};
|
||||
result.Establish(mold.type(), elementBytes, nullptr, rank, nullptr,
|
||||
@@ -57,7 +57,7 @@ RT_EXT_API_GROUP_BEGIN
|
||||
|
||||
void RTDEF(Transfer)(Descriptor &result, const Descriptor &source,
|
||||
const Descriptor &mold, const char *sourceFile, int line) {
|
||||
std::optional<std::int64_t> elements;
|
||||
Fortran::common::optional<std::int64_t> elements;
|
||||
if (mold.rank() > 0) {
|
||||
if (std::size_t sourceElementBytes{
|
||||
source.Elements() * source.ElementBytes()}) {
|
||||
|
||||
@@ -116,10 +116,11 @@ static bool GetLowerCaseName(
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::optional<SubscriptValue> GetSubscriptValue(IoStatementState &io) {
|
||||
std::optional<SubscriptValue> value;
|
||||
static Fortran::common::optional<SubscriptValue> GetSubscriptValue(
|
||||
IoStatementState &io) {
|
||||
Fortran::common::optional<SubscriptValue> value;
|
||||
std::size_t byteCount{0};
|
||||
std::optional<char32_t> ch{io.GetCurrentChar(byteCount)};
|
||||
Fortran::common::optional<char32_t> ch{io.GetCurrentChar(byteCount)};
|
||||
bool negate{ch && *ch == '-'};
|
||||
if ((ch && *ch == '+') || negate) {
|
||||
io.HandleRelativePosition(byteCount);
|
||||
@@ -136,7 +137,7 @@ static std::optional<SubscriptValue> GetSubscriptValue(IoStatementState &io) {
|
||||
if (overflow) {
|
||||
io.GetIoErrorHandler().SignalError(
|
||||
"NAMELIST input subscript value overflow");
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
if (negate) {
|
||||
if (value) {
|
||||
@@ -158,7 +159,7 @@ static bool HandleSubscripts(IoStatementState &io, Descriptor &desc,
|
||||
std::size_t contiguousStride{source.ElementBytes()};
|
||||
bool ok{true};
|
||||
std::size_t byteCount{0};
|
||||
std::optional<char32_t> ch{io.GetNextNonBlank(byteCount)};
|
||||
Fortran::common::optional<char32_t> ch{io.GetNextNonBlank(byteCount)};
|
||||
char32_t comma{GetComma(io)};
|
||||
for (; ch && *ch != ')'; ++j) {
|
||||
SubscriptValue dimLower{0}, dimUpper{0}, dimStride{0};
|
||||
@@ -282,9 +283,9 @@ static bool HandleSubstring(
|
||||
SubscriptValue chars{static_cast<SubscriptValue>(desc.ElementBytes()) / kind};
|
||||
// Allow for blanks in substring bounds; they're nonstandard, but not
|
||||
// ambiguous within the parentheses.
|
||||
std::optional<SubscriptValue> lower, upper;
|
||||
Fortran::common::optional<SubscriptValue> lower, upper;
|
||||
std::size_t byteCount{0};
|
||||
std::optional<char32_t> ch{io.GetNextNonBlank(byteCount)};
|
||||
Fortran::common::optional<char32_t> ch{io.GetNextNonBlank(byteCount)};
|
||||
if (ch) {
|
||||
if (*ch == ':') {
|
||||
lower = 1;
|
||||
@@ -346,7 +347,8 @@ static bool HandleComponent(IoStatementState &io, Descriptor &desc,
|
||||
// If base and component are both arrays, the component name
|
||||
// must be followed by subscripts; process them now.
|
||||
std::size_t byteCount{0};
|
||||
if (std::optional<char32_t> next{io.GetNextNonBlank(byteCount)};
|
||||
if (Fortran::common::optional<char32_t> next{
|
||||
io.GetNextNonBlank(byteCount)};
|
||||
next && *next == '(') {
|
||||
io.HandleRelativePosition(byteCount); // skip over '('
|
||||
StaticDescriptor<maxRank, true, 16> staticDesc;
|
||||
@@ -435,7 +437,7 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
|
||||
RUNTIME_CHECK(handler, listInput != nullptr);
|
||||
// Find this namelist group's header in the input
|
||||
io.BeginReadingRecord();
|
||||
std::optional<char32_t> next;
|
||||
Fortran::common::optional<char32_t> next;
|
||||
char name[nameBufferSize];
|
||||
RUNTIME_CHECK(handler, group.groupName != nullptr);
|
||||
char32_t comma{GetComma(io)};
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "lock.h"
|
||||
#include "numeric-templates.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Runtime/descriptor.h"
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
@@ -32,7 +33,7 @@ static constexpr int rangeBits{
|
||||
|
||||
extern Lock lock;
|
||||
extern Generator generator;
|
||||
extern std::optional<GeneratedWord> nextValue;
|
||||
extern Fortran::common::optional<GeneratedWord> nextValue;
|
||||
|
||||
// Call only with lock held
|
||||
static GeneratedWord GetNextValue() {
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Fortran::runtime::random {
|
||||
|
||||
Lock lock;
|
||||
Generator generator;
|
||||
std::optional<GeneratedWord> nextValue;
|
||||
Fortran::common::optional<GeneratedWord> nextValue;
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "freestanding-tools.h"
|
||||
#include "stat.h"
|
||||
#include "terminator.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Runtime/cpp-type.h"
|
||||
#include "flang/Runtime/descriptor.h"
|
||||
#include "flang/Runtime/memory.h"
|
||||
@@ -95,7 +96,7 @@ static inline RT_API_ATTRS std::int64_t GetInt64(
|
||||
}
|
||||
}
|
||||
|
||||
static inline RT_API_ATTRS std::optional<std::int64_t> GetInt64Safe(
|
||||
static inline RT_API_ATTRS Fortran::common::optional<std::int64_t> GetInt64Safe(
|
||||
const char *p, std::size_t bytes, Terminator &terminator) {
|
||||
switch (bytes) {
|
||||
case 1:
|
||||
@@ -113,7 +114,7 @@ static inline RT_API_ATTRS std::optional<std::int64_t> GetInt64Safe(
|
||||
if (static_cast<Int128>(result) == n) {
|
||||
return result;
|
||||
}
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
default:
|
||||
terminator.Crash("GetInt64Safe: no case for %zd bytes", bytes);
|
||||
@@ -334,7 +335,8 @@ inline RT_API_ATTRS RESULT ApplyLogicalKind(
|
||||
}
|
||||
|
||||
// Calculate result type of (X op Y) for *, //, DOT_PRODUCT, &c.
|
||||
std::optional<std::pair<TypeCategory, int>> inline constexpr RT_API_ATTRS
|
||||
Fortran::common::optional<
|
||||
std::pair<TypeCategory, int>> inline constexpr RT_API_ATTRS
|
||||
GetResultType(TypeCategory xCat, int xKind, TypeCategory yCat, int yKind) {
|
||||
int maxKind{std::max(xKind, yKind)};
|
||||
switch (xCat) {
|
||||
@@ -390,18 +392,18 @@ GetResultType(TypeCategory xCat, int xKind, TypeCategory yCat, int yKind) {
|
||||
if (yCat == TypeCategory::Character) {
|
||||
return std::make_pair(TypeCategory::Character, maxKind);
|
||||
} else {
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
case TypeCategory::Logical:
|
||||
if (yCat == TypeCategory::Logical) {
|
||||
return std::make_pair(TypeCategory::Logical, maxKind);
|
||||
} else {
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
|
||||
// Accumulate floating-point results in (at least) double precision
|
||||
|
||||
@@ -112,7 +112,7 @@ RT_API_ATTRS TypeCode::TypeCode(TypeCategory f, int kind) {
|
||||
}
|
||||
}
|
||||
|
||||
RT_API_ATTRS std::optional<std::pair<TypeCategory, int>>
|
||||
RT_API_ATTRS Fortran::common::optional<std::pair<TypeCategory, int>>
|
||||
TypeCode::GetCategoryAndKind() const {
|
||||
switch (raw_) {
|
||||
case CFI_type_signed_char:
|
||||
@@ -204,7 +204,7 @@ TypeCode::GetCategoryAndKind() const {
|
||||
case CFI_type_char32_t:
|
||||
return std::make_pair(TypeCategory::Character, 4);
|
||||
default:
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Fortran::runtime::typeInfo {
|
||||
|
||||
RT_OFFLOAD_API_GROUP_BEGIN
|
||||
|
||||
RT_API_ATTRS std::optional<TypeParameterValue> Value::GetValue(
|
||||
RT_API_ATTRS Fortran::common::optional<TypeParameterValue> Value::GetValue(
|
||||
const Descriptor *descriptor) const {
|
||||
switch (genre_) {
|
||||
case Genre::Explicit:
|
||||
@@ -26,9 +26,9 @@ RT_API_ATTRS std::optional<TypeParameterValue> Value::GetValue(
|
||||
return addendum->LenParameterValue(value_);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
default:
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
#include "terminator.h"
|
||||
#include "flang/Common/Fortran.h"
|
||||
#include "flang/Common/bit-population-count.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Runtime/descriptor.h"
|
||||
#include <cinttypes>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace Fortran::runtime::typeInfo {
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
LenParameter = 3
|
||||
};
|
||||
RT_API_ATTRS Genre genre() const { return genre_; }
|
||||
RT_API_ATTRS std::optional<TypeParameterValue> GetValue(
|
||||
RT_API_ATTRS Fortran::common::optional<TypeParameterValue> GetValue(
|
||||
const Descriptor *) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "unit-map.h"
|
||||
#include "flang/Common/optional.h"
|
||||
|
||||
namespace Fortran::runtime::io {
|
||||
|
||||
@@ -29,7 +30,7 @@ void UnitMap::Initialize() {
|
||||
ExternalFileUnit &UnitMap::NewUnit(const Terminator &terminator) {
|
||||
CriticalSection critical{lock_};
|
||||
Initialize();
|
||||
std::optional<int> n{freeNewUnits_.PopValue()};
|
||||
Fortran::common::optional<int> n{freeNewUnits_.PopValue()};
|
||||
if (!n) {
|
||||
n = emergencyNewUnit_++;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ ExternalFileUnit *ExternalFileUnit::LookUpOrCreate(
|
||||
}
|
||||
|
||||
ExternalFileUnit *ExternalFileUnit::LookUpOrCreateAnonymous(int unit,
|
||||
Direction dir, std::optional<bool> isUnformatted,
|
||||
Direction dir, Fortran::common::optional<bool> isUnformatted,
|
||||
const Terminator &terminator) {
|
||||
// Make sure that the returned anonymous unit has been opened
|
||||
// not just created in the unitMap.
|
||||
@@ -95,9 +95,10 @@ ExternalFileUnit &ExternalFileUnit::NewUnit(
|
||||
return unit;
|
||||
}
|
||||
|
||||
bool ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
|
||||
std::optional<Action> action, Position position, OwningPtr<char> &&newPath,
|
||||
std::size_t newPathLength, Convert convert, IoErrorHandler &handler) {
|
||||
bool ExternalFileUnit::OpenUnit(Fortran::common::optional<OpenStatus> status,
|
||||
Fortran::common::optional<Action> action, Position position,
|
||||
OwningPtr<char> &&newPath, std::size_t newPathLength, Convert convert,
|
||||
IoErrorHandler &handler) {
|
||||
if (convert == Convert::Unknown) {
|
||||
convert = executionEnvironment.conversion;
|
||||
}
|
||||
@@ -176,9 +177,10 @@ bool ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
|
||||
return impliedClose;
|
||||
}
|
||||
|
||||
void ExternalFileUnit::OpenAnonymousUnit(std::optional<OpenStatus> status,
|
||||
std::optional<Action> action, Position position, Convert convert,
|
||||
IoErrorHandler &handler) {
|
||||
void ExternalFileUnit::OpenAnonymousUnit(
|
||||
Fortran::common::optional<OpenStatus> status,
|
||||
Fortran::common::optional<Action> action, Position position,
|
||||
Convert convert, IoErrorHandler &handler) {
|
||||
// I/O to an unconnected unit reads/creates a local file, e.g. fort.7
|
||||
std::size_t pathMaxLen{32};
|
||||
auto path{SizedNew<char>{handler}(pathMaxLen)};
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
#include "lock.h"
|
||||
#include "terminator.h"
|
||||
#include "flang/Common/constexpr-bitset.h"
|
||||
#include "flang/Common/optional.h"
|
||||
#include "flang/Runtime/memory.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
|
||||
namespace Fortran::runtime::io {
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
static ExternalFileUnit *LookUpOrCreate(
|
||||
int unit, const Terminator &, bool &wasExtant);
|
||||
static ExternalFileUnit *LookUpOrCreateAnonymous(int unit, Direction,
|
||||
std::optional<bool> isUnformatted, const Terminator &);
|
||||
Fortran::common::optional<bool> isUnformatted, const Terminator &);
|
||||
static ExternalFileUnit *LookUp(const char *path, std::size_t pathLen);
|
||||
static ExternalFileUnit &CreateNew(int unit, const Terminator &);
|
||||
static ExternalFileUnit *LookUpForClose(int unit);
|
||||
@@ -64,11 +64,11 @@ public:
|
||||
static void FlushAll(IoErrorHandler &);
|
||||
|
||||
// Returns true if an existing unit was closed
|
||||
bool OpenUnit(std::optional<OpenStatus>, std::optional<Action>, Position,
|
||||
OwningPtr<char> &&path, std::size_t pathLength, Convert,
|
||||
IoErrorHandler &);
|
||||
void OpenAnonymousUnit(std::optional<OpenStatus>, std::optional<Action>,
|
||||
Position, Convert, IoErrorHandler &);
|
||||
bool OpenUnit(Fortran::common::optional<OpenStatus>,
|
||||
Fortran::common::optional<Action>, Position, OwningPtr<char> &&path,
|
||||
std::size_t pathLength, Convert, IoErrorHandler &);
|
||||
void OpenAnonymousUnit(Fortran::common::optional<OpenStatus>,
|
||||
Fortran::common::optional<Action>, Position, Convert, IoErrorHandler &);
|
||||
void CloseUnit(CloseStatus, IoErrorHandler &);
|
||||
void DestroyClosed();
|
||||
|
||||
@@ -169,7 +169,7 @@ private:
|
||||
u_;
|
||||
|
||||
// Points to the active alternative (if any) in u_ for use as a Cookie
|
||||
std::optional<IoStatementState> io_;
|
||||
Fortran::common::optional<IoStatementState> io_;
|
||||
|
||||
// A stack of child I/O pseudo-units for defined I/O that have this
|
||||
// unit number.
|
||||
@@ -211,7 +211,7 @@ private:
|
||||
ChildUnformattedIoStatementState<Direction::Input>, InquireUnitState,
|
||||
ErroneousIoStatementState, ExternalMiscIoStatementState>
|
||||
u_;
|
||||
std::optional<IoStatementState> io_;
|
||||
Fortran::common::optional<IoStatementState> io_;
|
||||
};
|
||||
|
||||
} // namespace Fortran::runtime::io
|
||||
|
||||
@@ -40,7 +40,7 @@ const std::uint8_t UTF8FirstByteTable[256]{
|
||||
// clang-format on
|
||||
|
||||
// Non-minimal encodings are accepted.
|
||||
std::optional<char32_t> DecodeUTF8(const char *p0) {
|
||||
Fortran::common::optional<char32_t> DecodeUTF8(const char *p0) {
|
||||
const std::uint8_t *p{reinterpret_cast<const std::uint8_t *>(p0)};
|
||||
std::size_t bytes{MeasureUTF8Bytes(*p0)};
|
||||
if (bytes == 1) {
|
||||
@@ -50,7 +50,7 @@ std::optional<char32_t> DecodeUTF8(const char *p0) {
|
||||
for (std::size_t j{1}; j < bytes; ++j) {
|
||||
std::uint8_t next{p[j]};
|
||||
if (next < 0x80 || next > 0xbf) {
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
result = (result << 6) | (next & 0x3f);
|
||||
}
|
||||
@@ -58,7 +58,7 @@ std::optional<char32_t> DecodeUTF8(const char *p0) {
|
||||
return static_cast<char32_t>(result);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
return Fortran::common::nullopt;
|
||||
}
|
||||
|
||||
std::size_t EncodeUTF8(char *p0, char32_t ucs) {
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
#ifndef FORTRAN_RUNTIME_UTF_H_
|
||||
#define FORTRAN_RUNTIME_UTF_H_
|
||||
|
||||
#include "flang/Common/optional.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
namespace Fortran::runtime {
|
||||
|
||||
@@ -58,7 +58,7 @@ static constexpr std::size_t maxUTF8Bytes{7};
|
||||
|
||||
// Ensure that all bytes are present in sequence in the input buffer
|
||||
// before calling; use MeasureUTF8Bytes(first byte) to count them.
|
||||
std::optional<char32_t> DecodeUTF8(const char *);
|
||||
Fortran::common::optional<char32_t> DecodeUTF8(const char *);
|
||||
|
||||
// Ensure that at least maxUTF8Bytes remain in the output
|
||||
// buffer before calling.
|
||||
|
||||
Reference in New Issue
Block a user