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 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 //
29 // The forward-mode AD classes in Sacado are a derivative work of the
30 // expression template classes in the Fad package by Nicolas Di Cesare.
31 // The following banner is included in the original Fad source code:
32 //
33 // ************ DO NOT REMOVE THIS BANNER ****************
34 //
35 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
36 // http://www.ann.jussieu.fr/~dicesare
37 //
38 // CEMRACS 98 : C++ courses,
39 // templates : new C++ techniques
40 // for scientific computing
41 //
42 //********************************************************
43 //
44 // NumericalTraits class to illustrate TRAITS
45 //
46 //********************************************************
47 // @HEADER
48 
49 #ifndef SACADO_TRAITS_HPP
50 #define SACADO_TRAITS_HPP
51 
52 #include <string>
53 #include <type_traits>
54 
55 #include "Sacado_ConfigDefs.h"
56 #include "Sacado_dummy_arg.hpp"
57 #include "Sacado_mpl_enable_if.hpp"
59 
60 #ifdef HAVE_SACADO_COMPLEX
61 #include <complex>
62 #endif
63 
64 namespace Sacado {
65 
70  enum DerivInit {
73  };
74 
76  template <typename T>
77  struct IsExpr {
78  static const bool value = false;
79  };
80 
82  template <typename T>
83  struct IsView {
84  static const bool value = false;
85  };
86 
88  template <typename T>
89  struct BaseExprType {
90  typedef T type;
91  };
92 
94  template <typename T,unsigned,unsigned> struct ViewFadType {};
95 
97  template <typename T> struct OverrideDefaultPromote {
98  static const bool value = false;
99  };
100 
102 
106  template <typename A, typename B, typename Enabled = void> struct Promote {};
107 
109  template <typename A>
110  struct Promote< A, A,
111  typename mpl::enable_if_c< !OverrideDefaultPromote<A>::value >::type > {
112  typedef typename BaseExprType<A>::type type;
113  };
114 
116  template <typename A, typename B>
117  struct Promote< A, B,
118  typename mpl::enable_if_c< std::is_convertible<A,B>::value &&
119  !std::is_convertible<B,A>::value &&
120  !OverrideDefaultPromote<A>::value &&
121  !OverrideDefaultPromote<B>::value
122  >::type > {
123  typedef typename BaseExprType<B>::type type;
124  };
125 
127  template <typename A, typename B>
128  struct Promote< A, B,
129  typename mpl::enable_if_c< std::is_convertible<B,A>::value &&
130  !std::is_convertible<A,B>::value &&
131  !OverrideDefaultPromote<A>::value &&
132  !OverrideDefaultPromote<B>::value
133  >::type > {
134  typedef typename BaseExprType<A>::type type;
135  };
136 
141  template <typename A, typename B>
142  struct Promote< A, B,
143  typename mpl::enable_if_c< std::is_convertible<A,B>::value &&
144  std::is_convertible<B,A>::value &&
145  !std::is_same<A,B>::value &&
146  ( IsExpr<A>::value ||
147  IsExpr<B>::value ) >::type >
148  {
152  };
153 
159  template <typename A, typename B>
160  struct Promote< A, B,
161  typename mpl::enable_if_c< !std::is_convertible<A,B>::value &&
162  !std::is_convertible<B,A>::value &&
163  IsExpr<A>::value &&
164  std::is_convertible< B, typename BaseExprType< typename A::value_type >::type >::value
165  >::type >
166  {
167  typedef typename BaseExprType<A>::type type;
168  };
169 
175  template <typename A, typename B>
176  struct Promote< A, B,
177  typename mpl::enable_if_c< !std::is_convertible<A,B>::value &&
178  !std::is_convertible<B,A>::value &&
179  IsExpr<B>::value &&
180  std::is_convertible< A, typename BaseExprType< typename B::value_type >::type >::value
181  >::type >
182  {
183  typedef typename BaseExprType<B>::type type;
184  };
185 
191  template <typename A, typename B>
192  struct Promote< A, B,
193  typename mpl::enable_if_c< !std::is_convertible<A,B>::value &&
194  !std::is_convertible<B,A>::value &&
195  IsExpr<A>::value &&
196  IsExpr<B>::value &&
197  std::is_same< typename BaseExprType< typename A::value_type >::type,
198  typename BaseExprType< typename B::value_type >::type >::value
199  >::type >
200  {
204  };
205 
207 #define SACADO_PROMOTE_SPECIALIZATION(type1,type2,type3) \
208  template <> struct Promote< type1, type2, void > { \
209  typedef type3 type; \
210  }; \
211  template <> struct Promote< type2, type1, void > { \
212  typedef type3 type; \
213  };
214 
215  SACADO_PROMOTE_SPECIALIZATION(double,float,double)
216  SACADO_PROMOTE_SPECIALIZATION(double,long,double)
217  SACADO_PROMOTE_SPECIALIZATION(double,int,double)
218  SACADO_PROMOTE_SPECIALIZATION(float,long,float)
219  SACADO_PROMOTE_SPECIALIZATION(float,int,float)
220 #ifdef HAVE_SACADO_COMPLEX
221  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,std::complex<float>,std::complex<double>)
222  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,double,std::complex<double>)
223  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,float,std::complex<double>)
224  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,long,std::complex<double>)
225  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,int,std::complex<double>)
226  SACADO_PROMOTE_SPECIALIZATION(std::complex<float>,float,std::complex<float>)
227  SACADO_PROMOTE_SPECIALIZATION(std::complex<float>,long,std::complex<float>)
228  SACADO_PROMOTE_SPECIALIZATION(std::complex<float>,int,std::complex<float>)
229 #endif // HAVE_SACADO_COMPLEX
230 
231 #undef SACADO_PROMOTE_SPECIALIZATION
232 
233  // Macros for building proper Promote specialization for AD types
234 
235 #define SACADO_AD_PROMOTE_SPEC(NS, AD) /* */
236 
237 #define SACADO_AD_PROMOTE_SPEC2(NS, AD) /* */
238 
239 #define SACADO_FAD_PROMOTE_SPEC(NS, FAD) /* */
240 
241 #define SACADO_SFAD_PROMOTE_SPEC(NS, FAD) /* */
242 
243 #define SACADO_EXPR_PROMOTE_SPEC(NS) /* */
244 
245 #define SACADO_VFAD_PROMOTE_SPEC(NS) /* */
246 
247 #define SACADO_RAD_PROMOTE_SPEC(NS) \
248  namespace NS { \
249  template <typename> class ADvar; \
250  template <typename> class ADvari; \
251  } \
252  template <typename T> \
253  struct OverrideDefaultPromote< NS :: ADvari <T>& > { \
254  static const bool value = true; \
255  }; \
256  template <typename T> \
257  struct Promote< NS :: ADvar <T>, \
258  NS :: ADvari <T>& > { \
259  typedef NS :: ADvar <T> type; \
260  }; \
261  template <typename T> \
262  struct Promote< NS :: ADvari <T>&, \
263  NS :: ADvar <T> > { \
264  typedef NS :: ADvar <T> type; \
265  }; \
266  template <typename T> \
267  struct Promote< NS :: ADvari <T>&, \
268  typename NS :: ADvari <T>::value_type > { \
269  typedef NS :: ADvar <T> type; \
270  }; \
271  template <typename T> \
272  struct Promote< typename NS :: ADvari <T>::value_type, \
273  NS :: ADvari <T>& > { \
274  typedef NS :: ADvar <T> type; \
275  }; \
276  template <typename T> \
277  struct Promote< NS :: ADvari <T>&, \
278  typename dummy< typename NS :: ADvari <T>::value_type, \
279  typename NS :: ADvari <T>::scalar_type \
280  >::type > { \
281  typedef NS :: ADvar <T> type; \
282  }; \
283  template <typename T> \
284  struct Promote< typename dummy< typename NS :: ADvari <T>::value_type, \
285  typename NS :: ADvari <T>::scalar_type \
286  >::type, \
287  NS :: ADvari <T>& > { \
288  typedef NS :: ADvar <T> type; \
289  };
290 
291  //
292  // We define defaults for all of the traits to make Sacado easier to use.
293  // The default choices are based on what appears to be the "safest" choice
294  // for any scalar type. They may not work in all cases, in which case a
295  // specialization should be provided.
296  //
297 
299 
303  template <typename T> struct ScalarType {
304  typedef T type;
305  };
306 
308 
311  template <typename T> struct ScalarType<const T> {
312  typedef const typename ScalarType<T>::type type;
313  };
314 
316 
320  template <typename T> struct ValueType {
321  typedef T type;
322  };
323 
325 
328  template <typename T> struct ValueType<const T> {
329  typedef const typename ValueType<T>::type type;
330  };
331 
333 
337  template <typename T> struct IsADType {
338  static const bool value = false;
339  };
340 
342 
346  template <typename T> struct IsScalarType {
347  static const bool value = false;
348  };
349 
351 
355  template <typename T> struct IsSimdType {
356  static const bool value = false;
357  };
358 
360 
363  template <typename T> struct Value {
365  static const T& eval(const T& x) { return x; }
366  };
367 
369  template <typename T> struct Value<const T> {
370  typedef typename ValueType<T>::type value_type;
372  static const value_type& eval(const T& x) {
373  return Value<T>::eval(x);
374  }
375  };
376 
378 
382  template <typename T> struct ScalarValue {
384  static const T& eval(const T& x) { return x; }
385  };
386 
388  template <typename T> struct ScalarValue<const T> {
391  static const scalar_type& eval(const T& x) {
392  return ScalarValue<T>::eval(x);
393  }
394  };
395 
397  template <typename T>
399  typename ScalarType<T>::type scalarValue(const T& x) {
400  return ScalarValue<T>::eval(x);
401  }
402 
404  template <typename T> struct MarkConstant {
406  static void eval(T& x) {}
407  };
408 
410  template <typename T> struct StringName {
411  static std::string eval() { return ""; }
412  };
413 
415  template <typename T> struct IsEqual {
417  static bool eval(const T& x, const T& y) { return x == y; }
418  };
419 
421  template <typename T> struct IsStaticallySized {
422  static const bool value = false;
423  };
424 
426 
429  template <typename T> struct IsStaticallySized<const T> {
430  static const bool value = IsStaticallySized<T>::value;
431  };
432 
434  template <typename T> struct StaticSize {
435  static const unsigned value = 0;
436  };
437 
439  template <typename T> struct IsFad {
440  static const bool value = false;
441  };
442 
444  template <typename T> struct IsFad< const T >
445  {
446  static const bool value = IsFad<T>::value;
447  };
448 
450  template <typename T>
451  struct RemoveConst {
452  typedef T type;
453  };
454 
456  template <typename T>
457  struct RemoveConst< const T > {
458  typedef T type;
459  };
460 
462 #define SACADO_BUILTIN_SPECIALIZATION(t,NAME) \
463  template <> struct ScalarType< t > { \
464  typedef t type; \
465  }; \
466  template <> struct ValueType< t > { \
467  typedef t type; \
468  }; \
469  template <> struct IsADType< t > { \
470  static const bool value = false; \
471  }; \
472  template <> struct IsScalarType< t > { \
473  static const bool value = true; \
474  }; \
475  template <> struct Value< t > { \
476  SACADO_INLINE_FUNCTION \
477  static const t& eval(const t& x) { return x; } \
478  }; \
479  template <> struct ScalarValue< t > { \
480  SACADO_INLINE_FUNCTION \
481  static const t& eval(const t& x) { return x; } \
482  }; \
483  template <> struct StringName< t > { \
484  static std::string eval() { return NAME; } \
485  }; \
486  template <> struct IsEqual< t > { \
487  SACADO_INLINE_FUNCTION \
488  static bool eval(const t& x, const t& y) { \
489  return x == y; } \
490  }; \
491  template <> struct IsStaticallySized< t > { \
492  static const bool value = true; \
493  };
494 
495 #define SACADO_BUILTIN_SPECIALIZATION_COMPLEX(t,NAME) \
496  template <> struct ScalarType< t > { \
497  typedef t type; \
498  }; \
499  template <> struct ValueType< t > { \
500  typedef t type; \
501  }; \
502  template <> struct IsADType< t > { \
503  static const bool value = false; \
504  }; \
505  template <> struct IsScalarType< t > { \
506  static const bool value = true; \
507  }; \
508  template <> struct Value< t > { \
509  static const t& eval(const t& x) { return x; } \
510  }; \
511  template <> struct ScalarValue< t > { \
512  static const t& eval(const t& x) { return x; } \
513  }; \
514  template <> struct StringName< t > { \
515  static std::string eval() { return NAME; } \
516  }; \
517  template <> struct IsEqual< t > { \
518  static bool eval(const t& x, const t& y) { \
519  return x == y; } \
520  }; \
521  template <> struct IsStaticallySized< t > { \
522  static const bool value = true; \
523  };
524 
525  SACADO_BUILTIN_SPECIALIZATION(char,"char")
526  SACADO_BUILTIN_SPECIALIZATION(float,"float")
527  SACADO_BUILTIN_SPECIALIZATION(double,"double")
529  SACADO_BUILTIN_SPECIALIZATION(unsigned int,"unsigned int")
530  SACADO_BUILTIN_SPECIALIZATION(long,"long")
531  SACADO_BUILTIN_SPECIALIZATION(unsigned long,"unsigned long")
532  SACADO_BUILTIN_SPECIALIZATION(bool,"bool")
533 #ifdef HAVE_SACADO_COMPLEX
534  SACADO_BUILTIN_SPECIALIZATION_COMPLEX(std::complex<double>,"std::complex<double>")
535  SACADO_BUILTIN_SPECIALIZATION_COMPLEX(std::complex<float>,"std::complex<float>")
536 #endif
537 
538 #undef SACADO_BUILTIN_SPECIALIZATION
539 #undef SACADO_BUILTIN_SPECIALIZATION_COMPLEX
540 
541 template< typename T , T v , bool NonZero = ( v != T(0) ) >
543 {
544  // Declaration of 'static const' causes an unresolved linker symbol in debug
545  // static const T value = v ;
546  enum { value = T(v) };
547  typedef T value_type ;
554 };
555 
556 template< typename T , T zero >
558 {
560  typedef T value_type ;
566  SACADO_INLINE_FUNCTION integral_nonzero& operator=(const T & v) { value = v; return *this; }
567 };
568 
569 } // namespace Sacado
570 
571 #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:573
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.