FLANG
typekind-traits.h
1//===-- include/flang/Evaluate/typekind-traits.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 FORTRAN_EVALUATE_TYPEKINDTRAITS_H_
10#define FORTRAN_EVALUATE_TYPEKINDTRAITS_H_
11
12#include "flang/Common/Fortran-consts.h"
13#include "flang/Evaluate/common.h"
14#include "flang/Evaluate/complex-value.h"
15#include "flang/Evaluate/integer-value.h"
16#include "flang/Evaluate/logical-value.h"
17#include "flang/Evaluate/real-value.h"
18#include "flang/Evaluate/type.h"
19
20namespace Fortran::evaluate::value {
21class CharacterValue;
22class IntegerValue;
23class ComplexValue;
24} // namespace Fortran::evaluate::value
25
26namespace Fortran::evaluate {
27
46template <common::TypeCategory CAT, int KIND> struct TypeKind;
47
48template <int KIND> struct TypeKind<common::TypeCategory::Integer, KIND> {
49 static constexpr common::TypeCategory category{common::TypeCategory::Integer};
50 static constexpr int kind{KIND};
51 static constexpr int bits{value::IntegerValue::bits(KIND)};
52 static constexpr int bytesStored{value::IntegerValue::bytesStored(kind)};
53 using UnsignedT = common::HostUnsignedIntType<bits>;
54 using SignedT = common::HostSignedIntType<bits>;
55 using HostT = SignedT;
56 using Scalar = value::IntegerValue;
58 static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
59};
60
61using IntegerKindTypes = std::tuple<TypeKind<TypeCategory::Integer, 1>,
64
65template <int KIND> struct TypeKind<common::TypeCategory::Unsigned, KIND> {
66 static constexpr common::TypeCategory category{
67 common::TypeCategory::Unsigned};
68 static constexpr int kind{KIND};
69 static constexpr int bits{value::IntegerValue::bits(KIND)};
70 static constexpr int bytesStored{value::IntegerValue::bytesStored(kind)};
71 using UnsignedT = common::HostUnsignedIntType<bits>;
72 using SignedT = common::HostSignedIntType<bits>;
73 using HostT = UnsignedT;
74 using Scalar = value::IntegerValue;
76 static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
77};
78
79using UnsignedKindTypes = std::tuple<TypeKind<TypeCategory::Unsigned, 1>,
82
83template <int KIND> struct TypeKind<common::TypeCategory::Logical, KIND> {
84 static constexpr common::TypeCategory category{common::TypeCategory::Logical};
85 static constexpr int kind{KIND};
86 static constexpr int bits{value::LogicalValue::bits(KIND)};
87 static constexpr int bytesStored{value::LogicalValue::bytesStored(kind)};
88 using UnsignedT = common::HostUnsignedIntType<bits>;
89 using SignedT = common::HostSignedIntType<bits>;
90 using HostT = UnsignedT;
91 using Scalar = value::LogicalValue;
93 static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
94};
95
96using LogicalKindTypes = std::tuple<TypeKind<TypeCategory::Logical, 1>,
99
100namespace detail {
101// Only REAL(4) and REAL(8) have a portable native host arithmetic type
102// (float and double, respectively); every other kind maps to void.
103template <int BITS> struct RealHostType {
104 using type = void;
105};
106template <> struct RealHostType<32> {
107 using type = float;
108};
109template <> struct RealHostType<64> {
110 using type = double;
111};
112} // namespace detail
113
114template <int KIND> struct TypeKind<common::TypeCategory::Real, KIND> {
115 static constexpr common::TypeCategory category{common::TypeCategory::Real};
116 static constexpr int kind{KIND};
117 static constexpr int bits{value::RealValue::bits(KIND)};
118 static constexpr int bytesStored{value::RealValue::bytesStored(kind)};
119 using UnsignedT = common::HostUnsignedIntType<bits>;
120 using SignedT = common::HostSignedIntType<bits>;
121 using HostT = typename detail::RealHostType<bits>::type;
122 using Scalar = value::RealValue;
123 using FortranType = Fortran::evaluate::Type<common::TypeCategory::Real>;
124 static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
125};
126
127using RealKindTypes =
128 std::tuple<TypeKind<TypeCategory::Real, 2>, TypeKind<TypeCategory::Real, 3>,
131
132template <int KIND> struct TypeKind<common::TypeCategory::Complex, KIND> {
133 static constexpr common::TypeCategory category{common::TypeCategory::Complex};
134 static constexpr int kind{KIND};
135 static constexpr int bytesStored{value::ComplexValue::bytesStored(kind)};
137 using Scalar = value::ComplexValue;
138 static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
140};
141
142using ComplexKindTypes = std::tuple<TypeKind<TypeCategory::Complex, 2>,
146
147template <> struct TypeKind<common::TypeCategory::Character, 1> {
148 static constexpr common::TypeCategory category{
149 common::TypeCategory::Character};
150 static constexpr int kind{1};
151 using CharT = char;
152 using StringT = std::basic_string<CharT>;
153 using HostT = void;
154 using Scalar = value::CharacterValue;
156 static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
157};
158
159template <> struct TypeKind<common::TypeCategory::Character, 2> {
160 static constexpr common::TypeCategory category{
161 common::TypeCategory::Character};
162 static constexpr int kind{2};
163 using CharT = char16_t;
164 using StringT = std::basic_string<CharT>;
165 using HostT = void;
166 using Scalar = value::CharacterValue;
168 static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
169};
170
171template <> struct TypeKind<common::TypeCategory::Character, 4> {
172 static constexpr common::TypeCategory category{
173 common::TypeCategory::Character};
174 static constexpr int kind{4};
175 using CharT = char32_t;
176 using StringT = std::basic_string<CharT>;
177 using HostT = void;
178 using Scalar = value::CharacterValue;
180 static constexpr DynamicType GetType() { return DynamicType{category, kind}; }
181};
182
183using CharacterKindTypes = std::tuple<TypeKind<TypeCategory::Character, 1>,
185
186using AllIntrinsicKindTypes =
187 common::CombineTuples<IntegerKindTypes, UnsignedKindTypes, LogicalKindTypes,
188 RealKindTypes, ComplexKindTypes, CharacterKindTypes>;
189
190} // namespace Fortran::evaluate
191#endif // FORTRAN_EVALUATE_TYPEKINDTRAITS_H_
Definition type.h:73
Definition type.h:56
Definition character-value.h:34
Definition complex-value.h:28
std::size_t bytesStored() const
Number of bytes accessed by FromRawBytes/StoreRawBytes.
Definition complex-value.h:87
Definition integer-value.h:34
std::size_t bytesStored() const
Number of bytes accessed by FromRawBytes/StoreRawBytes.
Definition integer-value.h:101
Definition logical-value.h:25
std::size_t bytesStored() const
Number of bytes accessed by FromRawBytes/StoreRawBytes.
Definition logical-value.h:69
std::size_t bytesStored() const
Number of bytes accessed by FromRawBytes/StoreRawBytes.
Definition real-value.h:84
Definition bit-population-count.h:20
Definition call.h:34
Definition typekind-traits.h:46
Definition typekind-traits.h:103