// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2017 Gael Guennebaud <[email protected]> // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SYMBOLIC_INDEX_H #define EIGEN_SYMBOLIC_INDEX_H // IWYU pragma: private #include "../InternalHeaderCheck.h" namespace Eigen { /** \namespace Eigen::symbolic * \ingroup Core_Module * * 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_tag> x; * struct y_tag {}; static const symbolic::SymbolExpr<y_tag> y; * struct z_tag {}; static const symbolic::SymbolExpr<z_tag> z; * * // Defines an expression: * auto expr = (x+3)/y+z; * * // And evaluate it: (c++14) * std::cout << expr.eval(x=6,y=3,z=-13) << "\n"; * * \endcode * * It is currently only used internally to define and manipulate the * Eigen::placeholders::last and Eigen::placeholders::lastp1 symbols in * Eigen::seq and Eigen::seqN. * */ namespace symbolic { template <typename Tag> class Symbol; template <typename Tag, typename Type> class SymbolValue; template <typename Arg0> class NegateExpr; template <typename Arg1, typename Arg2> class AddExpr; template <typename Arg1, typename Arg2> class ProductExpr; template <typename Arg1, typename Arg2> class QuotientExpr; template <typename IndexType = Index> class ValueExpr; /** \class BaseExpr * \ingroup Core_Module * Common base class of any symbolic expressions */ template <typename Derived_> class BaseExpr { … }; template <typename T> struct is_symbolic { … }; // A simple wrapper around an integral value to provide the eval method. // We could also use a free-function symbolic_eval... template <typename IndexType> class ValueExpr : BaseExpr<ValueExpr<IndexType>> { … }; // Specialization for compile-time value, // It is similar to ValueExpr(N) but this version helps the compiler to generate better code. ValueExpr<internal::FixedInt<N>>; /** Represents the actual value of a symbol identified by its tag * * It is the return type of SymbolValue::operator=, and most of the time this is only way it is used. */ template <typename Tag, typename Type> class SymbolValue : public BaseExpr<SymbolValue<Tag, Type>> { … }; SymbolValue<Tag, Index>; SymbolValue<Tag, internal::FixedInt<N>>; // Find and return a symbol value based on the tag. template <typename Tag, typename... Types> struct EvalSymbolValueHelper; // Empty base case, symbol not found. EvalSymbolValueHelper<Tag>; // We found a symbol value matching the provided Tag! EvalSymbolValueHelper<Tag, SymbolValue<Tag, Type>, OtherTypes...>; // No symbol value in first value, recursive search starting with next. EvalSymbolValueHelper<Tag, T1, OtherTypes...>; /** Expression of a symbol uniquely identified by the template parameter type \c tag */ template <typename tag> class SymbolExpr : public BaseExpr<SymbolExpr<tag>> { … }; template <typename Arg0> class NegateExpr : public BaseExpr<NegateExpr<Arg0>> { … }; template <typename Arg0, typename Arg1> class AddExpr : public BaseExpr<AddExpr<Arg0, Arg1>> { … }; template <typename Arg0, typename Arg1> class ProductExpr : public BaseExpr<ProductExpr<Arg0, Arg1>> { … }; template <typename Arg0, typename Arg1> class QuotientExpr : public BaseExpr<QuotientExpr<Arg0, Arg1>> { … }; } // end namespace symbolic } // end namespace Eigen #endif // EIGEN_SYMBOLIC_INDEX_H