Lunderberg commented on code in PR #13933:
URL: https://github.com/apache/tvm/pull/13933#discussion_r1102989040


##########
src/arith/pattern_match.h:
##########
@@ -813,6 +835,77 @@ inline PCallExpr<PIfThenElseOp, TCond, TA, TB> 
if_then_else(const Pattern<TCond>
                                                  false_value.derived());
 }
 
+template <typename... TPattern>
+class PMatchesOneOf {
+ public:
+  explicit PMatchesOneOf(const TPattern&... patterns) : patterns_{patterns...} 
{}
+
+  /*! \brief Check if value matches one of the patterns.
+   *
+   * This call also populates the PVars with matched value based on
+   * the first successful match.  The values in PVars are valid until
+   * the next call to Match.
+   *
+   * \param value The value to be matched against.
+   *
+   * \return Whether value matches the pattern.
+   */
+  template <typename NodeType>
+  inline bool Match(const NodeType& value) const {
+    return Match(value, []() { return true; });
+  }
+
+  /*! \brief Check if value matches one of the patterns.
+   *
+   * This call also populates the PVars with matched value based on
+   * the first successful match.  The values in PVars are valid until
+   * the next call to Match.
+   *
+   * \param value The value to be matched against.
+   *
+   * \param cond A callable that performs additional validation,
+   * returning true if the match passes.  This will typically be a
+   * lambda function written in terms of the filled PVars.  This will
+   * be called once for each successful pattern match.  If `cond()`
+   * returns false, the next match will be attempted.
+   *
+   * \return Whether value matches the pattern.
+   */
+  template <typename NodeType, typename Condition>
+  inline bool Match(const NodeType& value, Condition cond) const {
+    return MatchImpl(value, cond, 
std::make_index_sequence<sizeof...(TPattern)>());
+  }
+
+ private:
+  template <typename NodeType, typename Condition>
+  inline bool MatchImpl(const NodeType& value, Condition cond, 
std::index_sequence<>) const {
+    return false;
+  }
+
+  template <typename NodeType, typename Condition, size_t FirstIndex, 
size_t... RemainingIndices>
+  inline bool MatchImpl(const NodeType& value, Condition cond,
+                        std::index_sequence<FirstIndex, RemainingIndices...>) 
const {
+    return std::get<FirstIndex>(patterns_).Match(value, cond) ||
+           MatchImpl(value, cond, std::index_sequence<RemainingIndices...>());
+  }
+
+  std::tuple<const TPattern&...> patterns_;

Review Comment:
   Certainly.  This is following the same usage as both the `PVar` which occurs 
as `const PVar<T>&` when it appears inside other patterns, and the existing 
operator overloads which take arguments by const reference.  Because the 
`PVar<T>::value_` field is mutable, it can still be updated through these const 
references.
   
   I believe this was initially done to avoid making copies of temporary 
objects produced from the operators.  So long as the call to `Match` occurs 
within the same expression as the operators, this doesn't produce dangling 
references.  I did try a bit to change to more standard value semantics, but 
that ended up being a much larger change than I wanted to make.
   
   I'm updating this section with a comment to describe this behavior.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to