diff --git a/Eigen/Core b/Eigen/Core index 2ce2dd6b2..b9149659a 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -354,8 +354,8 @@ using std::ptrdiff_t; #include "src/Core/util/StaticAssert.h" #include "src/Core/util/XprHelper.h" #include "src/Core/util/Memory.h" -#include "src/Core/util/SymbolicIndex.h" #include "src/Core/util/IntegralConstant.h" +#include "src/Core/util/SymbolicIndex.h" #include "src/Core/NumTraits.h" diff --git a/Eigen/src/Core/util/IndexedViewHelper.h b/Eigen/src/Core/util/IndexedViewHelper.h index a8259bb2c..5dca1926c 100644 --- a/Eigen/src/Core/util/IndexedViewHelper.h +++ b/Eigen/src/Core/util/IndexedViewHelper.h @@ -60,7 +60,7 @@ static const auto end = last+1; #else // Using a FixedExpr<1> expression is important here to make sure the compiler // can fully optimize the computation starting indices with zero overhead. -static const Symbolic::AddExpr,Symbolic::FixedExpr<1> > end(last+Symbolic::FixedExpr<1>()); +static const Symbolic::AddExpr,Symbolic::FixedExpr<1> > end(last+fix<1>()); #endif } // end namespace placeholders diff --git a/Eigen/src/Core/util/SymbolicIndex.h b/Eigen/src/Core/util/SymbolicIndex.h index cee5d908a..fcc5921e6 100644 --- a/Eigen/src/Core/util/SymbolicIndex.h +++ b/Eigen/src/Core/util/SymbolicIndex.h @@ -57,6 +57,17 @@ protected: Index m_value; }; +// Simple wrapper around a compile-time value, +// It is similar to ValueExpr(N) but this version helps the compiler to generate better code. +template +class FixedExpr { +public: + FixedExpr() {} + template + Index eval_impl(const T&) const { return N; } +}; + + /** \class BaseExpr * \ingroup Core_Module * Common base class of any symbolic expressions @@ -101,6 +112,34 @@ public: friend QuotientExpr operator/(Index a, const BaseExpr& b) { return QuotientExpr(a,b.derived()); } + + template + AddExpr > operator+(internal::fix_t) const + { return AddExpr >(derived(), FixedExpr()); } + template + AddExpr > operator-(internal::fix_t) const + { return AddExpr >(derived(), FixedExpr<-N>()); } + template + ProductExpr > operator*(internal::fix_t) const + { return ProductExpr >(derived(),FixedExpr()); } + template + QuotientExpr > operator/(internal::fix_t) const + { return QuotientExpr >(derived(),FixedExpr()); } + + template + friend AddExpr > operator+(internal::fix_t, const BaseExpr& b) + { return AddExpr >(b.derived(), FixedExpr()); } + template + friend AddExpr,FixedExpr > operator-(internal::fix_t, const BaseExpr& b) + { return AddExpr,FixedExpr >(-b.derived(), FixedExpr()); } + template + friend ProductExpr,Derived> operator*(internal::fix_t, const BaseExpr& b) + { return ProductExpr,Derived>(FixedExpr(),b.derived()); } + template + friend QuotientExpr,Derived> operator/(internal::fix_t, const BaseExpr& b) + { return QuotientExpr ,Derived>(FixedExpr(),b.derived()); } + + template AddExpr operator+(const BaseExpr &b) const { return AddExpr(derived(), b.derived()); } @@ -124,17 +163,6 @@ struct is_symbolic { enum { value = internal::is_convertible >::value }; }; -// Simple wrapper around a compile-time value, -// It is similar to ValueExpr(N) but this version helps the compiler to generate better code. -template -class FixedExpr : public BaseExpr > { -public: - FixedExpr() {} - template - Index eval_impl(const T&) const { return 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.