FLANG

logical.h
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
21 // Module ISO_C_BINDING kind C_BOOL is LOGICAL(KIND=1) and must have
22 // C's bit representation (.TRUE. -> 1, .FALSE. -> 0).
23 static constexpr bool IsLikeC{BITS <= 8 || IS_LIKE_C};
24
25 constexpr Logical() {} // .FALSE.
26 template <int B, bool C>
27 constexpr Logical(Logical<B, C> x) : word_{Represent(x.IsTrue())} {}
28 constexpr Logical(bool truth) : word_{Represent(truth)} {}
29
30 template <int B, bool C> constexpr Logical &operator=(Logical<B, C> x) {
31 word_ = Represent(x.IsTrue());
32 return *this;
33 }
34
35 // Fortran actually has only .EQV. & .NEQV. relational operations
36 // for LOGICAL, but this template class supports more so that
37 // it can be used with the STL for sorting and as a key type for
38 // std::set<> & std::map<>.
39 template <int B, bool C>
40 constexpr bool operator<(const Logical<B, C> &that) const {
41 return !IsTrue() && that.IsTrue();
42 }
43 template <int B, bool C>
44 constexpr bool operator<=(const Logical<B, C> &) const {
45 return !IsTrue();
46 }
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> &that) const {
53 return IsTrue() != that.IsTrue();
54 }
55 template <int B, bool C>
56 constexpr bool operator>=(const Logical<B, C> &) const {
57 return 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
64 constexpr bool IsTrue() const {
65 if constexpr (IsLikeC) {
66 return !word_.IsZero();
67 } else {
68 return word_.BTEST(0);
69 }
70 }
71
72 constexpr Logical NOT() const { return {word_.IEOR(canonicalTrue)}; }
73
74 constexpr Logical AND(const Logical &that) const {
75 return {word_.IAND(that.word_)};
76 }
77
78 constexpr Logical OR(const Logical &that) const {
79 return {word_.IOR(that.word_)};
80 }
81
82 constexpr Logical EQV(const Logical &that) const { return NEQV(that).NOT(); }
83
84 constexpr Logical NEQV(const Logical &that) const {
85 return {word_.IEOR(that.word_)};
86 }
87
88 private:
89 using Word = Integer<bits>;
90 static constexpr Word canonicalTrue{IsLikeC ? -std::uint64_t{1} : 1};
91 static constexpr Word canonicalFalse{0};
92 static constexpr Word Represent(bool x) {
93 return x ? canonicalTrue : canonicalFalse;
94 }
95 constexpr Logical(const Word &w) : word_{w} {}
96 Word word_;
97 };
98
99 extern template class Logical<8>;
100 extern template class Logical<16>;
101 extern template class Logical<32>;
102 extern template class Logical<64>;
103 } // namespace Fortran::evaluate::value
104 #endif // FORTRAN_EVALUATE_LOGICAL_H_
Fortran::evaluate::value::Logical
Definition: logical.h:17