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
15namespace Fortran::evaluate::value {
16
17template <int BITS, bool IS_LIKE_C = true> class Logical {
18public:
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
96private:
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
105extern template class Logical<8>;
106extern template class Logical<16>;
107extern template class Logical<32>;
108extern 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.

source code of flang/include/flang/Evaluate/logical.h