@@ -45,8 +45,18 @@ const std::shared_ptr<False>& False::Instance() {
4545Result<std::shared_ptr<Expression>> False::Negate () const { return True::Instance (); }
4646
4747// And implementation
48+ Result<std::unique_ptr<And>> And::Make (std::shared_ptr<Expression> left,
49+ std::shared_ptr<Expression> right) {
50+ if (!left || !right) [[unlikely]] {
51+ return InvalidExpression (" And expression cannot have null children" );
52+ }
53+ return std::unique_ptr<And>(new And (std::move (left), std::move (right)));
54+ }
55+
4856And::And (std::shared_ptr<Expression> left, std::shared_ptr<Expression> right)
49- : left_(std::move(left)), right_(std::move(right)) {}
57+ : left_(std::move(left)), right_(std::move(right)) {
58+ ICEBERG_DCHECK (left_ && right_, " And cannot have null children" );
59+ }
5060
5161std::string And::ToString () const {
5262 return std::format (" ({} and {})" , left_->ToString (), right_->ToString ());
@@ -56,7 +66,7 @@ Result<std::shared_ptr<Expression>> And::Negate() const {
5666 // De Morgan's law: not(A and B) = (not A) or (not B)
5767 ICEBERG_ASSIGN_OR_RAISE (auto left_negated, left_->Negate ());
5868 ICEBERG_ASSIGN_OR_RAISE (auto right_negated, right_->Negate ());
59- return std::make_shared<Or> (std::move (left_negated), std::move (right_negated));
69+ return Or::Make (std::move (left_negated), std::move (right_negated));
6070}
6171
6272bool And::Equals (const Expression& expr) const {
@@ -69,8 +79,18 @@ bool And::Equals(const Expression& expr) const {
6979}
7080
7181// Or implementation
82+ Result<std::unique_ptr<Or>> Or::Make (std::shared_ptr<Expression> left,
83+ std::shared_ptr<Expression> right) {
84+ if (!left || !right) [[unlikely]] {
85+ return InvalidExpression (" Or cannot have null children" );
86+ }
87+ return std::unique_ptr<Or>(new Or (std::move (left), std::move (right)));
88+ }
89+
7290Or::Or (std::shared_ptr<Expression> left, std::shared_ptr<Expression> right)
73- : left_(std::move(left)), right_(std::move(right)) {}
91+ : left_(std::move(left)), right_(std::move(right)) {
92+ ICEBERG_DCHECK (left_ && right_, " Or cannot have null children" );
93+ }
7494
7595std::string Or::ToString () const {
7696 return std::format (" ({} or {})" , left_->ToString (), right_->ToString ());
@@ -80,7 +100,7 @@ Result<std::shared_ptr<Expression>> Or::Negate() const {
80100 // De Morgan's law: not(A or B) = (not A) and (not B)
81101 ICEBERG_ASSIGN_OR_RAISE (auto left_negated, left_->Negate ());
82102 ICEBERG_ASSIGN_OR_RAISE (auto right_negated, right_->Negate ());
83- return std::make_shared<And> (std::move (left_negated), std::move (right_negated));
103+ return And::Make (std::move (left_negated), std::move (right_negated));
84104}
85105
86106bool Or::Equals (const Expression& expr) const {
@@ -93,7 +113,16 @@ bool Or::Equals(const Expression& expr) const {
93113}
94114
95115// Not implementation
96- Not::Not (std::shared_ptr<Expression> child) : child_(std::move(child)) {}
116+ Result<std::unique_ptr<Not>> Not::Make (std::shared_ptr<Expression> child) {
117+ if (!child) [[unlikely]] {
118+ return InvalidExpression (" Not expression cannot have null child" );
119+ }
120+ return std::unique_ptr<Not>(new Not (std::move (child)));
121+ }
122+
123+ Not::Not (std::shared_ptr<Expression> child) : child_(std::move(child)) {
124+ ICEBERG_DCHECK (child_ != nullptr , " Not expression cannot have null child" );
125+ }
97126
98127std::string Not::ToString () const { return std::format (" not({})" , child_->ToString ()); }
99128
@@ -199,7 +228,7 @@ Result<Expression::Operation> Negate(Expression::Operation op) {
199228 case Expression::Operation::kMax :
200229 case Expression::Operation::kMin :
201230 case Expression::Operation::kCount :
202- return InvalidArgument (" No negation for operation: {}" , op);
231+ return InvalidExpression (" No negation for operation: {}" , op);
203232 }
204233 std::unreachable ();
205234}
0 commit comments