Logo  0.95.0-final
Finite Element Embedded Library and Language in C++
Feel++ Feel++ on Github Feel++ community
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
typetraits.hpp
Go to the documentation of this file.
1 /* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
2 
3  This file is part of the Feel library
4 
5  Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
6  Date: 2005-07-28
7 
8  Copyright (C) 2009 Université de Grenoble 1
9  Copyright (C) 2005,2006 EPFL
10 
11  This library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU Lesser General Public
13  License as published by the Free Software Foundation; either
14  version 3.0 of the License, or (at your option) any later version.
15 
16  This library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public
22  License along with this library; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
30 #ifndef __typetraits_HPP
31 #define __typetraits_HPP 1
32 
33 #include <boost/concept_check.hpp>
34 
35 #include <boost/preprocessor/comparison/less.hpp>
36 #include <boost/preprocessor/comparison/equal.hpp>
37 #include <boost/preprocessor/logical/and.hpp>
38 #include <boost/preprocessor/control/if.hpp>
39 #include <boost/preprocessor/list/at.hpp>
40 #include <boost/preprocessor/list/cat.hpp>
41 #include <boost/preprocessor/list/for_each_product.hpp>
42 #include <boost/preprocessor/logical/or.hpp>
43 #include <boost/preprocessor/tuple/to_list.hpp>
44 #include <boost/preprocessor/tuple/eat.hpp>
45 #include <boost/preprocessor/facilities/empty.hpp>
46 #include <boost/preprocessor/punctuation/comma.hpp>
47 #include <boost/preprocessor/facilities/identity.hpp>
48 #include <boost/preprocessor/arithmetic/add.hpp>
49 #include <boost/preprocessor/list/filter.hpp>
50 
51 #if !defined( FEELPP_TRAITS_HPP)
52 //#error feel/feelcore/typetraits.hpp must not be used directly, use feel/feelcore/traits.hpp instead
53 #endif
54 
55 #if defined( FEELPP_HAS_QD_H )
56 qd_real floor( const qd_real &a );
57 qd_real ceil( const qd_real &a );
58 qd_real npwr( const qd_real &a, int n );
59 #endif
60 
61 #if defined FEELPP_HAS_ARPREC
62 inline mp_real_temp floor( mp_real const& m )
63 {
64  if ( m >0 ) return ::aint( m );
65 
66  return ::aint( m-1 );
67 }
68 inline mp_real_temp ceil( mp_real const& m )
69 {
70  if ( m >0 )return ::aint( m+1 );
71 
72  return ::aint( m );
73 }
74 #endif // FEELPP_HAS_ARPREC
75 
76 namespace Feel
77 {
78 
79 template<typename T>
80 struct type_traits
81 {
82 };
83 
84 # define FEELPP_FUNC_NAME(T) BOOST_PP_TUPLE_ELEM(3, 0 , T)
85 # define FEELPP_FUNC_CALL(T) BOOST_PP_TUPLE_ELEM(3, 1 , T)
86 # define FEELPP_FUNC_NONS(T) BOOST_PP_TUPLE_ELEM(3, 2 , T)
87 
88 #define FEELPP_STD_FUNCS \
89 BOOST_PP_TUPLE_TO_LIST( \
90  19, \
91  ( \
92  (abs , std::abs , abs ), /* absolute value*/ \
93  (sqrt , std::sqrt , sqrt ), /* square root */ \
94  (norm1 , std::abs , abs ), /* norm1 */ \
95  (norm2 , std::abs , abs ), /* norm2 */ \
96  (norm_inf , std::abs , abs ), /* norm_inf */ \
97  (cos , std::cos , cos ), \
98  (sin , std::sin , sin ), \
99  (tan , std::tan , tan ), \
100  (acos , std::acos , acos ), \
101  (asin , std::asin , asin ), \
102  (atan , std::atan , atan ), \
103  (cosh , std::cosh , cosh ), \
104  (sinh , std::sinh , sinh ), \
105  (tanh , std::tanh , tanh ), \
106  (exp , std::exp , exp ), \
107  (log , std::log , log ), \
108  (log10 , std::log10, log10), \
109  (ceil , std::ceil , ceil ), \
110  (floor , std::floor, floor) \
111  ) \
112  ) \
113 
114 #define FEELPP_STDCOMPLEX_FUNCS \
115  BOOST_PP_TUPLE_TO_LIST( \
116  11, \
117  ( \
118  (abs , std::abs , abs ), /* absolute value*/ \
119  (sqrt , std::sqrt , sqrt ), /* square root */ \
120  (norm1 , std::abs , abs ), /* norm1 */ \
121  (norm2 , std::abs , abs ), /* norm2 */ \
122  (norm_inf , std::abs , abs ), /* norm_inf */ \
123  (cos , std::cos , cos ), \
124  (sin , std::sin , sin ), \
125  (tan , std::tan , tan ), \
126  (exp , std::exp , exp ), \
127  (log , std::log , log ), \
128  (log10 , std::log10, log10 ) \
129  ) \
130  ) \
131 
132 #define FEELPP_STD_BINARY_FUNCS \
133 BOOST_PP_TUPLE_TO_LIST( \
134  1, \
135  ( \
136  (pow , std::pow, pow ) \
137  ) \
138  ) \
139 
140 #
141 #define FEELPP_MP_FUNCS \
142 BOOST_PP_TUPLE_TO_LIST( \
143  18, \
144  ( \
145  (abs , mpfr::abs , abs ), /* absolute value*/ \
146  (sqrt , mpfr::sqrt , sqrt ), /* square root */ \
147  (norm1 , mpfr::abs , abs ), /* norm1 */ \
148  (norm2 , mpfr::abs , abs ), /* norm2 */ \
149  (norm_inf , mpfr::abs , abs ), /* norm_inf */ \
150  (cos , mpfr::cos , cos ), \
151  (sin , mpfr::sin , sin ), \
152  (tan , mpfr::tan , tan ), \
153  (acos , mpfr::acos , acos ), \
154  (asin , mpfr::asin , asin ), \
155  (atan , mpfr::atan , atan ), \
156  (cosh , mpfr::cosh , cosh ), \
157  (sinh , mpfr::sinh , sinh ), \
158  (tanh , mpfr::tanh , tanh ), \
159  (exp , mpfr::exp , exp ), \
160  (log , mpfr::log , log ), \
161  (ceil , mpfr::ceil , ceil ), \
162  (floor , mpfr::floor, floor) \
163  ) \
164  ) \
165 
166 #
167 #
168 #define FEELPP_MP_BINARY_FUNCS \
169 BOOST_PP_TUPLE_TO_LIST( \
170  1, \
171  ( \
172  (pow , mpfr::pow, pow ) \
173  ) \
174  ) \
175 
176 #
177 #define FEELPP_GLOBAL_FUNCS \
178 BOOST_PP_TUPLE_TO_LIST( \
179  18, \
180  ( \
181  (abs , ::abs , abs ), /* absolute value*/ \
182  (sqrt , ::sqrt , sqrt ), /* square root */ \
183  (norm1 , ::abs , abs ), /* norm1 */ \
184  (norm2 , ::abs , abs ), /* norm2 */ \
185  (norm_inf , ::abs , abs ), /* norm_inf */ \
186  (cos , ::cos , cos ), \
187  (sin , ::sin , sin ), \
188  (tan , ::tan , tan ), \
189  (acos , ::acos , acos ), \
190  (asin , ::asin , asin ), \
191  (atan , ::atan , atan ), \
192  (cosh , ::cosh , cosh ), \
193  (sinh , ::sinh , sinh ), \
194  (tanh , ::tanh , tanh ), \
195  (exp , ::exp , exp ), \
196  (log , ::log , log ), \
197  (ceil , ::ceil , ceil ), \
198  (floor , ::floor, floor) \
199  ) \
200  ) \
201 
202 #
203 #define FEELPP_GLOBAL_BINARY_FUNCS \
204 BOOST_PP_TUPLE_TO_LIST( \
205  1, \
206  ( \
207  (pow , ::npwr, npwr ) \
208  ) \
209  ) \
210 
211 
212 #
213 #if 1
214 # define FEELPP_TRAITS_FUNC_REAL(T, t) \
215  BOOST_PP_IF( FEELPP_TRAITS_IS_COMPLEX(T), \
216  t.real(), \
217  t ) \
218 
219 #
220 # define FEELPP_TRAITS_FUNC_IMAG(T, t) \
221  BOOST_PP_IF( FEELPP_TRAITS_IS_COMPLEX(T), \
222  BOOST_PP_IDENTITY( t.imag() ), \
223  BOOST_PP_IDENTITY( FEELPP_TRAITS_REAL_TYPE(T)( 0.0 ) ) )() \
224 
225 #
226 # define FEELPP_TRAITS_FUNC_CONJ(T, t) \
227  BOOST_PP_IF( FEELPP_TRAITS_IS_COMPLEX(T), \
228  BOOST_PP_IDENTITY( std::conj( t ) ), \
229  BOOST_PP_IDENTITY( t ) )() \
230 
231 #else
232 # define FEELPP_TRAITS_FUNC_REAL(T, t) t
233 # define FEELPP_TRAITS_FUNC_IMAG(T, t) 0.0
234 # define FEELPP_TRAITS_FUNC_CONJ(T, t) t
235 #endif
236 #
237 # define FEELPP_TRAITS_TYPE(T) BOOST_PP_TUPLE_ELEM(7, 0 , T)
238 # define FEELPP_TRAITS_REAL_TYPE(T) BOOST_PP_TUPLE_ELEM(7, 1 , T)
239 # define FEELPP_TRAITS_IS_FLOATING(T) BOOST_PP_TUPLE_ELEM(7, 2 , T)
240 # define FEELPP_TRAITS_IS_COMPLEX(T) BOOST_PP_TUPLE_ELEM(7, 3 , T)
241 # define FEELPP_TRAITS_RANK(T) BOOST_PP_TUPLE_ELEM(7, 4 , T)
242 # define FEELPP_TRAITS_EPSILON(T) BOOST_PP_TUPLE_ELEM(7, 5 , T)
243 # define FEELPP_TRAITS_FUNC_TYPE(T) BOOST_PP_TUPLE_ELEM(7, 6 , T)
244 #
245 const double factor_from_eps = 50;
246 const float factor_from_eps_fl = 50;
247 
248 #if defined( FEELPP_HAS_QD_H )
249 #define QD_DD_TYPE ( dd_real, dd_real, 1, 0, 11, dd_real::_eps*factor_from_eps , 2 ),
250 #define QD_QD_TYPE ( qd_real, qd_real, 1, 0, 12, qd_real::_eps*factor_from_eps , 2 ),
251 #define QD_NTYPES 2
252 #else
253 #define QD_NTYPES 0
254 #define QD_DD_TYPE
255 #define QD_QD_TYPE
256 #endif // FEELPP_HAS_QD_H
257 
258 #if defined( FEELPP_HAS_MPFR )
259 #define MPFR_MP_TYPE ( mp_type, mp_type, 1, 0, 10 , mp_eps*factor_from_eps, 1 ),
260 #define MPFR_NTYPES 1
261 #else
262 #define MPFR_NTYPES 0
263 #define MPFR_MP_TYPE
264 #endif // FEELPP_HAS_MPFR
265 
266 #define FEELPP_NUMERICAL_NTYPES BOOST_PP_ADD(4, BOOST_PP_ADD( QD_NTYPES, MPFR_NTYPES ) )
267 # define FEELPP_TRAITS_TYPES \
268  BOOST_PP_TUPLE_TO_LIST( \
269  FEELPP_NUMERICAL_NTYPES, \
270  ( \
271  QD_DD_TYPE \
272  QD_QD_TYPE \
273  MPFR_MP_TYPE \
274  ( float , float , 1, 0, 7 , std::numeric_limits<float>::epsilon()*factor_from_eps_fl , 0 ), \
275  ( double , double , 1, 0, 8 , std::numeric_limits<double>::epsilon()*factor_from_eps, 0 ), \
276  ( std::complex<float>, float, 1, 1, 10, std::numeric_limits<float>::epsilon()*factor_from_eps_fl , 3 ), \
277  ( std::complex<double>, double, 1, 1, 11, std::numeric_limits<double>::epsilon()*factor_from_eps , 3 ) \
278  ) \
279  ) \
280 
281 #
282 # /* Generates code for all integral types. */
283 # define FEELPP_TRAITS_OP(_, T) \
284  FEELPP_TRAITS_OP_CODE T \
285 
286 #
287 #define FEELPP_TRAITS_OP_CODE(T) \
288 template<> \
289 struct type_traits<FEELPP_TRAITS_TYPE( T )> { \
290  typedef type_traits<FEELPP_TRAITS_TYPE( T )> self_type; \
291  typedef FEELPP_TRAITS_TYPE( T ) value_type; \
292  typedef const value_type &const_reference; \
293  typedef value_type &reference; \
294  typedef FEELPP_TRAITS_REAL_TYPE( T ) real_type; \
295  typedef FEELPP_TRAITS_REAL_TYPE( T ) precision_type; \
296  \
297  static const bool is_floating = FEELPP_TRAITS_IS_FLOATING( T ); \
298  static const uint16_type rank = FEELPP_TRAITS_RANK( T ); \
299  static real_type epsilon() { return FEELPP_TRAITS_EPSILON( T ); } \
300 }; \
301 inline \
302 FEELPP_TRAITS_REAL_TYPE( T ) real( FEELPP_TRAITS_TYPE( T ) const& t ) \
303 { \
304  boost::ignore_unused_variable_warning(t); \
305  return FEELPP_TRAITS_FUNC_REAL( T, t ); \
306 } \
307 inline \
308 FEELPP_TRAITS_REAL_TYPE( T ) imag ( FEELPP_TRAITS_TYPE( T ) const& t ) \
309 { \
310  boost::ignore_unused_variable_warning(t); \
311  return FEELPP_TRAITS_FUNC_IMAG( T, t ); \
312 } \
313 inline \
314 FEELPP_TRAITS_TYPE( T ) conj ( FEELPP_TRAITS_TYPE( T ) const& t) \
315 { \
316  boost::ignore_unused_variable_warning(t); \
317  return FEELPP_TRAITS_FUNC_CONJ( T, t ); \
318 } \
319 
320 
321 
325 BOOST_PP_LIST_FOR_EACH_PRODUCT( FEELPP_TRAITS_OP, 1, ( FEELPP_TRAITS_TYPES ) )
326 
327 namespace math
328 {
329 #
330 # define FEELPP_PRED_FUNC(d, data, elem) BOOST_PP_EQUAL(FEELPP_TRAITS_FUNC_TYPE(elem), data)
331 #
332 
335 # define FEELPP_UNARY_FUNCS_OP(_,TF) \
336  FEELPP_UNARY_FUNCS_OP_CODE TF \
337 
338 #
339 # define FEELPP_UNARY_FUNCS_OP_CODE(T,F) \
340  inline \
341  FEELPP_TRAITS_TYPE( T ) FEELPP_FUNC_NAME( F )( FEELPP_TRAITS_TYPE( T ) const& t ) \
342  { \
343  return FEELPP_FUNC_CALL( F )( t ); \
344  } \
345 
346 #
347 BOOST_PP_LIST_FOR_EACH_PRODUCT( FEELPP_UNARY_FUNCS_OP, 2, ( BOOST_PP_LIST_FILTER( FEELPP_PRED_FUNC, 0, FEELPP_TRAITS_TYPES ), FEELPP_STD_FUNCS ) )
348 BOOST_PP_LIST_FOR_EACH_PRODUCT( FEELPP_UNARY_FUNCS_OP, 2, ( BOOST_PP_LIST_FILTER( FEELPP_PRED_FUNC, 1, FEELPP_TRAITS_TYPES ), FEELPP_MP_FUNCS ) )
349 BOOST_PP_LIST_FOR_EACH_PRODUCT( FEELPP_UNARY_FUNCS_OP, 2, ( BOOST_PP_LIST_FILTER( FEELPP_PRED_FUNC, 2, FEELPP_TRAITS_TYPES ), FEELPP_GLOBAL_FUNCS ) )
350 BOOST_PP_LIST_FOR_EACH_PRODUCT( FEELPP_UNARY_FUNCS_OP, 2, ( BOOST_PP_LIST_FILTER( FEELPP_PRED_FUNC, 3, FEELPP_TRAITS_TYPES ), FEELPP_STDCOMPLEX_FUNCS ) )
351 
355 # define FEELPP_BINARY_FUNCS_OP(_,TF) \
356  FEELPP_BINARY_FUNCS_OP_CODE TF \
357 
358 #
359 # define FEELPP_BINARY_FUNCS_OP_CODE(T,F) \
360  template<typename Type2> \
361  inline \
362  FEELPP_TRAITS_TYPE( T ) FEELPP_FUNC_NAME( F )( FEELPP_TRAITS_TYPE( T ) const& x, Type2 const& y ) \
363  { \
364  return FEELPP_FUNC_CALL( F )( x, y ); \
365  } \
366 
367 #
368 BOOST_PP_LIST_FOR_EACH_PRODUCT( FEELPP_BINARY_FUNCS_OP, 2, ( BOOST_PP_LIST_FILTER( FEELPP_PRED_FUNC, 0, FEELPP_TRAITS_TYPES ), FEELPP_STD_BINARY_FUNCS ) )
369 BOOST_PP_LIST_FOR_EACH_PRODUCT( FEELPP_BINARY_FUNCS_OP, 2, ( BOOST_PP_LIST_FILTER( FEELPP_PRED_FUNC, 1, FEELPP_TRAITS_TYPES ), FEELPP_MP_BINARY_FUNCS ) )
370 BOOST_PP_LIST_FOR_EACH_PRODUCT( FEELPP_BINARY_FUNCS_OP, 2, ( BOOST_PP_LIST_FILTER( FEELPP_PRED_FUNC, 2, FEELPP_TRAITS_TYPES ), FEELPP_GLOBAL_BINARY_FUNCS ) )
371 } // math
372 
373 
374 
375 } // Feel
376 
377 #if defined( FEELPP_HAS_QD_H )
378 //
379 // make dd_real/qd_real known to boost::lambda
380 //
381 namespace boost
382 {
383 namespace lambda
384 {
385 namespace detail
386 {
387 
388 template <> struct promote_code<dd_real>
389 {
390  static const int value = 6000;
391 };
392 template <> struct promote_code<qd_real>
393 {
394  static const int value = 7000;
395 };
396 
397 } // namespace detail
398 } // namespace lambda
399 } // namespace boost
400 
401 #endif /* FEELPP_HAS_QD_H */
402 
403 #endif /* __typetraits_H */

Generated on Fri Oct 25 2013 14:24:26 for Feel++ by doxygen 1.8.4