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
42namespace 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) \
89template<> class TensorTypeData<T> {\
90public: \
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}; \
99template<> class TensorTypeFromId<num> {\
100public: \
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>
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>
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);
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
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
const char * tensor_type_names[]
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 DPEC(L, R, T)
Definition type_data.h:169
#define TYPEINFO(num, T, iscmplx, mcpyok, realT, floatrealT)
Definition type_data.h:88
#define SPEC(L, R, T)
Definition type_data.h:166
#define TENSOR_MAX_TYPE_ID
Definition type_data.h:115