Meta.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // Eigen is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of
15 // the License, or (at your option) any later version.
16 //
17 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Eigen. If not, see <http://www.gnu.org/licenses/>.
25 
26 #ifndef EIGEN_META_H
27 #define EIGEN_META_H
28 
29 namespace Eigen {
30 
31 namespace internal {
32 
40 struct true_type { enum { value = 1 }; };
41 struct false_type { enum { value = 0 }; };
42 
43 template<bool Condition, typename Then, typename Else>
44 struct conditional { typedef Then type; };
45 
46 template<typename Then, typename Else>
47 struct conditional <false, Then, Else> { typedef Else type; };
48 
49 template<typename T, typename U> struct is_same { enum { value = 0 }; };
50 template<typename T> struct is_same<T,T> { enum { value = 1 }; };
51 
52 template<typename T> struct remove_reference { typedef T type; };
53 template<typename T> struct remove_reference<T&> { typedef T type; };
54 
55 template<typename T> struct remove_pointer { typedef T type; };
56 template<typename T> struct remove_pointer<T*> { typedef T type; };
57 template<typename T> struct remove_pointer<T*const> { typedef T type; };
58 
59 template <class T> struct remove_const { typedef T type; };
60 template <class T> struct remove_const<const T> { typedef T type; };
61 template <class T> struct remove_const<const T[]> { typedef T type[]; };
62 template <class T, unsigned int Size> struct remove_const<const T[Size]> { typedef T type[Size]; };
63 
64 template<typename T> struct remove_all { typedef T type; };
65 template<typename T> struct remove_all<const T> { typedef typename remove_all<T>::type type; };
66 template<typename T> struct remove_all<T const&> { typedef typename remove_all<T>::type type; };
67 template<typename T> struct remove_all<T&> { typedef typename remove_all<T>::type type; };
68 template<typename T> struct remove_all<T const*> { typedef typename remove_all<T>::type type; };
69 template<typename T> struct remove_all<T*> { typedef typename remove_all<T>::type type; };
70 
71 template<typename T> struct is_arithmetic { enum { value = false }; };
72 template<> struct is_arithmetic<float> { enum { value = true }; };
73 template<> struct is_arithmetic<double> { enum { value = true }; };
74 template<> struct is_arithmetic<long double> { enum { value = true }; };
75 template<> struct is_arithmetic<bool> { enum { value = true }; };
76 template<> struct is_arithmetic<char> { enum { value = true }; };
77 template<> struct is_arithmetic<signed char> { enum { value = true }; };
78 template<> struct is_arithmetic<unsigned char> { enum { value = true }; };
79 template<> struct is_arithmetic<signed short> { enum { value = true }; };
80 template<> struct is_arithmetic<unsigned short>{ enum { value = true }; };
81 template<> struct is_arithmetic<signed int> { enum { value = true }; };
82 template<> struct is_arithmetic<unsigned int> { enum { value = true }; };
83 template<> struct is_arithmetic<signed long> { enum { value = true }; };
84 template<> struct is_arithmetic<unsigned long> { enum { value = true }; };
85 
86 template <typename T> struct add_const { typedef const T type; };
87 template <typename T> struct add_const<T&> { typedef T& type; };
88 
89 template <typename T> struct is_const { enum { value = 0 }; };
90 template <typename T> struct is_const<T const> { enum { value = 1 }; };
91 
92 template<typename T> struct add_const_on_value_type { typedef const T type; };
93 template<typename T> struct add_const_on_value_type<T&> { typedef T const& type; };
94 template<typename T> struct add_const_on_value_type<T*> { typedef T const* type; };
95 template<typename T> struct add_const_on_value_type<T* const> { typedef T const* const type; };
96 template<typename T> struct add_const_on_value_type<T const* const> { typedef T const* const type; };
97 
101 template<bool Condition, typename T> struct enable_if;
102 
103 template<typename T> struct enable_if<true,T>
104 { typedef T type; };
105 
106 
107 
111 class noncopyable
112 {
113  noncopyable(const noncopyable&);
114  const noncopyable& operator=(const noncopyable&);
115 protected:
116  noncopyable() {}
117  ~noncopyable() {}
118 };
119 
120 
128 template<typename T> struct result_of {};
129 
130 struct has_none {int a[1];};
131 struct has_std_result_type {int a[2];};
132 struct has_tr1_result {int a[3];};
133 
134 template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)>
135 struct unary_result_of_select {typedef ArgType type;};
136 
137 template<typename Func, typename ArgType>
138 struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
139 
140 template<typename Func, typename ArgType>
141 struct unary_result_of_select<Func, ArgType, sizeof(has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;};
142 
143 template<typename Func, typename ArgType>
144 struct result_of<Func(ArgType)> {
145  template<typename T>
146  static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
147  template<typename T>
148  static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0);
149  static has_none testFunctor(...);
150 
151  // note that the following indirection is needed for gcc-3.3
152  enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
153  typedef typename unary_result_of_select<Func, ArgType, FunctorType>::type type;
154 };
155 
156 template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)>
157 struct binary_result_of_select {typedef ArgType0 type;};
158 
159 template<typename Func, typename ArgType0, typename ArgType1>
160 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)>
161 {typedef typename Func::result_type type;};
162 
163 template<typename Func, typename ArgType0, typename ArgType1>
164 struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_tr1_result)>
165 {typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;};
166 
167 template<typename Func, typename ArgType0, typename ArgType1>
168 struct result_of<Func(ArgType0,ArgType1)> {
169  template<typename T>
170  static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
171  template<typename T>
172  static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0);
173  static has_none testFunctor(...);
174 
175  // note that the following indirection is needed for gcc-3.3
176  enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
177  typedef typename binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type;
178 };
179 
183 template<int Y,
184  int InfX = 0,
185  int SupX = ((Y==1) ? 1 : Y/2),
186  bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) >
187  // use ?: instead of || just to shut up a stupid gcc 4.3 warning
188 class meta_sqrt
189 {
190  enum {
191  MidX = (InfX+SupX)/2,
192  TakeInf = MidX*MidX > Y ? 1 : 0,
193  NewInf = int(TakeInf) ? InfX : int(MidX),
194  NewSup = int(TakeInf) ? int(MidX) : SupX
195  };
196  public:
197  enum { ret = meta_sqrt<Y,NewInf,NewSup>::ret };
198 };
199 
200 template<int Y, int InfX, int SupX>
201 class meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
202 
204 template<typename T, typename U> struct scalar_product_traits;
205 
206 template<typename T> struct scalar_product_traits<T,T>
207 {
208  //enum { Cost = NumTraits<T>::MulCost };
209  typedef T ReturnType;
210 };
211 
212 template<typename T> struct scalar_product_traits<T,std::complex<T> >
213 {
214  //enum { Cost = 2*NumTraits<T>::MulCost };
215  typedef std::complex<T> ReturnType;
216 };
217 
218 template<typename T> struct scalar_product_traits<std::complex<T>, T>
219 {
220  //enum { Cost = 2*NumTraits<T>::MulCost };
221  typedef std::complex<T> ReturnType;
222 };
223 
224 // FIXME quick workaround around current limitation of result_of
225 // template<typename Scalar, typename ArgType0, typename ArgType1>
226 // struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> {
227 // typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type;
228 // };
229 
230 template<typename T> struct is_diagonal
231 { enum { ret = false }; };
232 
233 template<typename T> struct is_diagonal<DiagonalBase<T> >
234 { enum { ret = true }; };
235 
236 template<typename T> struct is_diagonal<DiagonalWrapper<T> >
237 { enum { ret = true }; };
238 
239 template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
240 { enum { ret = true }; };
241 
242 } // end namespace internal
243 
244 } // end namespace Eigen
245 
246 #endif // EIGEN_META_H