@@ -84,12 +84,12 @@ namespace attwoodn::expression_tree {
8484 * False if the given object did not satisfy the expression in this node and the expressions of all
8585 * nodes under this node in the expression tree.
8686 */
87- virtual bool evaluate (const Obj& obj) = 0;
87+ virtual bool evaluate (const Obj& obj) const = 0;
8888
8989 /* *
9090 * @brief Performs a deep clone of pointers to this base class to avoid object slicing.
9191 */
92- auto clone () {
92+ auto clone () const {
9393 return std::unique_ptr<expression_tree_node<Obj>>(clone_impl ());
9494 }
9595
@@ -106,6 +106,11 @@ namespace attwoodn::expression_tree {
106106 public:
107107 using this_type = expression_tree_op_node<Obj, LeftChild, RightChild>;
108108
109+ expression_tree_op_node () = delete ;
110+ expression_tree_op_node (expression_tree_op_node&& other) = delete ;
111+ expression_tree_op_node& operator =(const expression_tree_op_node& other) = delete ;
112+ expression_tree_op_node& operator =(expression_tree_op_node&& other) = delete ;
113+
109114 expression_tree_op_node (boolean_op bool_op)
110115 : bool_op_(bool_op) {}
111116
@@ -134,7 +139,7 @@ namespace attwoodn::expression_tree {
134139 delete l;
135140 }
136141
137- bool evaluate (const Obj& obj) override {
142+ bool evaluate (const Obj& obj) const override {
138143 if (!left_ || !right_) {
139144 throw std::runtime_error (" expression_tree_op_node has a missing child node" );
140145 }
@@ -237,6 +242,13 @@ namespace attwoodn::expression_tree {
237242 public:
238243 using this_type = expression_tree_leaf_node<Obj, Op, CompValue>;
239244
245+ expression_tree_leaf_node () = delete ;
246+
247+ expression_tree_leaf_node (const expression_tree_leaf_node& other) = default ;
248+ expression_tree_leaf_node (expression_tree_leaf_node&& other) = default ;
249+ expression_tree_leaf_node& operator =(const expression_tree_leaf_node& other) = default ;
250+ expression_tree_leaf_node& operator =(expression_tree_leaf_node&& other) = default ;
251+
240252 /* *
241253 * @brief Constructor that accepts a reference to a member variable of Obj
242254 */
@@ -255,7 +267,7 @@ namespace attwoodn::expression_tree {
255267
256268 ~expression_tree_leaf_node () override {};
257269
258- bool evaluate (const Obj& obj) override {
270+ bool evaluate (const Obj& obj) const override {
259271 if (member_func_ && member_var_) {
260272 throw std::runtime_error (" expression_tree_leaf_node has both a member function reference " +
261273 std::string (" and member variable reference. Only one is permitted" ));
@@ -391,28 +403,46 @@ namespace attwoodn::expression_tree {
391403
392404 expression_tree (node::expression_tree_node<Obj>* expr) {
393405 if (!expr) {
394- throw std::runtime_error (" Attempted to construct an expression_tree with a null root expression node " );
406+ throw std::runtime_error (" Attempted to construct an expression_tree using a null expression" );
395407 }
396-
397408 expr_ = expr->clone ().release ();
398409 delete expr;
399410 }
400411
401- expression_tree (const expression_tree& other)
402- : expr_(other.expr_->clone ().release()) {}
412+ expression_tree (std::unique_ptr<node::expression_tree_node<Obj>> expr)
413+ : expression_tree(expr.release()) {}
414+
415+ expression_tree (const expression_tree& other) {
416+ if (!other.expr_ ) {
417+ throw std::runtime_error (" Attempted to copy construct an expression_tree " +
418+ std::string (" from an expression_tree with a null expression" ));
419+ }
420+ expr_ = other.expr_ ->clone ().release ();
421+ }
403422
404- expression_tree (expression_tree&& other)
405- : expr_(other.expr_) {
423+ expression_tree (expression_tree&& other) {
424+ if (!other.expr_ ) {
425+ throw std::runtime_error (" Attempted to move construct an expression_tree " +
426+ std::string (" from an expression_tree with a null expression" ));
427+ }
428+ expr_ = other.expr_ ;
406429 other.expr_ = nullptr ;
407430 }
408431
409432 expression_tree& operator =(const expression_tree& other) {
433+ if (!other.expr_ ) {
434+ throw std::runtime_error (" Attempted copy assignment from an expression_tree with a null expression" );
435+ }
410436 delete expr_;
411437 expr_ = other.expr_ ->clone ().release ();
412438 return *this ;
413439 }
414440
415- expression_tree& operator =(const expression_tree&& other) {
441+ expression_tree& operator =(expression_tree&& other) {
442+ if (!other.expr_ ) {
443+ throw std::runtime_error (" Attempted move assignment from an expression_tree with a null expression" );
444+ }
445+
416446 if (this != &other) {
417447 delete expr_;
418448 expr_ = other.expr_ ;
@@ -431,7 +461,7 @@ namespace attwoodn::expression_tree {
431461 * @returns True if the given object satisfied the expression tree conditions;
432462 * False if the given object did not satisfy the expression tree conditions.
433463 */
434- bool evaluate (const Obj& obj) {
464+ bool evaluate (const Obj& obj) const {
435465 if (!expr_) {
436466 throw std::runtime_error (" expression_tree has a null root expression node" );
437467 }
@@ -446,4 +476,4 @@ namespace attwoodn::expression_tree {
446476 private:
447477 node::expression_tree_node<Obj>* expr_ = nullptr ;
448478 };
449- }
479+ }
0 commit comments