59    using SymbolTable = exprtk::symbol_table<Scalar>;
 
   60    using Expression = exprtk::expression<Scalar>;
 
   61    using Parser = exprtk::parser<Scalar>;
 
   68    { initialize_(expression, variableNames); }
 
 
   75    template<
class S, std::enable_if_t<std::is_convertible_v<Scalar, S>, 
int> = 0>
 
   76    Scalar 
operator() (
const std::array<S, numVars>& params)
 const 
   77    { 
return evalRandomAcessImpl_(params); }
 
 
   79    template<
class S, std::enable_if_t<std::is_convertible_v<Scalar, S>, 
int> = 0>
 
   80    Scalar 
operator() (
const Dune::FieldVector<S, numVars>& params)
 const 
   81    { 
return evalRandomAcessImpl_(params); }
 
 
   83    template<
class ...Params, std::enable_if_t<(
sizeof...(Params) == numVars) && (std::is_convertible_v<Scalar, std::decay_t<Params>> && ...), 
int> = 0>
 
   85    { 
return evalRandomAcessImpl_(std::array<Scalar, numVars>{ std::forward<Params>(params)... }); }
 
 
   91    template<
class RandomAccessContainer>
 
   92    Scalar evalRandomAcessImpl_(
const RandomAccessContainer& params)
 const 
   94        if constexpr (numVars > 0)
 
   96            std::lock_guard lock(evalMutex_);
 
   97            for (std::size_t i = 0; i < numVars; ++i)
 
   98                variables_[i] = params[i];
 
   99            return expression_.value();
 
  102            return expression_.value();
 
  105    template<std::size_t... I>
 
  106    std::array<std::string, numVars> extractVariableNames_(std::string_view names, std::index_sequence<I...>)
 const 
  108        static_assert(numVars == 
sizeof...(I), 
"Number of variables has to match size of index set.");
 
  109        if (names.size() != numVars)
 
  110            DUNE_THROW(Dune::IOError, 
"Number of variables in '" 
  111                << names << 
"' does not match number of function arguments: " << numVars);
 
  112        return { std::string(1, names.at(I))... };
 
  116    void initialize_(
const std::string& expression, 
const std::array<std::string, numVars>& variableNames)
 
  118        for (std::size_t i = 0; i < numVars; ++i)
 
  119            symbolTable_.add_variable(std::string{variableNames[i]}, variables_[i]);
 
  120        symbolTable_.add_constants();
 
  121        expression_.register_symbol_table(symbolTable_);
 
  123        if (!parser_.compile(expression, expression_))
 
  125            std::stringstream ss;
 
  126            ss << Fmt::format(
"Parsing expression '{}' failed.\n", expression);
 
  130                for (std::size_t i = 0; i < parser_.error_count(); ++i)
 
  132                    const auto error = parser_.get_error(i);
 
  135                        "-- error (position: {:02d}, type: {}): {}\n",
 
  136                        static_cast<unsigned int>(error.token.position),
 
  137                        exprtk::parser_error::to_str(error.mode).c_str(),
 
  138                        error.diagnostic.c_str()
 
  143            DUNE_THROW(Dune::IOError, ss.str());
 
  145        else if (verbosity_ >= 2)
 
  147            std::cout << Fmt::format(
 
  148                "Successfully parsed math expression '{}'\n",
 
  154    unsigned int verbosity_ = 2;
 
  155    SymbolTable symbolTable_;
 
  156    Expression expression_;
 
  158    mutable std::array<Scalar, numVars> variables_;
 
  159    mutable std::mutex evalMutex_;
 
 
FunctionFromStringExpression(const std::string &expression, std::string_view variableNames)
Delegating constructor using all characters of a string as variables.
Definition functionfromstringexpression.hh:72
FunctionFromStringExpression(const std::string &expression, const std::array< std::string, numVars > &variableNames)
Constructor from math expression and array of variable names.
Definition functionfromstringexpression.hh:67
Scalar evalStringExpression(const std::string &expression, int verbosity=0)
Evaluating simple string math expressions.
Definition functionfromstringexpression.hh:168