diff --git a/Eigen/src/Core/ArithmeticSequence.h b/Eigen/src/Core/ArithmeticSequence.h index 38cc32aa3..dc346bac6 100644 --- a/Eigen/src/Core/ArithmeticSequence.h +++ b/Eigen/src/Core/ArithmeticSequence.h @@ -23,6 +23,29 @@ static const all_t all; // minimalistic symbolic scalar type //-------------------------------------------------------------------------------- + +/** This namespace defines a set of classes and functions to build and evaluate symbolic expressions of scalar type Index. + * Here is a simple example: + * + * \code + * // First step, defines symbols: + * struct x_tag {}; static const Symbolic::SymbolExpr x; + * struct y_tag {}; static const Symbolic::SymbolExpr y; + * struct z_tag {}; static const Symbolic::SymbolExpr z; + * + * // Defines an expression: + * auto expr = (x+3)/y+z; + * + * // And evaluate it: (c++14) + * std::cout << expr.eval(std::make_tuple(Symbolic::defineValue(x,6),Symbolic::defineValue(y,3),Symbolic::defineValue(z,-13))) << "\n"; + * + * // In c++98/11, only one symbol per expression is supported for now: + * auto expr98 = (3-x)/2; + * std::cout << expr98.eval(Symbolic::defineValue(x,6)) << "\n"; + * + * It is currently only used internally to define and minipulate the placeholders::last and placeholders::end symbols in Eigen::seq and Eigen::seqN. + * + */ namespace Symbolic { template class Symbol; @@ -42,12 +65,24 @@ protected: Index m_value; }; +/** \class BaseExpr + * Common base class of any symbolic expressions + */ template class BaseExpr { public: const Derived& derived() const { return *static_cast(this); } + /** Evaluate the expression given the \a values of the symbols. + * + * \param values defines the values of the symbols, it can either be a SymbolValue or a std::tuple of SymbolValue + * as constructed by the defineValue function. + * + */ + template + Index eval(const T& values) const { return derived().eval(values); } + NegateExpr operator-() const { return NegateExpr(derived()); } AddExpr operator+(Index b) const @@ -73,7 +108,7 @@ public: { return AddExpr >(derived(), -b.derived()); } template - AddExpr operator/(const BaseExpr &b) const + QuotientExpr operator/(const BaseExpr &b) const { return QuotientExpr(derived(), b.derived()); } }; @@ -83,11 +118,18 @@ struct is_symbolic { enum { value = internal::is_convertible >::value }; }; +/** Represents the actual value of a symbol identified by its tag + * + * It is the return type of defineValue(), and most of the time this is only way it is used. + */ template class SymbolValue { public: + /** Default constructor from the value \a val */ SymbolValue(Index val) : m_value(val) {} + + /** \returns the stored value of the symbol */ Index value() const { return m_value; } protected: Index m_value; @@ -102,12 +144,17 @@ public: Index eval(const SymbolValue &values) const { return values.value(); } - - // TODO add a c++14 eval taking a tuple of SymbolValue and getting the value with std::get >... +#if __cplusplus > 201103L + // C++14 versions suitable for multiple symbols + template + Index eval(const std::tuple& values) const { return std::get >(values).value(); } +#endif }; +/** Associate the value \a val to the symbol \a symb + */ template -SymbolValue defineValue(SymbolExpr,Index val) { +SymbolValue defineValue(SymbolExpr /*symb*/,Index val) { return SymbolValue(val); }