#ifndef WARPX_PARSER_H_ #define WARPX_PARSER_H_ #include #include #include #include #include "wp_parser_c.h" #include "wp_parser_y.h" #ifdef _OPENMP #include #endif class GpuParser; class WarpXParser { public: WarpXParser (std::string const& func_body); WarpXParser () = default; ~WarpXParser (); void define (std::string const& func_body); void setConstant (std::string const& name, double c); // // Option 1: Register every variable to an address provided. // Assign values to external variables. // Call eval(). void registerVariable (std::string const& name, double& var); // inline double eval () const noexcept; // // Option 2: Register all variables at once. Parser will create // variables internally. // Call eval(...) with variable values. void registerVariables (std::vector const& names); // template inline double eval (T x, Ts... yz) const noexcept; void print () const; std::string const& expr () const; std::set symbols () const; friend class GpuParser; private: void clear (); template inline void unpack (double* p, T x) const noexcept; template inline void unpack (double* p, T x, Ts... yz) const noexcept; std::string m_expression; #ifdef _OPENMP std::vector m_parser; mutable std::vector > m_variables; #else struct wp_parser* m_parser = nullptr; mutable std::array m_variables; #endif }; inline double WarpXParser::eval () const noexcept { #ifdef _OPENMP return wp_ast_eval(m_parser[omp_get_thread_num()]->ast); #else return wp_ast_eval(m_parser->ast); #endif } template inline double WarpXParser::eval (T x, Ts... yz) const noexcept { #ifdef _OPENMP unpack(m_variables[omp_get_thread_num()].data(), x, yz...); #else unpack(m_variables.data(), x, yz...); #endif return eval(); } template inline void WarpXParser::unpack (double* p, T x) const noexcept { *p = x; } template inline void WarpXParser::unpack (double* p, T x, Ts... yz) const noexcept { *p++ = x; unpack(p, yz...); } #endif