// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2008-2009 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 /** \internal * \file Meta.h * This file contains generic metaprogramming classes which are not specifically related to Eigen. * \note In case you wonder, yes we're aware that Boost already provides all these features, * we however don't want to add a dependency to Boost. */ struct ei_meta_true { enum { ret = 1 }; }; struct ei_meta_false { enum { ret = 0 }; }; 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 }; }; template struct ei_unref { typedef T type; }; template struct ei_unref { typedef T type; }; template struct ei_unpointer { typedef T type; }; template struct ei_unpointer { typedef T type; }; template struct ei_unpointer { typedef T type; }; template struct ei_unconst { typedef T type; }; template struct ei_unconst { 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 typename ei_cleantype::type type; }; template struct ei_cleantype { typedef typename ei_cleantype::type type; }; template struct ei_cleantype { typedef typename ei_cleantype::type type; }; template struct ei_cleantype { typedef typename ei_cleantype::type type; }; template struct ei_cleantype { typedef typename ei_cleantype::type type; }; template struct ei_is_arithmetic { enum { ret = false }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic{ enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template<> struct ei_is_arithmetic { enum { ret = true }; }; template struct ei_makeconst { typedef const T type; }; template struct ei_makeconst { typedef const T type; }; template struct ei_makeconst { typedef const T& type; }; template struct ei_makeconst { typedef const T& type; }; template struct ei_makeconst { typedef const T* type; }; template struct ei_makeconst { typedef const T* type; }; template struct ei_makeconst_return_type { typedef typename ei_meta_if::ret, T, typename ei_makeconst::type>::ret type; }; /** \internal Allows to enable/disable an overload * according to a compile time condition. */ template struct ei_enable_if; template struct ei_enable_if { typedef T type; }; /** \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. FIXME, that behavior is a pretty bad hack. */ 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; }; /** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer. * Usage example: \code ei_meta_sqrt<1023>::ret \endcode */ template Y))) > // use ?: instead of || just to shut up a stupid gcc 4.3 warning class ei_meta_sqrt { enum { MidX = (InfX+SupX)/2, TakeInf = MidX*MidX > Y ? 1 : 0, NewInf = int(TakeInf) ? InfX : int(MidX), NewSup = int(TakeInf) ? int(MidX) : SupX }; public: enum { ret = ei_meta_sqrt::ret }; }; template class ei_meta_sqrt { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; }; /** \internal determines whether the product of two numeric types is allowed and what the return type is */ template struct ei_scalar_product_traits; template struct ei_scalar_product_traits { //enum { Cost = NumTraits::MulCost }; typedef T ReturnType; }; template struct ei_scalar_product_traits > { //enum { Cost = 2*NumTraits::MulCost }; typedef std::complex ReturnType; }; template struct ei_scalar_product_traits, T> { //enum { Cost = 2*NumTraits::MulCost }; typedef std::complex ReturnType; }; // FIXME quick workaround around current limitation of ei_result_of // template // struct ei_result_of(ArgType0,ArgType1)> { // typedef typename ei_scalar_product_traits::type, typename ei_cleantype::type>::ReturnType type; // }; template struct ei_is_diagonal { enum { ret = false }; }; template struct ei_is_diagonal > { enum { ret = true }; }; template struct ei_is_diagonal > { enum { ret = true }; }; template struct ei_is_diagonal > { enum { ret = true }; }; #endif // EIGEN_META_H