MADNESS  0.10.1
type_data.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31 
32  $Id$
33 */
34 
35 
36 #ifndef MADNESS_TENSOR_TYPE_DATA_H__INCLUDED
37 #define MADNESS_TENSOR_TYPE_DATA_H__INCLUDED
38 
39 /// \file type_data.h
40 /// \brief Defines and implements TensorTypeData, a type traits class.
41 
42 namespace madness {
43 
44  /// Traits class to specify support of numeric types.
45 
46  /// This traits class is used to specify which numeric types are
47  /// supported by the tensor library and also their unique integer id.
48  /// Unsupported types will default to an entry supported=false.
49  ///
50  /// To add a new type, append it to the definitions below using
51  /// TYPEINFO and tensor_type_names, incrementing the id, and set
52  /// TENSOR_MAX_TYPE_ID accordingly. You might also have to specialize
53  /// some of the methods in tensor.cc, and will have to add additional
54  /// instantiations at the end of tensor.cc and tensoriter.cc.
55  template <class T>
57 // {
58 // public:
59 // // id=unique and sequential identifier for each type
60 // enum {id = int};
61 // // supported=true for all supported scalar numeric types
62 // enum {supported = bool};
63 // // iscomplex=true if a complex type
64 // enum {iscomplex = bool};
65 // // memcopyok=true if memcpy can be used to copy an array
66 // // of the type ... it should be true for all native types
67 // // and probably false for all types that require a
68 // // special constructor or assignment operator.
69 // enum {memcopyok = bool};
70 // // type=the actual type
71 // typedef T type;
72 // // scalar_type = is the type of abs, normf, absmin, absmax, real, imag.
73 // // Not all of these functions are defined for all types.
74 // // Unfortunately, in the current version, some misuses will only be
75 // // detected at run time.
76 // typedef ... scalar_type;
77 // // float_scalar_type = the floating-point equivalent of scalar_type
78 // typedef ... float_scalar_type;
79 // };
80 
81  /// This provides the reverse mapping from integer id to type name
82  template <int id>
84  public:
85  typedef long type;
86  };
87 
88 #define TYPEINFO(num, T, iscmplx, mcpyok, realT,floatrealT) \
89 template<> class TensorTypeData<T> {\
90 public: \
91  enum {id = num}; \
92  enum {supported = true}; \
93  enum {iscomplex = iscmplx}; \
94  enum {memcopyok = mcpyok}; \
95  typedef T type; \
96  typedef realT scalar_type; \
97  typedef floatrealT float_scalar_type; \
98 }; \
99 template<> class TensorTypeFromId<num> {\
100 public: \
101  typedef T type; \
102 }
103 
104  TYPEINFO(0,int,false,true,int,double);
105  TYPEINFO(1,long,false,true,long,double);
106  TYPEINFO(2,float,false,true,float,float);
107  TYPEINFO(3,double,false,true,double,double);
108  TYPEINFO(4,float_complex,true,true,float,float);
109  TYPEINFO(5,double_complex,true,true,double,double);
110 
111 #ifdef HAVE_LONG_LONG
112  TYPEINFO(6,long long,false,true,long long,double);
113 #define TENSOR_MAX_TYPE_ID 6
114 #else
115 #define TENSOR_MAX_TYPE_ID 5
116 #endif // HAVE_LONG_LONG
117 
118 #undef TYPEINFO
119 
120 #ifdef TENSOR_CC
121  const char *tensor_type_names[TENSOR_MAX_TYPE_ID+1] = {
122  "int","long","float","double","float_complex","double_complex"
123 #ifdef HAVE_LONG_LONG
124  ,"long long"
125 #endif // HAVE_LONG_LONG
126  };
127 #else
128  extern const char *tensor_type_names[];
129 #endif
130 
131  /// The template IsSupported is used to constrain instantiation of
132  /// templates to the supported scalar types. It is only implemented if
133  /// the type is supported, in which case it evaluates to the return
134  /// type.
135  ///
136  /// E.g., to restrict operator+ to supported types T that can be added
137  /// to type A, with a return type of A.
138  ///
139  /// template <typename T> typename IsSupported < TensorTypeData<T>, A >::type
140  /// operator+(A const &v, T const &w) {
141  /// ...
142  /// return something of type A
143  /// };
144 
145  template <typename TypeData, typename, bool = TypeData::supported>
146  struct IsSupported;
147 
148  template <typename TypeData, typename ReturnType>
149  struct IsSupported <TypeData, ReturnType, true> {
150  typedef ReturnType type;
151  };
152 
153  // This macro embodies the above for a single parameter template.
154  // Look in tensor.h for example of how to use in multi-parameter
155  // templates.
156  //
157  // *** !!! *** Unfortunately, this macro was confusing Doxygen
158  // so we have removed all usages.
159  //#define ISSUPPORTED(T,RETURNTYPE)
160  //template <typename T> typename IsSupported < TensorTypeData<T>, RETURNTYPE >::type
161 
162  /// TensorResultType<L,R>::type is the type of (L op R) where op is nominally multiplication
163  template <typename leftT, typename rightT>
164  struct TensorResultType {};
165 
166 #define SPEC(L,R,T) \
167  template <> struct TensorResultType<L,R> {typedef T type;}; \
168  template <> struct TensorResultType<R,L> {typedef T type;}
169 #define DPEC(L,R,T) \
170  template <> struct TensorResultType<L,L> {typedef T type;}
171 
172  DPEC(int,int,int);
173  SPEC(int,long,long);
174  SPEC(int,float,float);
175  SPEC(int,double,double);
178  DPEC(long,long,long);
179  SPEC(long,float,float);
180  SPEC(long,double,double);
183  DPEC(float,float,float);
184  SPEC(float,double,double);
187  DPEC(double,double,double);
193 
194 #ifdef HAVE_LONG_LONG
195  SPEC(int,long long,long long);
196  SPEC(long,long long,long long);
197  DPEC(long long,long long,long long);
198  SPEC(long long,float,float);
199  SPEC(long long,double,double);
200  SPEC(long long,float_complex,float_complex);
202 #endif // HAVE_LONG_LONG
203 
204  /// This macro simplifies access to TensorResultType
205 #define TENSOR_RESULT_TYPE(L,R) typename TensorResultType<L,R>::type
206 
207 
208 #undef DPEC
209 #undef SPEC
210 }
211 #endif // MADNESS_TENSOR_TYPE_DATA_H__INCLUDED
std::complex< double > double_complex
Definition: cfft.h:14
Traits class to specify support of numeric types.
Definition: type_data.h:56
This provides the reverse mapping from integer id to type name.
Definition: type_data.h:83
long type
Definition: type_data.h:85
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
const char * tensor_type_names[]
SPEC(int, long, long)
TYPEINFO(0, int, false, true, int, double)
DPEC(int, int, int)
std::complex< float > float_complex
Definition: ran.h:39
ReturnType type
Definition: type_data.h:150
Definition: type_data.h:146
TensorResultType<L,R>::type is the type of (L op R) where op is nominally multiplication.
Definition: type_data.h:164
#define TENSOR_MAX_TYPE_ID
Definition: type_data.h:115