9#ifndef FORTRAN_EVALUATE_HOST_H_
10#define FORTRAN_EVALUATE_HOST_H_
21#include "quadmath_wrapper.h"
22#include "flang/Common/float128.h"
24#include "flang/Evaluate/type.h"
25#include "flang/Evaluate/typekind-traits.h"
40 bool hasSubnormalFlushingHardwareControl()
const {
41 return hasSubnormalFlushingHardwareControl_;
43 void SetFlag(RealFlag flag) { flags_.set(flag); }
44 bool hardwareFlagsAreReliable()
const {
return hardwareFlagsAreReliable_; }
47 std::fenv_t originalFenv_;
49 unsigned int originalMxcsr;
52 bool hasSubnormalFlushingHardwareControl_{
false};
53 bool hardwareFlagsAreReliable_{
true};
62template <
typename FTN_T>
using HostType =
typename HostTypeHelper<FTN_T>::Type;
64template <
typename... T>
constexpr inline bool HostTypeExists() {
73template <
typename FTN_T>
74inline constexpr Scalar<FTN_T> CastHostToFortran(
const HostType<FTN_T> &x) {
75 static_assert(HostTypeExists<FTN_T>());
76 if constexpr (FTN_T::category == TypeCategory::Complex &&
77 Scalar<FTN_T>::bytesStored(FTN_T::kind) !=
sizeof(HostType<FTN_T>)) {
80 return Scalar<FTN_T>{CastHostToFortran<typename FTN_T::Part>(std::real(x)),
81 CastHostToFortran<typename FTN_T::Part>(std::imag(x))};
84 Scalar<FTN_T>::bytesStored(FTN_T::kind) ==
sizeof(HostType<FTN_T>));
85 return Scalar<FTN_T>::FromRawBytes(FTN_T::kind, &x,
sizeof(x));
90template <
typename FTN_T>
91inline constexpr HostType<FTN_T> CastFortranToHost(
const Scalar<FTN_T> &x) {
92 static_assert(HostTypeExists<FTN_T>());
93 if constexpr (FTN_T::category == TypeCategory::Complex &&
94 Scalar<FTN_T>::bytesStored(FTN_T::kind) !=
sizeof(HostType<FTN_T>)) {
95 using FortranPartType =
typename FTN_T::Part;
96 return HostType<FTN_T>{CastFortranToHost<FortranPartType>(x.REAL()),
97 CastFortranToHost<FortranPartType>(x.AIMAG())};
100 Scalar<FTN_T>::bytesStored(FTN_T::kind) ==
sizeof(HostType<FTN_T>));
101 HostType<FTN_T> result;
102 x.StoreRawBytes(&result,
sizeof(result));
108 using Type = std::int8_t;
112 using Type = std::int16_t;
116 using Type = std::int32_t;
120 using Type = std::int64_t;
124#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__)
125 using Type = __int128_t;
136 TypeKind<TypeCategory::Real, common::RealKindForPrecision(24)>> {
138 using Type = std::conditional_t<
sizeof(float) == 4 &&
145 TypeKind<TypeCategory::Real, common::RealKindForPrecision(53)>> {
147 using Type = std::conditional_t<
sizeof(double) == 8 &&
154 TypeKind<TypeCategory::Real, common::RealKindForPrecision(64)>> {
156 using Type = std::conditional_t<
sizeof(
long double) >= 10 &&
165 using Type = __float128;
170 using Type = std::conditional_t<
sizeof(
long double) == 16 &&
180 using Type = std::conditional_t<HostTypeExists<RealT>(),
187 using Type = __complex128;
193 using Type = std::conditional_t<KIND <= 8, std::uint8_t, UnsupportedType>;
204template <
typename T,
typename... TT>
206 static constexpr int value{common::TypeIndex<T, TT...>};
210 using HostTypeMapping =
211 common::MapTemplate<HostType, AllIntrinsicKindTypes, std::tuple>;
212 static constexpr int index{
216 using Type = std::conditional_t<index >= 0,
217 std::tuple_element_t<(index >= 0) ? index : 0, AllIntrinsicKindTypes>,
221template <
typename HOST_T>
222using FortranType =
typename FortranTypeHelper<HOST_T>::Type;
224template <
typename... HT>
constexpr inline bool FortranTypeExists() {
225 return (... && (!std::is_same_v<FortranType<HT>,
UnknownType>));
typename std::conditional_t< detail::numeric_limits< T >::is_specialized && !std::numeric_limits< T >::is_specialized, detail::numeric_limits< T >, std::numeric_limits< T > > numeric_limits
Definition numeric-limits.h:118
Definition typekind-traits.h:46