30 #ifndef __typetraits_HPP
31 #define __typetraits_HPP 1
33 #include <boost/concept_check.hpp>
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>
51 #if !defined( FEELPP_TRAITS_HPP)
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 );
61 #if defined FEELPP_HAS_ARPREC
62 inline mp_real_temp floor( mp_real
const& m )
64 if ( m >0 ) return ::aint( m );
68 inline mp_real_temp ceil( mp_real
const& m )
70 if ( m >0 )return ::aint( m+1 );
74 #endif // FEELPP_HAS_ARPREC
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)
88 #define FEELPP_STD_FUNCS \
89 BOOST_PP_TUPLE_TO_LIST( \
92 (abs , std::abs , abs ), \
93 (sqrt , std::sqrt , sqrt ), \
94 (norm1 , std::abs , abs ), \
95 (norm2 , std::abs , abs ), \
96 (norm_inf , std::abs , abs ), \
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) \
114 #define FEELPP_STDCOMPLEX_FUNCS \
115 BOOST_PP_TUPLE_TO_LIST( \
118 (abs , std::abs , abs ), \
119 (sqrt , std::sqrt , sqrt ), \
120 (norm1 , std::abs , abs ), \
121 (norm2 , std::abs , abs ), \
122 (norm_inf , std::abs , abs ), \
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 ) \
132 #define FEELPP_STD_BINARY_FUNCS \
133 BOOST_PP_TUPLE_TO_LIST( \
136 (pow , std::pow, pow ) \
141 #define FEELPP_MP_FUNCS \
142 BOOST_PP_TUPLE_TO_LIST( \
145 (abs , mpfr::abs , abs ), \
146 (sqrt , mpfr::sqrt , sqrt ), \
147 (norm1 , mpfr::abs , abs ), \
148 (norm2 , mpfr::abs , abs ), \
149 (norm_inf , mpfr::abs , abs ), \
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) \
168 #define FEELPP_MP_BINARY_FUNCS \
169 BOOST_PP_TUPLE_TO_LIST( \
172 (pow , mpfr::pow, pow ) \
177 #define FEELPP_GLOBAL_FUNCS \
178 BOOST_PP_TUPLE_TO_LIST( \
181 (abs , ::abs , abs ), \
182 (sqrt , ::sqrt , sqrt ), \
183 (norm1 , ::abs , abs ), \
184 (norm2 , ::abs , abs ), \
185 (norm_inf , ::abs , abs ), \
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) \
203 #define FEELPP_GLOBAL_BINARY_FUNCS \
204 BOOST_PP_TUPLE_TO_LIST( \
207 (pow , ::npwr, npwr ) \
214 # define FEELPP_TRAITS_FUNC_REAL(T, t) \
215 BOOST_PP_IF( FEELPP_TRAITS_IS_COMPLEX(T), \
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 ) ) )() \
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 ) )() \
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
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)
245 const double factor_from_eps = 50;
246 const float factor_from_eps_fl = 50;
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 ),
256 #endif // FEELPP_HAS_QD_H
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
262 #define MPFR_NTYPES 0
264 #endif // FEELPP_HAS_MPFR
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, \
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 ) \
283 # define FEELPP_TRAITS_OP(_, T) \
284 FEELPP_TRAITS_OP_CODE T \
287 #define FEELPP_TRAITS_OP_CODE(T) \
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; \
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 ); } \
302 FEELPP_TRAITS_REAL_TYPE( T ) real( FEELPP_TRAITS_TYPE( T ) const& t ) \
304 boost::ignore_unused_variable_warning(t); \
305 return FEELPP_TRAITS_FUNC_REAL( T, t ); \
308 FEELPP_TRAITS_REAL_TYPE( T ) imag ( FEELPP_TRAITS_TYPE( T ) const& t ) \
310 boost::ignore_unused_variable_warning(t); \
311 return FEELPP_TRAITS_FUNC_IMAG( T, t ); \
314 FEELPP_TRAITS_TYPE( T ) conj ( FEELPP_TRAITS_TYPE( T ) const& t) \
316 boost::ignore_unused_variable_warning(t); \
317 return FEELPP_TRAITS_FUNC_CONJ( T, t ); \
325 BOOST_PP_LIST_FOR_EACH_PRODUCT( FEELPP_TRAITS_OP, 1, ( FEELPP_TRAITS_TYPES ) )
330 # define FEELPP_PRED_FUNC(d, data, elem) BOOST_PP_EQUAL(FEELPP_TRAITS_FUNC_TYPE(elem), data)
335 # define FEELPP_UNARY_FUNCS_OP(_,TF) \
336 FEELPP_UNARY_FUNCS_OP_CODE TF \
339 # define FEELPP_UNARY_FUNCS_OP_CODE(T,F) \
341 FEELPP_TRAITS_TYPE( T ) FEELPP_FUNC_NAME( F )( FEELPP_TRAITS_TYPE( T ) const& t ) \
343 return FEELPP_FUNC_CALL( F )( t ); \
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 ) )
355 # define FEELPP_BINARY_FUNCS_OP(_,TF) \
356 FEELPP_BINARY_FUNCS_OP_CODE TF \
359 # define FEELPP_BINARY_FUNCS_OP_CODE(T,F) \
360 template<typename Type2> \
362 FEELPP_TRAITS_TYPE( T ) FEELPP_FUNC_NAME( F )( FEELPP_TRAITS_TYPE( T ) const& x, Type2 const& y ) \
364 return FEELPP_FUNC_CALL( F )( x, y ); \
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 ) )
377 #if defined( FEELPP_HAS_QD_H )
388 template <>
struct promote_code<dd_real>
390 static const int value = 6000;
392 template <>
struct promote_code<qd_real>
394 static const int value = 7000;
#define FEELPP_UNARY_FUNCS_OP(_, TF)
Definition: typetraits.hpp:335
#define FEELPP_BINARY_FUNCS_OP(_, TF)
Definition: typetraits.hpp:355