// 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 // Copyright (C) 2006-2008 Benoit Jacob // // 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 . #ifndef EIGEN_META_H #define EIGEN_META_H // just a workaround because GCC seems to not really like empty structs #ifdef __GNUG__ struct ei_empty_struct{char _ei_dummy_;}; #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct #else #define EIGEN_EMPTY_STRUCT #endif //classes inheriting ei_no_assignment_operator don't generate a default operator=. class ei_no_assignment_operator { private: ei_no_assignment_operator& operator=(const ei_no_assignment_operator&); }; template class ei_int_if_dynamic EIGEN_EMPTY_STRUCT { public: ei_int_if_dynamic() {} explicit ei_int_if_dynamic(int) {} static int value() { return Value; } void setValue(int) {} }; template<> class ei_int_if_dynamic { int m_value; ei_int_if_dynamic() {} public: explicit ei_int_if_dynamic(int value) : m_value(value) {} int value() const { return m_value; } void setValue(int value) { m_value = value; } }; template struct ei_meta_if { typedef Then ret; }; template struct ei_meta_if { typedef Else ret; }; template struct ei_is_same_type { enum { ret = 0 }; }; template struct ei_is_same_type { enum { ret = 1 }; }; struct ei_meta_true {}; struct ei_meta_false {}; /** \internal * Convenient struct to get the result type of a unary or binary functor. * * It supports both the current STL mechanism (using the result_type member) as well as * upcoming next STL generation (using a templated result member). * If none of these members is provided, then the type of the first argument is returned. */ template struct ei_result_of {}; struct ei_has_none {int a[1];}; struct ei_has_std_result_type {int a[2];}; struct ei_has_tr1_result {int a[3];}; template struct ei_unary_result_of_select {typedef ArgType type;}; template struct ei_unary_result_of_select {typedef typename Func::result_type type;}; template struct ei_unary_result_of_select {typedef typename Func::template result::type type;}; template struct ei_result_of { template static ei_has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); template static ei_has_tr1_result testFunctor(T const *, typename T::template result::type const * = 0); static ei_has_none testFunctor(...); // note that the following indirection is needed for gcc-3.3 enum {FunctorType = sizeof(testFunctor(static_cast(0)))}; typedef typename ei_unary_result_of_select::type type; }; template struct ei_binary_result_of_select {typedef ArgType0 type;}; template struct ei_binary_result_of_select {typedef typename Func::result_type type;}; template struct ei_binary_result_of_select {typedef typename Func::template result::type type;}; template struct ei_result_of { template static ei_has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); template static ei_has_tr1_result testFunctor(T const *, typename T::template result::type const * = 0); static ei_has_none testFunctor(...); // note that the following indirection is needed for gcc-3.3 enum {FunctorType = sizeof(testFunctor(static_cast(0)))}; typedef typename ei_binary_result_of_select::type type; }; template struct ei_functor_traits { enum { Cost = 10, PacketAccess = false }; }; template struct ei_packet_traits { typedef T type; enum {size=1}; }; template struct ei_unpacket_traits { typedef T type; enum {size=1}; }; template class ei_corrected_matrix_flags { enum { row_major_bit = (Rows != 1 && Cols != 1) // if this is not a vector, // then the storage order really matters, // so let us strictly honor the user's choice. ? SuggestedFlags&RowMajorBit : Cols > 1 ? RowMajorBit : 0, inner_max_size = row_major_bit ? MaxCols : MaxRows, is_big = inner_max_size == Dynamic, linear_size = Cols * Rows, packet_access_bit = ei_packet_traits::size > 1 && (is_big || linear_size%ei_packet_traits::size==0) ? PacketAccessBit : 0, aligned_bit = packet_access_bit && (is_big || linear_size%ei_packet_traits::size==0) ? AlignedBit : 0 }; public: enum { ret = (SuggestedFlags & ~(EvalBeforeNestingBit | EvalBeforeAssigningBit | PacketAccessBit | RowMajorBit)) | LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit | aligned_bit }; }; template struct ei_size_at_compile_time { enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols }; }; template::Flags&SparseBit> class ei_eval; template class ei_eval { typedef typename ei_traits::Scalar _Scalar; enum {_Rows = ei_traits::RowsAtCompileTime, _Cols = ei_traits::ColsAtCompileTime, _MaxRows = ei_traits::MaxRowsAtCompileTime, _MaxCols = ei_traits::MaxColsAtCompileTime, _Flags = ei_traits::Flags }; public: typedef Matrix<_Scalar, _Rows, _Cols, _MaxRows, _MaxCols, ei_corrected_matrix_flags< _Scalar, _Rows, _Cols, _MaxRows, _MaxCols, _Flags >::ret > type; }; template struct ei_unref { typedef T type; }; template struct ei_unref { typedef T type; }; template struct ei_unconst { typedef T type; }; template struct ei_unconst { typedef T type; }; template struct ei_cleantype { typedef T type; }; template struct ei_cleantype { typedef T type; }; template struct ei_cleantype { typedef T type; }; template struct ei_cleantype { typedef T type; }; template struct ei_must_nest_by_value { enum { ret = false }; }; template struct ei_must_nest_by_value > { enum { ret = true }; }; template::type> struct ei_nested { typedef typename ei_meta_if< ei_must_nest_by_value::ret, T, typename ei_meta_if< (int(ei_traits::Flags) & EvalBeforeNestingBit) || ((n+1) * int(NumTraits::Scalar>::ReadCost) <= (n-1) * int(T::CoeffReadCost)), EvalType, const T& >::ret >::ret type; }; template struct ei_are_flags_consistent { enum { ret = !( (Flags&UnitDiagBit && Flags&ZeroDiagBit) ) }; }; /** \internal Gives the type of a sub-matrix or sub-vector of a matrix of type \a ExpressionType and size \a Size * TODO: could be a good idea to define a big ReturnType struct ?? */ template struct BlockReturnType { typedef Block::RowsAtCompileTime == 1 ? 1 : RowsOrSize), (ei_traits::ColsAtCompileTime == 1 ? 1 : RowsOrSize)> SubVectorType; typedef Block Type; }; #endif // EIGEN_META_H