@@ -40,12 +40,57 @@ class ICEBERG_EXPORT Expressions {
4040 // Logical operations
4141
4242 // / \brief Create an AND expression.
43+ template <typename ... Args>
4344 static std::shared_ptr<Expression> And (std::shared_ptr<Expression> left,
44- std::shared_ptr<Expression> right);
45+ std::shared_ptr<Expression> right,
46+ Args&&... args)
47+ requires std::conjunction_v<std::is_same<Args, std::shared_ptr<Expression>>...>
48+ {
49+ if constexpr (sizeof ...(args) == 0 ) {
50+ if (left->op () == Expression::Operation::kFalse ||
51+ right->op () == Expression::Operation::kFalse ) {
52+ return AlwaysFalse ();
53+ }
54+
55+ if (left->op () == Expression::Operation::kTrue ) {
56+ return right;
57+ }
58+
59+ if (right->op () == Expression::Operation::kTrue ) {
60+ return left;
61+ }
62+
63+ return std::make_shared<::iceberg::And>(std::move (left), std::move (right));
64+ } else {
65+ return And (And (std::move (left), std::move (right)), std::forward<Args>(args)...);
66+ }
67+ }
4568
4669 // / \brief Create an OR expression.
70+ template <typename ... Args>
4771 static std::shared_ptr<Expression> Or (std::shared_ptr<Expression> left,
48- std::shared_ptr<Expression> right);
72+ std::shared_ptr<Expression> right, Args&&... args)
73+ requires std::conjunction_v<std::is_same<Args, std::shared_ptr<Expression>>...>
74+ {
75+ if constexpr (sizeof ...(args) == 0 ) {
76+ if (left->op () == Expression::Operation::kTrue ||
77+ right->op () == Expression::Operation::kTrue ) {
78+ return AlwaysTrue ();
79+ }
80+
81+ if (left->op () == Expression::Operation::kFalse ) {
82+ return right;
83+ }
84+
85+ if (right->op () == Expression::Operation::kFalse ) {
86+ return left;
87+ }
88+
89+ return std::make_shared<::iceberg::Or>(std::move (left), std::move (right));
90+ } else {
91+ return Or (Or (std::move (left), std::move (right)), std::forward<Args>(args)...);
92+ }
93+ }
4994
5095 // Transform functions
5196
0 commit comments