Warning: This file is not a C or C++ file. It does not have highlighting.
1 | //===-- include/flang/Evaluate/complex.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_COMPLEX_H_ |
10 | #define FORTRAN_EVALUATE_COMPLEX_H_ |
11 | |
12 | #include "formatting.h" |
13 | #include "real.h" |
14 | #include <string> |
15 | |
16 | namespace llvm { |
17 | class raw_ostream; |
18 | } |
19 | |
20 | namespace Fortran::evaluate::value { |
21 | |
22 | template <typename REAL_TYPE> class Complex { |
23 | public: |
24 | using Part = REAL_TYPE; |
25 | static constexpr int bits{2 * Part::bits}; |
26 | |
27 | constexpr Complex() {} // (+0.0, +0.0) |
28 | constexpr Complex(const Complex &) = default; |
29 | constexpr Complex(const Part &r, const Part &i) : re_{r}, im_{i} {} |
30 | explicit constexpr Complex(const Part &r) : re_{r} {} |
31 | constexpr Complex &operator=(const Complex &) = default; |
32 | constexpr Complex &operator=(Complex &&) = default; |
33 | |
34 | constexpr bool operator==(const Complex &that) const { |
35 | return re_ == that.re_ && im_ == that.im_; |
36 | } |
37 | |
38 | constexpr const Part &REAL() const { return re_; } |
39 | constexpr const Part &AIMAG() const { return im_; } |
40 | constexpr Complex CONJG() const { return {re_, im_.Negate()}; } |
41 | constexpr Complex Negate() const { return {re_.Negate(), im_.Negate()}; } |
42 | |
43 | constexpr bool Equals(const Complex &that) const { |
44 | return re_.Compare(that.re_) == Relation::Equal && |
45 | im_.Compare(that.im_) == Relation::Equal; |
46 | } |
47 | |
48 | constexpr bool IsZero() const { return re_.IsZero() || im_.IsZero(); } |
49 | |
50 | constexpr bool IsInfinite() const { |
51 | return re_.IsInfinite() || im_.IsInfinite(); |
52 | } |
53 | |
54 | constexpr bool IsNotANumber() const { |
55 | return re_.IsNotANumber() || im_.IsNotANumber(); |
56 | } |
57 | |
58 | constexpr bool IsSignalingNaN() const { |
59 | return re_.IsSignalingNaN() || im_.IsSignalingNaN(); |
60 | } |
61 | |
62 | template <typename INT> |
63 | static ValueWithRealFlags<Complex> FromInteger(const INT &n, |
64 | Rounding rounding = TargetCharacteristics::defaultRounding) { |
65 | ValueWithRealFlags<Complex> result; |
66 | result.value.re_ = |
67 | Part::FromInteger(n, rounding).AccumulateFlags(result.flags); |
68 | return result; |
69 | } |
70 | |
71 | ValueWithRealFlags<Complex> Add(const Complex &, |
72 | Rounding rounding = TargetCharacteristics::defaultRounding) const; |
73 | ValueWithRealFlags<Complex> Subtract(const Complex &, |
74 | Rounding rounding = TargetCharacteristics::defaultRounding) const; |
75 | ValueWithRealFlags<Complex> Multiply(const Complex &, |
76 | Rounding rounding = TargetCharacteristics::defaultRounding) const; |
77 | ValueWithRealFlags<Complex> Divide(const Complex &, |
78 | Rounding rounding = TargetCharacteristics::defaultRounding) const; |
79 | |
80 | // ABS/CABS = HYPOT(re_, imag_) = SQRT(re_**2 + im_**2) |
81 | ValueWithRealFlags<Part> ABS( |
82 | Rounding rounding = TargetCharacteristics::defaultRounding) const { |
83 | return re_.HYPOT(im_, rounding); |
84 | } |
85 | |
86 | constexpr Complex FlushSubnormalToZero() const { |
87 | return {re_.FlushSubnormalToZero(), im_.FlushSubnormalToZero()}; |
88 | } |
89 | |
90 | static constexpr Complex NotANumber() { |
91 | return {Part::NotANumber(), Part::NotANumber()}; |
92 | } |
93 | |
94 | std::string DumpHexadecimal() const; |
95 | llvm::raw_ostream &AsFortran(llvm::raw_ostream &, int kind) const; |
96 | |
97 | // TODO: unit testing |
98 | |
99 | private: |
100 | Part re_, im_; |
101 | }; |
102 | |
103 | extern template class Complex<Real<Integer<16>, 11>>; |
104 | extern template class Complex<Real<Integer<16>, 8>>; |
105 | extern template class Complex<Real<Integer<32>, 24>>; |
106 | extern template class Complex<Real<Integer<64>, 53>>; |
107 | extern template class Complex<Real<X87IntegerContainer, 64>>; |
108 | extern template class Complex<Real<Integer<128>, 113>>; |
109 | } // namespace Fortran::evaluate::value |
110 | #endif // FORTRAN_EVALUATE_COMPLEX_H_ |
111 |
Warning: This file is not a C or C++ file. It does not have highlighting.