diff options
author | 2008-04-10 09:41:13 +0000 | |
---|---|---|
committer | 2008-04-10 09:41:13 +0000 | |
commit | ca448d2537cac67d77aac6db62de846bfcbc3022 (patch) | |
tree | 385fe31b9e12ceb6e55f9912b71691728aae2e65 | |
parent | 9d8876ce82c51f7898ddf73984fcfbb413ef851f (diff) |
split those files in util/
some more renaming
-rw-r--r-- | Eigen/Core | 13 | ||||
-rw-r--r-- | Eigen/src/Core/MatrixBase.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/PacketMath.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/Product.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/util/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Eigen/src/Core/util/Constants.h | 47 | ||||
-rw-r--r-- | Eigen/src/Core/util/ForwardDeclarations.h | 52 | ||||
-rw-r--r-- | Eigen/src/Core/util/Macros.h | 138 | ||||
-rw-r--r-- | Eigen/src/Core/util/Meta.h (renamed from Eigen/src/Core/util/Util.h) | 199 |
9 files changed, 259 insertions, 202 deletions
diff --git a/Eigen/Core b/Eigen/Core index 404eb89de..9f1210558 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -1,6 +1,14 @@ #ifndef EIGEN_CORE_H #define EIGEN_CORE_H +#ifdef __SSE2__ +#define EIGEN_VECTORIZE +#define EIGEN_VECTORIZE_SSE +#warning "enabling vectorization" +#include <emmintrin.h> +#include <xmmintrin.h> +#endif + #include <cstdlib> #include <cmath> #include <complex> @@ -9,8 +17,11 @@ namespace Eigen { -#include "src/Core/util/Util.h" +#include "src/Core/util/Macros.h" +#include "src/Core/util/Constants.h" #include "src/Core/util/ForwardDeclarations.h" +#include "src/Core/util/Meta.h" + #include "src/Core/NumTraits.h" #include "src/Core/MathFunctions.h" #include "src/Core/PacketMath.h" diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 62953eded..5c2350d6c 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -191,7 +191,7 @@ template<typename Derived> class MatrixBase /** Overloaded for optimal product evaluation */ template<typename Derived1, typename Derived2> - Derived& lazyAssign(const Product<Derived1,Derived2,CacheOptimal>& product); + Derived& lazyAssign(const Product<Derived1,Derived2,CacheOptimalProduct>& product); CommaInitializer operator<< (const Scalar& s); diff --git a/Eigen/src/Core/PacketMath.h b/Eigen/src/Core/PacketMath.h index aab123533..3697f262e 100644 --- a/Eigen/src/Core/PacketMath.h +++ b/Eigen/src/Core/PacketMath.h @@ -25,7 +25,7 @@ #ifndef EIGEN_PACKET_MATH_H #define EIGEN_PACKET_MATH_H -#ifdef EIGEN_INTEL_PLATFORM +#ifdef EIGEN_VECTORIZE_SSE template<> struct ei_packet_traits<float> { typedef __m128 type; enum {size=4}; }; template<> struct ei_packet_traits<double> { typedef __m128d type; enum {size=2}; }; diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 9e7127720..5d39f0c2b 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -109,7 +109,7 @@ struct ei_packet_product_unroller<RowMajor, Index, Dynamic, Lhs, Rhs, PacketScal template<typename Lhs, typename Rhs> struct ei_product_eval_mode { enum{ value = Lhs::MaxRowsAtCompileTime >= 8 && Rhs::MaxColsAtCompileTime >= 8 - ? CacheOptimal : UnrolledDotProduct }; + ? CacheOptimalProduct : NormalProduct }; }; template<typename Lhs, typename Rhs, int EvalMode> @@ -133,7 +133,7 @@ struct ei_traits<Product<Lhs, Rhs, EvalMode> > ? (unsigned int)(LhsFlags | RhsFlags) : (unsigned int)(LhsFlags | RhsFlags) & ~LargeBit ) | EvalBeforeAssigningBit - | (ei_product_eval_mode<Lhs, Rhs>::value == (int)CacheOptimal ? EvalBeforeNestingBit : 0)) + | (ei_product_eval_mode<Lhs, Rhs>::value == (int)CacheOptimalProduct ? EvalBeforeNestingBit : 0)) & (~(RowMajorBit | VectorizableBit)) | (((!(Lhs::Flags & RowMajorBit)) && (Lhs::Flags & VectorizableBit)) ? VectorizableBit : ((Rhs::Flags & RowMajorBit && (Rhs::Flags & VectorizableBit)) ? (RowMajorBit | VectorizableBit) @@ -257,7 +257,7 @@ MatrixBase<Derived>::operator*=(const MatrixBase<OtherDerived> &other) template<typename Derived> template<typename Derived1, typename Derived2> -Derived& MatrixBase<Derived>::lazyAssign(const Product<Derived1,Derived2,CacheOptimal>& product) +Derived& MatrixBase<Derived>::lazyAssign(const Product<Derived1,Derived2,CacheOptimalProduct>& product) { product._cacheOptimalEval(*this); return derived(); diff --git a/Eigen/src/Core/util/CMakeLists.txt b/Eigen/src/Core/util/CMakeLists.txt index 9ab9fc8b0..eb7b2b6eb 100644 --- a/Eigen/src/Core/util/CMakeLists.txt +++ b/Eigen/src/Core/util/CMakeLists.txt @@ -1,6 +1,6 @@ FILE(GLOB Eigen_Core_util_SRCS "*.h") INSTALL(FILES - ${Eigen_Core_SRCS} + ${Eigen_Core_util_SRCS} DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core/util ) diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h new file mode 100644 index 000000000..c71b12334 --- /dev/null +++ b/Eigen/src/Core/util/Constants.h @@ -0,0 +1,47 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.fr> +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see <http://www.gnu.org/licenses/>. + +#ifndef EIGEN_CONSTANTS_H +#define EIGEN_CONSTANTS_H + +const int Dynamic = 10000; + +// matrix/expression flags +const unsigned int RowMajorBit = 0x1; +const unsigned int EvalBeforeNestingBit = 0x2; +const unsigned int EvalBeforeAssigningBit = 0x4; +const unsigned int LargeBit = 0x8; +#ifdef EIGEN_VECTORIZE +const unsigned int VectorizableBit = 0x10; +#else +const unsigned int VectorizableBit = 0x0; +#endif + +enum { ConditionalJumpCost = 5 }; +enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight }; +enum DirectionType { Vertical, Horizontal }; +enum ProductEvaluationMode { NormalProduct, CacheOptimalProduct }; + +#endif // EIGEN_CONSTANTS_H diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index a7f269cb4..6167f13bd 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -70,56 +70,4 @@ template<typename Scalar> struct ei_scalar_quotient1_op; template<typename Scalar> struct ei_scalar_min_op; template<typename Scalar> struct ei_scalar_max_op; -template<typename T> struct ei_eval -{ - typedef Matrix<typename ei_traits<T>::Scalar, - ei_traits<T>::RowsAtCompileTime, - ei_traits<T>::ColsAtCompileTime, - ei_traits<T>::Flags & ~(EvalBeforeNestingBit | EvalBeforeAssigningBit), - ei_traits<T>::MaxRowsAtCompileTime, - ei_traits<T>::MaxColsAtCompileTime> type; -}; - -template<typename T> struct ei_unref { typedef T type; }; -template<typename T> struct ei_unref<T&> { typedef T type; }; - -template<typename T> struct ei_is_temporary -{ - enum { ret = 0 }; -}; - -template<typename T> struct ei_is_temporary<Temporary<T> > -{ - enum { ret = 1 }; -}; - -template<typename T, int n=1> struct ei_nested -{ - typedef typename ei_meta_if< - ei_is_temporary<T>::ret, - T, - typename ei_meta_if< - ei_traits<T>::Flags & EvalBeforeNestingBit - || (n+1) * NumTraits<typename ei_traits<T>::Scalar>::ReadCost < (n-1) * T::CoeffReadCost, - typename ei_eval<T>::type, - const T& - >::ret - >::ret type; -}; - -template<typename T> struct ei_functor_traits -{ - enum - { - Cost = 10, - IsVectorizable = false - }; -}; - -template<typename T> struct ei_packet_traits -{ - typedef T type; - enum {size=1}; -}; - #endif // EIGEN_FORWARDDECLARATIONS_H diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h new file mode 100644 index 000000000..84a2a0eef --- /dev/null +++ b/Eigen/src/Core/util/Macros.h @@ -0,0 +1,138 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.fr> +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see <http://www.gnu.org/licenses/>. + +#ifndef EIGEN_MACROS_H +#define EIGEN_MACROS_H + +#undef minor + +#ifdef EIGEN_DONT_USE_UNROLLED_LOOPS +#define EIGEN_UNROLLING_LIMIT 0 +#endif + +/** Defines the maximal loop size to enable meta unrolling of loops */ +#ifndef EIGEN_UNROLLING_LIMIT +#define EIGEN_UNROLLING_LIMIT 400 +#endif + +#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR +#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER RowMajorBit +#else +#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER 0 +#endif + +#define USING_PART_OF_NAMESPACE_EIGEN \ +EIGEN_USING_MATRIX_TYPEDEFS \ +using Eigen::Matrix; \ +using Eigen::MatrixBase; + +#ifdef NDEBUG +#define EIGEN_NO_DEBUG +#endif + +#ifndef ei_assert +#ifdef EIGEN_NO_DEBUG +#define ei_assert(x) +#else +#define ei_assert(x) assert(x) +#endif +#endif + +#ifdef EIGEN_INTERNAL_DEBUGGING +#define ei_internal_assert(x) ei_assert(x); +#else +#define ei_internal_assert(x) +#endif + +#ifdef EIGEN_NO_DEBUG +#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x +#else +#define EIGEN_ONLY_USED_FOR_DEBUG(x) +#endif + +// FIXME with the always_inline attribute, +// gcc 3.4.x reports the following compilation error: +// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval<Derived> Eigen::MatrixBase<Scalar, Derived>::eval() const' +// : function body not available +#if (defined __GNUC__) && (__GNUC__!=3) +#define EIGEN_ALWAYS_INLINE __attribute__((always_inline)) +#else +#define EIGEN_ALWAYS_INLINE +#endif + +#if (defined __GNUC__) +#define EIGEN_ALIGN_128 __attribute__ ((aligned(16))) +#else +#define EIGEN_ALIGN_128 +#endif + +#define EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \ +template<typename OtherDerived> \ +Derived& operator Op(const MatrixBase<OtherDerived>& other) \ +{ \ + return Eigen::MatrixBase<Derived>::operator Op(other); \ +} \ +Derived& operator Op(const Derived& other) \ +{ \ + return Eigen::MatrixBase<Derived>::operator Op(other); \ +} + +#define EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \ +template<typename Other> \ +Derived& operator Op(const Other& scalar) \ +{ \ + return Eigen::MatrixBase<Derived>::operator Op(scalar); \ +} + +#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \ +EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, =) \ +EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, +=) \ +EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \ +EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \ +EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=) + +#define _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, BaseClass) \ +typedef BaseClass Base; \ +typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \ +typedef typename Base::PacketScalar PacketScalar; \ +typedef typename Eigen::ei_nested<Derived>::type Nested; \ +typedef typename Eigen::ei_eval<Derived>::type Eval; \ +enum { RowsAtCompileTime = Base::RowsAtCompileTime, \ + ColsAtCompileTime = Base::ColsAtCompileTime, \ + MaxRowsAtCompileTime = Base::MaxRowsAtCompileTime, \ + MaxColsAtCompileTime = Base::MaxColsAtCompileTime, \ + SizeAtCompileTime = Base::SizeAtCompileTime, \ + MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ + IsVectorAtCompileTime = Base::IsVectorAtCompileTime, \ + Flags = Base::Flags, \ + CoeffReadCost = Base::CoeffReadCost }; + +#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ +_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase<Derived>) \ +friend class Eigen::MatrixBase<Derived>; + +#define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b) + +#endif // EIGEN_MACROS_H diff --git a/Eigen/src/Core/util/Util.h b/Eigen/src/Core/util/Meta.h index de45927ce..faf177473 100644 --- a/Eigen/src/Core/util/Util.h +++ b/Eigen/src/Core/util/Meta.h @@ -23,148 +23,8 @@ // License and a copy of the GNU General Public License along with // Eigen. If not, see <http://www.gnu.org/licenses/>. -#ifndef EIGEN_UTIL_H -#define EIGEN_UTIL_H - -#ifdef EIGEN_VECTORIZE -#ifdef EIGEN_INTEL_PLATFORM -#include <emmintrin.h> -#include <xmmintrin.h> -#else -#undef EIGEN_VECTORIZE -#endif -#endif - -#ifdef EIGEN_DONT_USE_UNROLLED_LOOPS -#define EIGEN_UNROLLING_LIMIT 0 -#endif - -/** Defines the maximal loop size to enable meta unrolling of loops */ -#ifndef EIGEN_UNROLLING_LIMIT -#define EIGEN_UNROLLING_LIMIT 400 -#endif - -#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR -#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER RowMajorBit -#else -#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER 0 -#endif - -#undef minor - -#define USING_PART_OF_NAMESPACE_EIGEN \ -EIGEN_USING_MATRIX_TYPEDEFS \ -using Eigen::Matrix; \ -using Eigen::MatrixBase; - -#ifdef NDEBUG -#define EIGEN_NO_DEBUG -#endif - -#ifndef ei_assert -#ifdef EIGEN_NO_DEBUG -#define ei_assert(x) -#else -#define ei_assert(x) assert(x) -#endif -#endif - -#ifdef EIGEN_INTERNAL_DEBUGGING -#define ei_internal_assert(x) ei_assert(x); -#else -#define ei_internal_assert(x) -#endif - -#ifdef EIGEN_NO_DEBUG -#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x -#else -#define EIGEN_ONLY_USED_FOR_DEBUG(x) -#endif - -// FIXME with the always_inline attribute, -// gcc 3.4.x reports the following compilation error: -// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval<Derived> Eigen::MatrixBase<Scalar, Derived>::eval() const' -// : function body not available -#if (defined __GNUC__) && (__GNUC__!=3) -#define EIGEN_ALWAYS_INLINE __attribute__((always_inline)) -#else -#define EIGEN_ALWAYS_INLINE -#endif - -#if (defined __GNUC__) -#define EIGEN_ALIGN_128 __attribute__ ((aligned(16))) -#else -#define EIGEN_ALIGN_128 -#endif - -#define EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \ -template<typename OtherDerived> \ -Derived& operator Op(const MatrixBase<OtherDerived>& other) \ -{ \ - return Eigen::MatrixBase<Derived>::operator Op(other); \ -} \ -Derived& operator Op(const Derived& other) \ -{ \ - return Eigen::MatrixBase<Derived>::operator Op(other); \ -} - -#define EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \ -template<typename Other> \ -Derived& operator Op(const Other& scalar) \ -{ \ - return Eigen::MatrixBase<Derived>::operator Op(scalar); \ -} - -#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \ -EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, =) \ -EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, +=) \ -EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \ -EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \ -EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=) - -#define _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, BaseClass) \ -typedef BaseClass Base; \ -typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \ -typedef typename Base::PacketScalar PacketScalar; \ -typedef typename Eigen::ei_nested<Derived>::type Nested; \ -typedef typename Eigen::ei_eval<Derived>::type Eval; \ -enum { RowsAtCompileTime = Base::RowsAtCompileTime, \ - ColsAtCompileTime = Base::ColsAtCompileTime, \ - MaxRowsAtCompileTime = Base::MaxRowsAtCompileTime, \ - MaxColsAtCompileTime = Base::MaxColsAtCompileTime, \ - SizeAtCompileTime = Base::SizeAtCompileTime, \ - MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ - IsVectorAtCompileTime = Base::IsVectorAtCompileTime, \ - Flags = Base::Flags, \ - CoeffReadCost = Base::CoeffReadCost }; - -#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ -_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase<Derived>) \ -friend class Eigen::MatrixBase<Derived>; - -#define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b) - -const int Dynamic = 10000; - -// matrix/expression flags -const unsigned int RowMajorBit = 0x1; -const unsigned int EvalBeforeNestingBit = 0x2; -const unsigned int EvalBeforeAssigningBit = 0x4; -const unsigned int LargeBit = 0x8; -#ifdef EIGEN_VECTORIZE -const unsigned int VectorizableBit = 0x10; -#else -const unsigned int VectorizableBit = 0x0; -#endif - - -enum { ConditionalJumpCost = 5 }; - -enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight }; - -enum DirectionType { Vertical, Horizontal }; - -enum ProductEvaluationMode { UnrolledDotProduct, CacheOptimal }; +#ifndef EIGEN_META_H +#define EIGEN_META_H // just a workaround because GCC seems to not really like empty structs #ifdef __GNUG__ @@ -270,4 +130,57 @@ struct ei_result_of<Func(ArgType0,ArgType1)> { typedef typename ei_binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type; }; -#endif // EIGEN_UTIL_H +template<typename T> struct ei_eval +{ + typedef Matrix<typename ei_traits<T>::Scalar, + ei_traits<T>::RowsAtCompileTime, + ei_traits<T>::ColsAtCompileTime, + ei_traits<T>::Flags & ~(EvalBeforeNestingBit | EvalBeforeAssigningBit), + ei_traits<T>::MaxRowsAtCompileTime, + ei_traits<T>::MaxColsAtCompileTime> type; +}; + +template<typename T> struct ei_unref { typedef T type; }; +template<typename T> struct ei_unref<T&> { typedef T type; }; + +template<typename T> struct ei_is_temporary +{ + enum { ret = 0 }; +}; + +template<typename T> struct ei_is_temporary<Temporary<T> > +{ + enum { ret = 1 }; +}; + +template<typename T, int n=1> struct ei_nested +{ + typedef typename ei_meta_if< + ei_is_temporary<T>::ret, + T, + typename ei_meta_if< + ei_traits<T>::Flags & EvalBeforeNestingBit + || (n+1) * NumTraits<typename ei_traits<T>::Scalar>::ReadCost < (n-1) * T::CoeffReadCost, + typename ei_eval<T>::type, + const T& + >::ret + >::ret type; +}; + +template<typename T> struct ei_functor_traits +{ + enum + { + Cost = 10, + IsVectorizable = false + }; +}; + +template<typename T> struct ei_packet_traits +{ + typedef T type; + enum {size=1}; +}; + + +#endif // EIGEN_META_H |