FLANG
logical-value.h
1//===-- include/flang/Evaluate/logical-value.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_VALUE_H_
10#define FORTRAN_EVALUATE_LOGICAL_VALUE_H_
11
12#include "integer-value.h"
13#include "llvm/Support/Compiler.h"
14#include <utility>
15
16namespace Fortran::evaluate::value {
17
25class LogicalValue {
26public:
27 using Word = IntegerValue;
28
29 LogicalValue() {}
30 LogicalValue(const LogicalValue &) = default;
31 LogicalValue(LogicalValue &&) = default;
32 LogicalValue &operator=(const LogicalValue &) = default;
33 LogicalValue &operator=(LogicalValue &&) = default;
34
35 LogicalValue(int kind, const LogicalValue &v) : LogicalValue{v} {
36 CHECK(kind == v.kind());
37 }
38
39 LogicalValue(int kind, LogicalValue &&v) : LogicalValue{std::move(v)} {
40 CHECK(kind == v.kind());
41 }
42
43 LogicalValue(int kind, bool truth) : word_(Represent(kind, truth)) {}
44
45 LogicalValue(int kind, const Word &w) : word_(kind, w) {}
46
50 static LogicalValue Zero(int kind) { return LogicalValue{kind, false}; }
51
52 void print(llvm::raw_ostream &os) const;
53
54#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
55 LLVM_DUMP_METHOD void dump() const;
56#endif
57
60 bool IsNull() const { return word_.IsNull(); }
61
63 int kind() const { return word_.kind(); }
64
65 int bits() const { return bits(kind()); }
66 static constexpr int bits(int kind) { return Word::bits(kind); }
67
69 std::size_t bytesStored() const { return bytesStored(kind()); }
70 static constexpr std::size_t bytesStored(int kind) {
71 return Word::bytesStored(kind);
72 }
73
74 Word word() const { return word_; }
75
76 bool IsCanonical() const {
77 const int kind{this->kind()};
78 return word_ == canonicalFalse(kind) || word_ == canonicalTrue(kind);
79 }
80
84 bool operator<(const LogicalValue &that) const {
85 return !IsTrue() && that.IsTrue();
86 }
87 bool operator<=(const LogicalValue &that) const { return !IsTrue(); }
88 bool operator==(const LogicalValue &that) const {
89 return IsTrue() == that.IsTrue();
90 }
91 bool operator!=(const LogicalValue &that) const {
92 return IsTrue() != that.IsTrue();
93 }
94
95 bool operator>=(const LogicalValue &that) const { return IsTrue(); }
96
97 bool operator>(const LogicalValue &that) const {
98 return IsTrue() && !that.IsTrue();
99 }
100
101 bool IsTrue() const { return !word_.IsZero(); }
102
103 LogicalValue NOT() const {
104 return FromWord(word_.IEOR(canonicalTrue(kind())));
105 }
106
107 LogicalValue AND(const LogicalValue &that) const {
108 return FromWord(word_.IAND(that.word()));
109 }
110
111 LogicalValue OR(const LogicalValue &that) const {
112 return FromWord(word_.IOR(that.word()));
113 }
114
115 LogicalValue EQV(const LogicalValue &that) const { return NEQV(that).NOT(); }
116
117 LogicalValue NEQV(const LogicalValue &that) const {
118 return FromWord(word_.IEOR(that.word()));
119 }
120
121 static LogicalValue FromRawBytes(
122 int kind, const void *raw, std::size_t expectedSize) {
123 Word w{Word::FromRawBytes(kind, raw, expectedSize)};
124 return LogicalValue{w.kind(), w};
125 }
126
127 void StoreRawBytes(void *dst, size_t size, bool *changed = nullptr) const {
128 word_.StoreRawBytes(dst, size, changed);
129 }
130
131private:
132 static Word canonicalTrue(int kind) { return Word{kind, 1}; }
133
134 static Word canonicalFalse(int kind) { return Word{kind, 0}; }
135
136 static Word Represent(int kind, bool x) {
137 return x ? canonicalTrue(kind) : canonicalFalse(kind);
138 }
139
140 static LogicalValue FromWord(const Word &w) {
141 LogicalValue v;
142 v.word_ = w;
143 return v;
144 }
145
146 static LogicalValue FromWord(Word &&w) {
147 LogicalValue v;
148 v.word_ = std::move(w);
149 return v;
150 }
151
152 Word word_;
153};
154
155} // namespace Fortran::evaluate::value
156
157namespace llvm {
159inline raw_ostream &operator<<(
160 raw_ostream &os, const Fortran::evaluate::value::LogicalValue &v) {
161 v.print(os);
162 return os;
163}
164} // namespace llvm
165
166#endif // FORTRAN_EVALUATE_LOGICAL_VALUE_H_
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
bool IsNull() const
Definition logical-value.h:60
std::size_t bytesStored() const
Number of bytes accessed by FromRawBytes/StoreRawBytes.
Definition logical-value.h:69
bool operator<(const LogicalValue &that) const
Definition logical-value.h:84
int kind() const
The kind of the value currently stored.
Definition logical-value.h:63
static LogicalValue Zero(int kind)
Definition logical-value.h:50