1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#pragma once
#include <cstdint>
namespace lbug {
namespace function {
/**
* The boolean operators (AND, OR, XOR, NOT) works a little differently from other operators. While
* other operators can operate on only non null operands, boolean operators can operate even with
* null operands in certain cases, for instance, Null OR True = True. Hence, the result value of
* the boolean operator can be True, False or Null. To accommodate for this, the dataType of
* result is uint8_t (that can have more than 2 values) rather than bool. In case, the result is
* computed to be Null based on the operands, we set result = NULL_BOOL, which should rightly be
* interpreted by operator executors as NULL and not as True.
* */
/**
* IMPORTANT: Not to be used outside the context of boolean operators.
* */
const uint8_t NULL_BOOL = 2;
/**
* AND operator Truth table:
*
* left isLeftNull right isRightNull result
* ------ ------------ ------- ------------- --------
* T F T F 1
* T F F F 0
* F F T F 0
* F F F F 0
* - T T F 2
* - T F F 0
* T F - T 2
* F F - T 0
* - T - T 2
* */
struct And {
static inline void operation(bool left, bool right, uint8_t& result, bool isLeftNull,
bool isRightNull) {
if ((!left && !isLeftNull) || (!right && !isRightNull)) {
result = false;
} else if (isLeftNull || isRightNull) {
result = NULL_BOOL;
} else {
result = true;
}
}
};
/**
* OR operator Truth table:
*
* left isLeftNull right isRightNull result
* ------ ------------ ------- ------------- --------
* T F T F 1
* T F F F 1
* F F T F 1
* F F F F 0
* - T T F 1
* - T F F 2
* T F - T 1
* F F - T 2
* - T - T 2
* */
struct Or {
static inline void operation(bool left, bool right, uint8_t& result, bool isLeftNull,
bool isRightNull) {
if ((left && !isLeftNull) || (right && !isRightNull)) {
result = true;
} else if (isLeftNull || isRightNull) {
result = NULL_BOOL;
} else {
result = false;
}
}
};
/**
* XOR operator Truth table:
*
* left isLeftNull right isRightNull result
* ------ ------------ ------- ------------- --------
* T F T F 0
* T F F F 1
* F F T F 1
* F F F F 0
* - T T F 2
* - T F F 2
* T F - T 2
* F F - T 2
* - T - T 2
* */
struct Xor {
static inline void operation(bool left, bool right, uint8_t& result, bool isLeftNull,
bool isRightNull) {
if (isLeftNull || isRightNull) {
result = NULL_BOOL;
} else {
result = left ^ right;
}
}
};
/**
* NOT operator Truth table:
*
* operand isNull right
* --------- ------------ -------
* T F 0
* F F 1
* - T 2
* */
struct Not {
static inline void operation(bool operand, bool isNull, uint8_t& result) {
result = isNull ? NULL_BOOL : !operand;
}
};
} // namespace function
} // namespace lbug