/** @file Apply.hpp * * Author: Roland Conybeare **/ #pragma once #include "Expression.hpp" //#include namespace xo { namespace ast { /** @class Apply * @brief syntax for a function call. * * In general we don't know function to be invoked * until runtime, depending on the nature of Expression. **/ class Apply : public Expression { public: using TypeDescr = xo::reflect::TypeDescr; public: /** create new apply-expression instance **/ static ref::rp make(const ref::rp & fn, const std::vector> & argv); /** downcast from Expression **/ static ref::brw from(ref::brw x) { return ref::brw::from(x); } const ref::rp & fn() const { return fn_; } const std::vector> & argv() const { return argv_; } virtual void display(std::ostream & os) const; private: Apply(TypeDescr apply_valuetype, const ref::rp & fn, const std::vector> & argv) : Expression(exprtype::apply, apply_valuetype), fn_{fn}, argv_(argv) {} private: /** function to invoke **/ ref::rp fn_; /** argument expressions, in l-to-r order **/ std::vector> argv_; }; /*Apply*/ #ifdef NOT_USING namespace detail { /** Use: ** std::vector> **/ template struct apply_push_args; template <> struct apply_push_args<> { static void push_all(std::vector> * /*p_argv*/) {} }; template struct apply_push_args { static void push_all(std::vector> * p_argv, const ref::rp & x, Rest... rest) { p_argv->push_back(x); apply_push_args::push_all(p_argv, rest...); }; }; } #endif /* reminder: initializer-lists are compile-time only */ inline ref::rp make_apply(const ref::rp & fn, const std::initializer_list> args) { std::vector> argv(args); return Apply::make(fn, argv); } /*make_apply*/ } /*namespace ast*/ } /*namespace xo*/ /** end Apply.hpp **/