#pragma once #include #include #include #include #include #include #include namespace NYql { class TExecTransformerBase : public TAsyncCallbackTransformer { public: using TStatusCallbackPair = std::pair; using TPrerequisite = std::function; using THandler = std::function; TStatusCallbackPair CallbackTransform(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx); bool CanExec(const TExprNode& node) const { return Handlers.contains(node.Content()); } protected: void AddHandler(std::initializer_list names, TPrerequisite prerequisite, THandler handler); static TPrerequisite RequireAll(); static TPrerequisite RequireNone(); static TPrerequisite RequireFirst(); static TPrerequisite RequireAllOf(std::initializer_list children); static TPrerequisite RequireSequenceOf(std::initializer_list children); template TPrerequisite Require(TStatus(TDerived::* prerequisite)(const TExprNode::TPtr&)) { return [this, prerequisite] (const TExprNode::TPtr& input) { return (static_cast(this)->*prerequisite)(input); }; } static TStatusCallbackPair ExecPass(const TExprNode::TPtr& input, TExprContext& ctx); static THandler Pass(); template THandler Hndl(TStatusCallbackPair(TDerived::* handler)(const TExprNode::TPtr&, TExprNode::TPtr&, TExprContext&)) { return [this, handler] (const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) { return (static_cast(this)->*handler)(input, output, ctx); }; } template THandler Hndl(TStatusCallbackPair(TDerived::* handler)(const TExprNode::TPtr&, TExprContext&)) { return [this, handler] (const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) { return (static_cast(this)->*handler)(input, ctx); }; } protected: struct THandlerInfo { TPrerequisite Prerequisite; THandler Handler; }; THashMap Handlers; }; } // NYql