Skip to content

Commit 84d51ac

Browse files
committed
implements expression tree operation nodes
1 parent 411e3f6 commit 84d51ac

File tree

1 file changed

+74
-4
lines changed

1 file changed

+74
-4
lines changed

include/attwoodn/expression_tree.hpp

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <stdexcept>
4+
35
namespace attwoodn::expression_tree {
46

57
namespace op {
@@ -51,6 +53,11 @@ namespace attwoodn::expression_tree {
5153
}
5254
}
5355

56+
enum class boolean_op {
57+
AND,
58+
OR
59+
};
60+
5461
namespace node {
5562

5663
/**
@@ -64,23 +71,86 @@ namespace attwoodn::expression_tree {
6471
/**
6572
* @brief Evaluates the given object to determine if it satisfies the expressions defined in this node and all child nodes.
6673
*
67-
* @returns True if the given object satisfied the expression in this node and all the expressions of all nodes
74+
* @returns True if the given object satisfied the expression in this node and the expressions of all nodes
6875
* under this node in the expression tree;
6976
*
70-
* False if the given object did not satisfy the epression in this node and all the expressions of all
77+
* False if the given object did not satisfy the expression in this node and the expressions of all
7178
* nodes under this node in the expression tree.
7279
*/
7380
virtual bool evaluate(const Obj& obj) = 0;
7481
};
7582

7683
/**
77-
*
84+
* @brief Represents inner boolean operation nodes of the tree. These nodes contain references to a left and right
85+
* child node, as well as the boolean operation to be performed (e.g. left child AND right child, or left child OR right child).
7886
*/
7987
template<typename Obj, typename LeftChild, typename RightChild>
8088
class expression_tree_op_node : public expression_tree_node_base<Obj> {
81-
89+
public:
90+
using this_type = expression_tree_op_node<Obj, LeftChild, RightChild>;
91+
92+
expression_tree_op_node(boolean_op bool_op)
93+
: bool_op_(bool_op) {}
94+
95+
expression_tree_op_node(const expression_tree_op_node& other) {
96+
bool_op_ = other.bool_op_;
97+
delete left_;
98+
delete right_;
99+
left_ = new LeftChild(*other.left_);
100+
right_ = new RightChild(*other.right_);
101+
}
102+
103+
~expression_tree_op_node() override {
104+
delete left_;
105+
delete right_;
106+
}
107+
108+
void set_right(RightChild* r) {
109+
delete right_;
110+
right_ = new RightChild(*r);
111+
delete r;
112+
}
113+
114+
void set_left(LeftChild* l) {
115+
delete left_;
116+
left_ = new LeftChild(*l);
117+
delete l;
118+
}
119+
120+
bool evaluate(const Obj& obj) override {
121+
if(!left_ || !right_) {
122+
throw std::runtime_error("expression_tree_op_node has a missing child node");
123+
}
124+
125+
switch(bool_op_) {
126+
case boolean_op::AND: {
127+
return left_->evaluate(obj) && right_->evaluate(obj);
128+
}
129+
130+
case boolean_op::OR: {
131+
return left_->evaluate(obj) || right_->evaluate(obj);
132+
}
133+
134+
default: {
135+
throw std::runtime_error("expression_tree_op_node contained a non-implemented boolean expression");
136+
}
137+
}
138+
139+
return false;
140+
}
141+
142+
143+
private:
144+
boolean_op bool_op_;
145+
LeftChild* left_ { nullptr };
146+
RightChild* right_ { nullptr };
82147
};
83148

149+
/**
150+
* @brief Represents leaf nodes of the tree. These nodes contain a reference to a member variable or member function of the
151+
* given Obj type, the requested logical operation to be performed (e.g. equals, greater_than, etc.), and the
152+
* value to compare to the given member variable or member function of an Obj instance.
153+
*/
84154
template<typename Obj, typename Op, typename CompValue>
85155
class expression_tree_leaf_node : public expression_tree_node_base<Obj> {
86156

0 commit comments

Comments
 (0)