Warning: This file is not a C or C++ file. It does not have highlighting.
1 | //===-- include/flang/Evaluate/logical.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_LOGICAL_H_ |
10 | #define FORTRAN_EVALUATE_LOGICAL_H_ |
11 | |
12 | #include "integer.h" |
13 | #include <cinttypes> |
14 | |
15 | namespace Fortran::evaluate::value { |
16 | |
17 | template <int BITS, bool IS_LIKE_C = true> class Logical { |
18 | public: |
19 | static constexpr int bits{BITS}; |
20 | using Word = Integer<bits>; |
21 | |
22 | // Module ISO_C_BINDING kind C_BOOL is LOGICAL(KIND=1) and must have |
23 | // C's bit representation (.TRUE. -> 1, .FALSE. -> 0). |
24 | static constexpr bool IsLikeC{BITS <= 8 || IS_LIKE_C}; |
25 | |
26 | constexpr Logical() {} // .FALSE. |
27 | template <int B, bool C> |
28 | constexpr Logical(Logical<B, C> x) : word_{Represent(x.IsTrue())} {} |
29 | constexpr Logical(bool truth) : word_{Represent(truth)} {} |
30 | // A raw word, for DATA initialization |
31 | constexpr Logical(Word &&w) : word_{std::move(w)} {} |
32 | |
33 | template <int B, bool C> constexpr Logical &operator=(Logical<B, C> x) { |
34 | word_ = Represent(x.IsTrue()); |
35 | return *this; |
36 | } |
37 | |
38 | Word word() const { return word_; } |
39 | bool IsCanonical() const { |
40 | return word_ == canonicalFalse || word_ == canonicalTrue; |
41 | } |
42 | |
43 | // Fortran actually has only .EQV. & .NEQV. relational operations |
44 | // for LOGICAL, but this template class supports more so that |
45 | // it can be used with the STL for sorting and as a key type for |
46 | // std::set<> & std::map<>. |
47 | template <int B, bool C> |
48 | constexpr bool operator<(const Logical<B, C> &that) const { |
49 | return !IsTrue() && that.IsTrue(); |
50 | } |
51 | template <int B, bool C> |
52 | constexpr bool operator<=(const Logical<B, C> &) const { |
53 | return !IsTrue(); |
54 | } |
55 | template <int B, bool C> |
56 | constexpr bool operator==(const Logical<B, C> &that) const { |
57 | return IsTrue() == that.IsTrue(); |
58 | } |
59 | template <int B, bool C> |
60 | constexpr bool operator!=(const Logical<B, C> &that) const { |
61 | return IsTrue() != that.IsTrue(); |
62 | } |
63 | template <int B, bool C> |
64 | constexpr bool operator>=(const Logical<B, C> &) const { |
65 | return IsTrue(); |
66 | } |
67 | template <int B, bool C> |
68 | constexpr bool operator>(const Logical<B, C> &that) const { |
69 | return IsTrue() && !that.IsTrue(); |
70 | } |
71 | |
72 | constexpr bool IsTrue() const { |
73 | if constexpr (IsLikeC) { |
74 | return !word_.IsZero(); |
75 | } else { |
76 | return word_.BTEST(0); |
77 | } |
78 | } |
79 | |
80 | constexpr Logical NOT() const { return {word_.IEOR(canonicalTrue)}; } |
81 | |
82 | constexpr Logical AND(const Logical &that) const { |
83 | return {word_.IAND(that.word_)}; |
84 | } |
85 | |
86 | constexpr Logical OR(const Logical &that) const { |
87 | return {word_.IOR(that.word_)}; |
88 | } |
89 | |
90 | constexpr Logical EQV(const Logical &that) const { return NEQV(that).NOT(); } |
91 | |
92 | constexpr Logical NEQV(const Logical &that) const { |
93 | return {word_.IEOR(that.word_)}; |
94 | } |
95 | |
96 | private: |
97 | static constexpr Word canonicalTrue{IsLikeC ? 1 : -std::uint64_t{1}}; |
98 | static constexpr Word canonicalFalse{0}; |
99 | static constexpr Word Represent(bool x) { |
100 | return x ? canonicalTrue : canonicalFalse; |
101 | } |
102 | Word word_; |
103 | }; |
104 | |
105 | extern template class Logical<8>; |
106 | extern template class Logical<16>; |
107 | extern template class Logical<32>; |
108 | extern template class Logical<64>; |
109 | } // namespace Fortran::evaluate::value |
110 | #endif // FORTRAN_EVALUATE_LOGICAL_H_ |
111 |
Warning: This file is not a C or C++ file. It does not have highlighting.