11#pragma once
22
3+ #include < stdexcept>
4+
35namespace 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