Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_Traits.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Sacado Package
4 //
5 // Copyright 2006 NTESS and the Sacado contributors.
6 // SPDX-License-Identifier: LGPL-2.1-or-later
7 //
8 // ***********************************************************************
9 //
10 // The forward-mode AD classes in Sacado are a derivative work of the
11 // expression template classes in the Fad package by Nicolas Di Cesare.
12 // The following banner is included in the original Fad source code:
13 //
14 // ************ DO NOT REMOVE THIS BANNER ****************
15 //
16 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
17 // http://www.ann.jussieu.fr/~dicesare
18 //
19 // CEMRACS 98 : C++ courses,
20 // templates : new C++ techniques
21 // for scientific computing
22 //
23 //********************************************************
24 //
25 // NumericalTraits class to illustrate TRAITS
26 //
27 //********************************************************
28 // @HEADER
29 
30 #ifndef SACADO_TRAITS_HPP
31 #define SACADO_TRAITS_HPP
32 
33 #include <string>
34 #include <type_traits>
35 
36 #include "Sacado_ConfigDefs.h"
37 #include "Sacado_dummy_arg.hpp"
38 #include "Sacado_mpl_enable_if.hpp"
40 
41 #ifdef HAVE_SACADO_COMPLEX
42 #include <complex>
43 #endif
44 
45 namespace Sacado {
46 
51  enum DerivInit {
54  };
55 
57  template <typename T>
58  struct IsExpr {
59  static const bool value = false;
60  };
61 
63  template <typename T>
64  struct IsView {
65  static const bool value = false;
66  };
67 
69  template <typename T>
70  struct BaseExprType {
71  typedef T type;
72  };
73 
75  template <typename T,unsigned,unsigned> struct ViewFadType {};
76 
78  template <typename T> struct OverrideDefaultPromote {
79  static const bool value = false;
80  };
81 
83 
87  template <typename A, typename B, typename Enabled = void> struct Promote {};
88 
90  template <typename A>
91  struct Promote< A, A,
92  typename mpl::enable_if_c< !OverrideDefaultPromote<A>::value >::type > {
93  typedef typename BaseExprType<A>::type type;
94  };
95 
97  template <typename A, typename B>
98  struct Promote< A, B,
99  typename mpl::enable_if_c< std::is_convertible<A,B>::value &&
100  !std::is_convertible<B,A>::value &&
101  !OverrideDefaultPromote<A>::value &&
102  !OverrideDefaultPromote<B>::value
103  >::type > {
104  typedef typename BaseExprType<B>::type type;
105  };
106 
108  template <typename A, typename B>
109  struct Promote< A, B,
110  typename mpl::enable_if_c< std::is_convertible<B,A>::value &&
111  !std::is_convertible<A,B>::value &&
112  !OverrideDefaultPromote<A>::value &&
113  !OverrideDefaultPromote<B>::value
114  >::type > {
115  typedef typename BaseExprType<A>::type type;
116  };
117 
122  template <typename A, typename B>
123  struct Promote< A, B,
124  typename mpl::enable_if_c< std::is_convertible<A,B>::value &&
125  std::is_convertible<B,A>::value &&
126  !std::is_same<A,B>::value &&
127  ( IsExpr<A>::value ||
128  IsExpr<B>::value ) >::type >
129  {
133  };
134 
140  template <typename A, typename B>
141  struct Promote< A, B,
142  typename mpl::enable_if_c< !std::is_convertible<A,B>::value &&
143  !std::is_convertible<B,A>::value &&
144  IsExpr<A>::value &&
145  std::is_convertible< B, typename BaseExprType< typename A::value_type >::type >::value
146  >::type >
147  {
148  typedef typename BaseExprType<A>::type type;
149  };
150 
156  template <typename A, typename B>
157  struct Promote< A, B,
158  typename mpl::enable_if_c< !std::is_convertible<A,B>::value &&
159  !std::is_convertible<B,A>::value &&
160  IsExpr<B>::value &&
161  std::is_convertible< A, typename BaseExprType< typename B::value_type >::type >::value
162  >::type >
163  {
164  typedef typename BaseExprType<B>::type type;
165  };
166 
172  template <typename A, typename B>
173  struct Promote< A, B,
174  typename mpl::enable_if_c< !std::is_convertible<A,B>::value &&
175  !std::is_convertible<B,A>::value &&
176  IsExpr<A>::value &&
177  IsExpr<B>::value &&
178  std::is_same< typename BaseExprType< typename A::value_type >::type,
179  typename BaseExprType< typename B::value_type >::type >::value
180  >::type >
181  {
185  };
186 
188 #define SACADO_PROMOTE_SPECIALIZATION(type1,type2,type3) \
189  template <> struct Promote< type1, type2, void > { \
190  typedef type3 type; \
191  }; \
192  template <> struct Promote< type2, type1, void > { \
193  typedef type3 type; \
194  };
195 
196  SACADO_PROMOTE_SPECIALIZATION(double,float,double)
197  SACADO_PROMOTE_SPECIALIZATION(double,long,double)
198  SACADO_PROMOTE_SPECIALIZATION(double,int,double)
199  SACADO_PROMOTE_SPECIALIZATION(float,long,float)
200  SACADO_PROMOTE_SPECIALIZATION(float,int,float)
201 #ifdef HAVE_SACADO_COMPLEX
202  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,std::complex<float>,std::complex<double>)
203  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,double,std::complex<double>)
204  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,float,std::complex<double>)
205  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,long,std::complex<double>)
206  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,int,std::complex<double>)
207  SACADO_PROMOTE_SPECIALIZATION(std::complex<float>,float,std::complex<float>)
208  SACADO_PROMOTE_SPECIALIZATION(std::complex<float>,long,std::complex<float>)
209  SACADO_PROMOTE_SPECIALIZATION(std::complex<float>,int,std::complex<float>)
210 #endif // HAVE_SACADO_COMPLEX
211 
212 #undef SACADO_PROMOTE_SPECIALIZATION
213 
214  // Macros for building proper Promote specialization for AD types
215 
216 #define SACADO_AD_PROMOTE_SPEC(NS, AD) /* */
217 
218 #define SACADO_AD_PROMOTE_SPEC2(NS, AD) /* */
219 
220 #define SACADO_FAD_PROMOTE_SPEC(NS, FAD) /* */
221 
222 #define SACADO_SFAD_PROMOTE_SPEC(NS, FAD) /* */
223 
224 #define SACADO_EXPR_PROMOTE_SPEC(NS) /* */
225 
226 #define SACADO_VFAD_PROMOTE_SPEC(NS) /* */
227 
228 #define SACADO_RAD_PROMOTE_SPEC(NS) \
229  namespace NS { \
230  template <typename> class ADvar; \
231  template <typename> class ADvari; \
232  } \
233  template <typename T> \
234  struct OverrideDefaultPromote< NS :: ADvari <T>& > { \
235  static const bool value = true; \
236  }; \
237  template <typename T> \
238  struct Promote< NS :: ADvar <T>, \
239  NS :: ADvari <T>& > { \
240  typedef NS :: ADvar <T> type; \
241  }; \
242  template <typename T> \
243  struct Promote< NS :: ADvari <T>&, \
244  NS :: ADvar <T> > { \
245  typedef NS :: ADvar <T> type; \
246  }; \
247  template <typename T> \
248  struct Promote< NS :: ADvari <T>&, \
249  typename NS :: ADvari <T>::value_type > { \
250  typedef NS :: ADvar <T> type; \
251  }; \
252  template <typename T> \
253  struct Promote< typename NS :: ADvari <T>::value_type, \
254  NS :: ADvari <T>& > { \
255  typedef NS :: ADvar <T> type; \
256  }; \
257  template <typename T> \
258  struct Promote< NS :: ADvari <T>&, \
259  typename dummy< typename NS :: ADvari <T>::value_type, \
260  typename NS :: ADvari <T>::scalar_type \
261  >::type > { \
262  typedef NS :: ADvar <T> type; \
263  }; \
264  template <typename T> \
265  struct Promote< typename dummy< typename NS :: ADvari <T>::value_type, \
266  typename NS :: ADvari <T>::scalar_type \
267  >::type, \
268  NS :: ADvari <T>& > { \
269  typedef NS :: ADvar <T> type; \
270  };
271 
272  //
273  // We define defaults for all of the traits to make Sacado easier to use.
274  // The default choices are based on what appears to be the "safest" choice
275  // for any scalar type. They may not work in all cases, in which case a
276  // specialization should be provided.
277  //
278 
280 
284  template <typename T> struct ScalarType {
285  typedef T type;
286  };
287 
289 
292  template <typename T> struct ScalarType<const T> {
293  typedef const typename ScalarType<T>::type type;
294  };
295 
297 
301  template <typename T> struct ValueType {
302  typedef T type;
303  };
304 
306 
309  template <typename T> struct ValueType<const T> {
310  typedef const typename ValueType<T>::type type;
311  };
312 
314 
318  template <typename T> struct IsADType {
319  static const bool value = false;
320  };
321 
323 
327  template <typename T> struct IsScalarType {
328  static const bool value = false;
329  };
330 
332 
336  template <typename T> struct IsSimdType {
337  static const bool value = false;
338  };
339 
341 
344  template <typename T> struct Value {
346  static const T& eval(const T& x) { return x; }
347  };
348 
350  template <typename T> struct Value<const T> {
351  typedef typename ValueType<T>::type value_type;
353  static const value_type& eval(const T& x) {
354  return Value<T>::eval(x);
355  }
356  };
357 
359 
363  template <typename T> struct ScalarValue {
365  static const T& eval(const T& x) { return x; }
366  };
367 
369  template <typename T> struct ScalarValue<const T> {
372  static const scalar_type& eval(const T& x) {
373  return ScalarValue<T>::eval(x);
374  }
375  };
376 
378  template <typename T>
380  typename ScalarType<T>::type scalarValue(const T& x) {
381  return ScalarValue<T>::eval(x);
382  }
383 
385  template <typename T> struct MarkConstant {
387  static void eval(T& x) {}
388  };
389 
391  template <typename T> struct StringName {
392  static std::string eval() { return ""; }
393  };
394 
396  template <typename T> struct IsEqual {
398  static bool eval(const T& x, const T& y) { return x == y; }
399  };
400 
402  template <typename T> struct IsStaticallySized {
403  static const bool value = false;
404  };
405 
407 
410  template <typename T> struct IsStaticallySized<const T> {
411  static const bool value = IsStaticallySized<T>::value;
412  };
413 
415  template <typename T> struct StaticSize {
416  static const unsigned value = 0;
417  };
418 
420  template <typename T> struct IsFad {
421  static const bool value = false;
422  };
423 
425  template <typename T> struct IsFad< const T >
426  {
427  static const bool value = IsFad<T>::value;
428  };
429 
431  template <typename T>
432  struct RemoveConst {
433  typedef T type;
434  };
435 
437  template <typename T>
438  struct RemoveConst< const T > {
439  typedef T type;
440  };
441 
443 #define SACADO_BUILTIN_SPECIALIZATION(t,NAME) \
444  template <> struct ScalarType< t > { \
445  typedef t type; \
446  }; \
447  template <> struct ValueType< t > { \
448  typedef t type; \
449  }; \
450  template <> struct IsADType< t > { \
451  static const bool value = false; \
452  }; \
453  template <> struct IsScalarType< t > { \
454  static const bool value = true; \
455  }; \
456  template <> struct Value< t > { \
457  SACADO_INLINE_FUNCTION \
458  static const t& eval(const t& x) { return x; } \
459  }; \
460  template <> struct ScalarValue< t > { \
461  SACADO_INLINE_FUNCTION \
462  static const t& eval(const t& x) { return x; } \
463  }; \
464  template <> struct StringName< t > { \
465  static std::string eval() { return NAME; } \
466  }; \
467  template <> struct IsEqual< t > { \
468  SACADO_INLINE_FUNCTION \
469  static bool eval(const t& x, const t& y) { \
470  return x == y; } \
471  }; \
472  template <> struct IsStaticallySized< t > { \
473  static const bool value = true; \
474  };
475 
476 #define SACADO_BUILTIN_SPECIALIZATION_COMPLEX(t,NAME) \
477  template <> struct ScalarType< t > { \
478  typedef t type; \
479  }; \
480  template <> struct ValueType< t > { \
481  typedef t type; \
482  }; \
483  template <> struct IsADType< t > { \
484  static const bool value = false; \
485  }; \
486  template <> struct IsScalarType< t > { \
487  static const bool value = true; \
488  }; \
489  template <> struct Value< t > { \
490  static const t& eval(const t& x) { return x; } \
491  }; \
492  template <> struct ScalarValue< t > { \
493  static const t& eval(const t& x) { return x; } \
494  }; \
495  template <> struct StringName< t > { \
496  static std::string eval() { return NAME; } \
497  }; \
498  template <> struct IsEqual< t > { \
499  static bool eval(const t& x, const t& y) { \
500  return x == y; } \
501  }; \
502  template <> struct IsStaticallySized< t > { \
503  static const bool value = true; \
504  };
505 
506  SACADO_BUILTIN_SPECIALIZATION(char,"char")
507  SACADO_BUILTIN_SPECIALIZATION(float,"float")
508  SACADO_BUILTIN_SPECIALIZATION(double,"double")
510  SACADO_BUILTIN_SPECIALIZATION(unsigned int,"unsigned int")
511  SACADO_BUILTIN_SPECIALIZATION(long,"long")
512  SACADO_BUILTIN_SPECIALIZATION(unsigned long,"unsigned long")
513  SACADO_BUILTIN_SPECIALIZATION(bool,"bool")
514 #ifdef HAVE_SACADO_COMPLEX
515  SACADO_BUILTIN_SPECIALIZATION_COMPLEX(std::complex<double>,"std::complex<double>")
516  SACADO_BUILTIN_SPECIALIZATION_COMPLEX(std::complex<float>,"std::complex<float>")
517 #endif
518 
519 #undef SACADO_BUILTIN_SPECIALIZATION
520 #undef SACADO_BUILTIN_SPECIALIZATION_COMPLEX
521 
522 template< typename T , T v , bool NonZero = ( v != T(0) ) >
524 {
525  // Declaration of 'static const' causes an unresolved linker symbol in debug
526  // static const T value = v ;
527  enum { value = T(v) };
528  typedef T value_type ;
535 };
536 
537 template< typename T , T zero >
539 {
541  typedef T value_type ;
547  SACADO_INLINE_FUNCTION integral_nonzero& operator=(const T & v) { value = v; return *this; }
548 };
549 
550 } // namespace Sacado
551 
552 #endif // SACADO_TRAITS_HPP
static SACADO_INLINE_FUNCTION const T & eval(const T &x)
SACADO_INLINE_FUNCTION ScalarType< T >::type scalarValue(const T &x)
A simple template function for invoking ScalarValue&lt;&gt;
static SACADO_INLINE_FUNCTION const value_type & eval(const T &x)
Base template specification for marking constants.
static std::string eval()
#define SACADO_PROMOTE_SPECIALIZATION(type1, type2, type3)
Specialization of Promote to builtin types.
SACADO_INLINE_FUNCTION integral_nonzero()
SACADO_INLINE_FUNCTION integral_nonzero & operator=(const integral_nonzero &v)
static SACADO_INLINE_FUNCTION void eval(T &x)
Base template specification for ScalarValue.
Base template specification for ScalarType.
Base template specification for whether a type is a Fad type.
Base template specification for string names of types.
static SACADO_INLINE_FUNCTION const T & eval(const T &x)
Base template specification for IsADType.
static const bool value
Base template specification for static size.
Base template specification for Value.
Is a type an expression.
Base template specification for IsSimdType.
const ScalarType< T >::type type
#define T
Definition: Sacado_rad.hpp:553
static const bool value
ValueType< T >::type value_type
Specialize this for a given type T to disable default Promote rules.
Determine whether a given type is a view.
Base template specification for testing equivalence.
Get the base Fad type from a view/expression.
SACADO_INLINE_FUNCTION integral_nonzero & operator=(const T &)
#define SACADO_BUILTIN_SPECIALIZATION_COMPLEX(t, NAME)
Remove const from a type.
Do not initialize the derivative array.
static const bool value
const ValueType< T >::type type
integral_nonzero< T, v > type
static SACADO_INLINE_FUNCTION bool eval(const T &x, const T &y)
SACADO_INLINE_FUNCTION integral_nonzero(const integral_nonzero &v)
#define SACADO_BUILTIN_SPECIALIZATION(t, NAME)
Specialization of above classes to builtin types.
DerivInit
Enum use to signal whether the derivative array should be initialized in AD object constructors...
static const bool value
ScalarType< T >::type scalar_type
static const bool value
Initialize the derivative array.
Base template specification for IsScalarType.
static SACADO_INLINE_FUNCTION const scalar_type & eval(const T &x)
expr expr expr bar false
#define SACADO_INLINE_FUNCTION
static const unsigned value
SACADO_INLINE_FUNCTION integral_nonzero & operator=(const integral_nonzero &)
SACADO_INLINE_FUNCTION integral_nonzero(const integral_nonzero &)
SACADO_INLINE_FUNCTION integral_nonzero(const T &)
static const bool value
SACADO_INLINE_FUNCTION integral_nonzero(const T &v)
Base template specification for ValueType.
Base template specification for Promote.
const double y
Base template specification for testing whether type is statically sized.
SACADO_INLINE_FUNCTION integral_nonzero & operator=(const T &v)
Get view type for any Fad type.