aimstil  5.0.5
traits.h
Go to the documentation of this file.
1 #ifndef TIL_TRAITS_H
2 #define TIL_TRAITS_H
3 
4 // include from STL
5 #include <limits>
6 
7 // includes from BOOST
8 #include "boost/call_traits.hpp"
9 #include "boost/type_traits.hpp"
10 #include "boost/utility/enable_if.hpp"
11 
12 // includes from TIL library
13 #include "til/til_common.h"
14 #include "til/til_declarations.h"
15 #include "til/templateTools.h"
16 
17 namespace til {
18 
19 #define TIL_COMMA ,
20 
21  //------------------------------------------------------------------------------
22 
23  //----------------//
24  // require_that //
25  //----------------//
26 
27  template < bool B > class require_that;
28  template <> class require_that<true> {};
29 
30  //------------------------------------------------------------------------------
31 
32  //-------------//
33  // precision //
34  //-------------//
35 
47  template < typename T >
48  struct precision { };
49 
51 #define TIL_DEFINE_PRECISION_FOR_NUMERIC_TYPES(argtype) \
52  template <> \
53  struct precision< argtype > \
54  { typedef argtype type; };
55 
57 
58  // If you happen to have build another base numeric class, like double_double,
59  // simply add a similar precision class. For all other non-fundamental classes,
60  // and this includes complex number, rational fraction, etc., the precision should
61  // reflect the encoding.
62 
63 #undef TIL_DEFINE_PRECISION_FOR_NUMERIC_TYPES
64 
65  // A macro to define specialization of precision trait.
66  // The template argument on which recursion is done has to be named 'T'.
67  // NB: to be undefined at the end of the definitions
68 #define DEFINE_PRECISION_RECURSIVE_SPECIALIZATION_T(argtype, targs) \
69  template < targs > \
70  struct precision< argtype > \
71  { typedef typename precision<T>::type type; } \
72 
73 #define DEFINE_PRECISION_RECURSIVE_SPECIALIZATION(argtype) \
74  DEFINE_PRECISION_RECURSIVE_SPECIALIZATION_T(argtype, typename T)
75 
76  // Specialization for images
80 
81  // Specialization for vectors
82  //DEFINE_PRECISION_RECURSIVE_SPECIALIZATION_T(Vector<T TIL_COMMA D TIL_COMMA TStorage>, typename T TIL_COMMA std::size_t D TIL_COMMA typename TStorage);
83 
84  // Specialization for points
85  //DEFINE_PRECISION_RECURSIVE_SPECIALIZATION_T(Point<T TIL_COMMA D TIL_COMMA TStorage>, typename T TIL_COMMA std::size_t D TIL_COMMA typename TStorage);
86 
87  // Specialization for arrays
88  DEFINE_PRECISION_RECURSIVE_SPECIALIZATION_T(numeric_array<T TIL_COMMA D>, typename T TIL_COMMA std::size_t D);
89  DEFINE_PRECISION_RECURSIVE_SPECIALIZATION_T(sparse_vector<T TIL_COMMA BaselinePolicy>, typename T TIL_COMMA typename BaselinePolicy);
90 
91  // Specialization for matrix
94 
95 #undef DEFINE_PRECISION_RECURSIVE_SPECIALIZATION
96 
97  //------------------------------------------------------------------------------
98 
99  //--------------------//
100  // change_precision //
101  //--------------------//
102 
105  template < typename T, typename TNewPrecision >
106  struct change_precision {};
107 
108  // A macro to define change_precision for numerical types.
109  // NB: to be undef'd before the end of this file.
110 #define TIL_DEFINE_CHANGE_PRECISION_FOR_NUMERIC_TYPES(argtype) \
111  template < typename TNewPrecision > \
112  struct change_precision< argtype, TNewPrecision > \
113  { \
114  typedef TNewPrecision type; \
115  private: \
116  typedef typename enable_if_c<std::numeric_limits<TNewPrecision>::is_specialized>::type CheckIsNumeric; \
117  }; \
118 
120 
121 #undef TIL_DEFINE_CHANGE_PRECISION_FOR_NUMERIC_TYPES
122 
123 
124  // A macro to define change_precision recursively for non-numerical types.
125  // NB: to be undef'd before the end of this file.
126 #define TIL_DEFINE_CHANGE_PRECISION_RECURSIVE_SPECIALIZATION_T(argtype, targs) \
127  template < targs , typename TNewPrecision> \
128  struct change_precision< argtype , TNewPrecision> \
129  { \
130  typedef typename change_precision<T, TNewPrecision>::type type; \
131  private: \
132  typedef typename enable_if_c<std::numeric_limits<TNewPrecision>::is_specialized>::type CheckIsNumeric; \
133  }; \
134 
135 
136 #define TIL_DEFINE_CHANGE_PRECISION_RECURSIVE_SPECIALIZATION(argtype) \
137  TIL_DEFINE_CHANGE_PRECISION_RECURSIVE_SPECIALIZATION_T(argtype, typename T)
138 
139 
140  // Specialization for images
144 
145  // Specialization for vectors
146  //TIL_DEFINE_CHANGE_PRECISION_RECURSIVE_SPECIALIZATION_T(Vector<T TIL_COMMA D TIL_COMMA TStorage>, typename T TIL_COMMA std::size_t D TIL_COMMA typename TStorage);
147 
148  // Specialization for matrix
151 
152 
153 
154  //------------------------------------------------------------------------------
155 
156  //-----------//
157  // combine //
158  //-----------//
159 
161  template < typename T1, typename T2 >
162  struct combine
163  {
164  typedef typename type_if<
165  // We choose T1 if T1 is floating point and T2 is not...
166  (!std::numeric_limits<T1>::is_integer && std::numeric_limits<T2>::is_integer) ||
167  // or, if not (T2 is floating and T1 is not) and...
168  ((!std::numeric_limits<T1>::is_integer || std::numeric_limits<T2>::is_integer) &&
169  // if encoding of T1 is larger than T2
170  (sizeof(T1) >= sizeof(T2))),
171  T1, T2 >::type type;
172  // NB: Note that we are in deep trouble if T1 and T2 have the same size and
173  // are both either integer or floating point, because then when arbitrarily
174  // chose T1...
175  // TODO: How is it done in the compiler?
176  };
177 
178  //------------------------------------------------------------------------------
179 
180  /*
181  template < typename TFunctor, typename T1, typename T2, >
182  struct result_of
183  {
184  };
185  */
186 
187  //------------------------------------------------------------------------------
188 
189  //--------------//
190  // value_type //
191  //--------------//
192 
197  template < typename T >
199  {
200  typedef typename T::value_type type;
201  };
202 
206  template < typename T >
207  struct value_type_of<T*>
208  {
209  typedef T type;
210  };
211 
220  template < typename T >
221  struct value_type_of<T&>
222  {
223  typedef typename value_type_of<T>::type type;
224  };
225 
227  template <>
229  {
230  typedef None type;
231  };
232 
233 
234  //------------------------------------------------------------------------------
235 
236  //-----------------//
237  // deref //
238  //-----------------//
239 
241  template < typename T >
242  struct deref
243  {
244  typedef typename T::reference type;
245  };
246 
247  template < typename T >
248  struct deref<T*>
249  {
250  typedef T & type;
251  };
252 
253  //------------------------------------------------------------------------------
254 
255  /*
256  //----------------//
257  // if_then_else //
258  //----------------//
259 
260  template < bool B, typename TTrue, typename TFalse >
261  struct if_then_else
262  {
263  typedef TTrue type;
264  };
265 
266  template < typename TTrue, typename TFalse >
267  struct if_then_else<false, TTrue, TFalse >
268  {
269  typedef TFalse type;
270  };
271  */
272 
273  //------------------------------------------------------------------------------
274 
275  // Actually, can't work, because sometimes we want the return value like Vactor<T,3>, that doesn't
276  // fit the template template parameter format.
277  template < template <typename> class TReturn >
279  {
280  template < typename T >
281  struct result_type
282  {
283  typedef TReturn<T> type;
284  };
285  };
286 
287 
288  //------------------------------------------------------------------------------
289 
290  //------------//
291  // range_of //
292  //------------//
293 
294  template < typename T >
295  struct range_of
296  { typedef typename T::range type; };
297 
298  template < typename T >
299  struct range_of<const T>
300  { typedef typename T::const_range type; };
301 
302  //------------------//
303  // const_range_of //
304  //------------------//
305 
306  template < typename T >
308  { typedef typename T::const_range type; };
309 
310 
311  //------------------------------------------------------------------------------
312 
313  //----------------//
314  // reference_of //
315  //----------------//
316 
318  template < typename T >
320  : public type_if<boost::is_const<T>::value, typename T::const_reference, typename T::reference>
321  {};
322 
323  //------------------------------------------------------------------------------
324 
325  //---------//
326  // opti // (was: param)
327  //---------//
328 
330  template < typename T >
331  struct opti
332  //: public type_if<boost::is_stateless<T>::value, T, typename boost::call_traits<T>::param_type>
333  : public type_if<boost::is_empty<T>::value, T, typename boost::call_traits<T>::param_type>
334  {};
335 
336 
337  //------------------------------------------------------------------------------
338 
339  //-------------//
340  // is_signed //
341  //-------------//
342 
343  template < typename T >
344  struct is_signed
345  : public type_if<std::numeric_limits<T>::is_signed, true_type, false_type>::type
346  {};
347 
348  //------------------------------------------------------------------------------
349 
350  //--------------//
351  // is_integer //
352  //--------------//
353 
354  template < typename T >
355  struct is_integer
356  : public type_if<std::numeric_limits<T>::is_integer, true_type, false_type>::type
357  {};
358 
359  //------------------------------------------------------------------------------
360 
361  //---------------------//
362  // is_floating_point //
363  //---------------------//
364 
365  // NB: small subtelty: we have to check that T is not an integer, but also that T is a number!
366  template < typename T >
368  : public type_if<std::numeric_limits<T>::is_specialized && !std::numeric_limits<T>::is_integer, true_type, false_type>::type
369  {};
370 
371  //------------------------------------------------------------------------------
372 
373  //-------------------//
374  // accumulation_of //
375  //-------------------//
376 
377  template < typename T >
378  struct accumulation_of {};
379 
380  template <>
381  struct accumulation_of<float> { typedef double type; };
382 
383  //------------------------------------------------------------------------------
384 
385 //#undef TIL_COMMA
386 
387 } // namespace
388 
389 
390 
391 #endif
Numerical precision of the data for storage classes.
Definition: traits.h:48
T::reference type
Definition: traits.h:244
T::const_range type
Definition: traits.h:300
DEFINE_PRECISION_RECURSIVE_SPECIALIZATION(ImageC< T >)
value_type_of< T >::type type
Definition: traits.h:223
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
#define TIL_DEFINE_PRECISION_FOR_NUMERIC_TYPES(argtype)
Specialization for numerical types.
Definition: traits.h:51
Returns T::reference or T::const_reference, depending on the constness of T.
Definition: traits.h:319
General macros, definitions and functions.
DEFINE_PRECISION_RECURSIVE_SPECIALIZATION_T(numeric_array< T TIL_COMMA D >, typename T TIL_COMMA std::size_t D)
A type representing the absence of a type.
Definition: til_common.h:82
This file contains forward declarations of classes defined in the TIL library.
TIL_DEFINE_CHANGE_PRECISION_RECURSIVE_SPECIALIZATION(ImageC< T >)
Type return by T when unitary T::operator*() is called.
Definition: traits.h:242
TIL_FOR_ALL_NUMERIC_TYPES(TIL_DEFINE_PRECISION_FOR_NUMERIC_TYPES)
#define TIL_DEFINE_CHANGE_PRECISION_FOR_NUMERIC_TYPES(argtype)
Definition: traits.h:110
type_if<(!std::numeric_limits< T1 >::is_integer &&std::numeric_limits< T2 >::is_integer)||((!std::numeric_limits< T1 >::is_integer||std::numeric_limits< T2 >::is_integer) &&(sizeof(T1) >=sizeof(T2))), T1, T2 >::type type
Definition: traits.h:171
T::range type
Definition: traits.h:296
Defines the return type of an operation between numbers of different types.
Definition: traits.h:162
Template to choose between one type or the other depending on some condition.
Definition: templateTools.h:61
Collects template tools used for library implementation.
Changing the numerical precision of an object.
Definition: traits.h:106
T::const_range type
Definition: traits.h:308
Externalization of the standard value_type member typedef.
Definition: traits.h:198
#define TIL_COMMA
Definition: traits.h:19
Return T is T is stateless^H^H^H^Hempty, otherwise boost::call_traits<T>::param_type.
Definition: traits.h:331
T::value_type type
Definition: traits.h:200