OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
TypeComputations.h
Go to the documentation of this file.
1// -*- C++ -*-
2/***************************************************************************
3 *
4 * The IPPL Framework
5 *
6 *
7 * Visit http://people.web.psi.ch/adelmann/ for more details
8 *
9 ***************************************************************************/
10
11
13//
14// FILE NAME
15// TypeComputations.h
16//
17// CREATED
18// July 11, 1997
19//
20// DESCRIPTION
21// PETE: Portable Expression Template Engine.
22//
23// This header file defines templates used to construct the
24// return types for unary, binary, and trinary operations.
25//
27
28#ifndef TYPE_COMPUTATIONS_H
29#define TYPE_COMPUTATIONS_H
30
31
33//
34// CLASS NAME
35// PETE_Type2Index<T>
36//
37// DESCRIPTION
38// This template describes a set of trait classes that associate an
39// index with a type. Each concrete class---a type that is designed
40// to be used like a built-in type---must have a specialization
41// of this class that provides a unique index. This index is used
42// to figure out the default return type of a binary/trinary operation.
43// Specifically, the largest index is chosen.
44//
46
47template<class Type>
49{
50 enum { val = 666666 };
51};
52
53template<> struct PETE_Type2Index<bool>
54{
55 enum { val = 1 };
56};
57
58template<> struct PETE_Type2Index<char>
59{
60 enum { val = 2 };
61};
62
63template<> struct PETE_Type2Index<short>
64{
65 enum { val = 3 };
66};
67
68template<> struct PETE_Type2Index<int>
69{
70 enum { val = 4 };
71};
72
73template<> struct PETE_Type2Index<long>
74{
75 enum { val = 5 };
76};
77
78template<> struct PETE_Type2Index<float>
79{
80 enum { val = 6 };
81};
82
83template<> struct PETE_Type2Index<double>
84{
85 enum { val = 7 };
86};
87
88
90//
91// CLASS NAME
92// PETEUnaryReturn<T, Op>
93//
94// DESCRIPTION
95// This template describes the default mechanism for calculating the
96// return type to a unary expression given the argument type T and
97// the operation type Op.
98//
99// There are two sensible things one can do automatically:
100// o (Op::tag == PETE_UnaryPassThruTag) make the return type
101// the same as the argument to the function/operation.
102// For example, operator-(T) should return a T.
103// o (Op::tag != PETE_UnaryPassThruTag) return a type based entirely on
104// the operation. For example, operator! always returns a bool.
105// To figure out which approach to take, PETEUnaryReturn uses the
106// tag from the operator and another template, PETE_ComputeUnaryType.
107// Consider negation (unary minus). The operator would be formed like:
108// struct OpUnaryMinus {
109// enum { tag = PETE_UnaryPassThruTag };
110// };
111// Logical negation (not) would be formed like:
112// struct OpNot {
113// enum { tag = PETE_Type2Index<bool> };
114// typedef bool type;
115// };
116// The minor redundancy (specifying the tag and the type) is required to
117// allow easy support for compilers that may or may not support partial
118// specialization.
119//
120// Special cases can be handled by directly specializing PETEUnaryReturn.
121// For example, the abs function typically returns a double when the
122// argument is a complex<double>. The appropriate specialization here
123// would be:
124// template<> struct PETEUnaryReturn< complex<double>, FnAbs > {
125// typedef double type;
126// };
127//
129
131
132template<class T, class Op, int OpTag>
134{
135 typedef typename Op::type type;
136};
137
138template<class T, class Op>
140{
141 typedef T type;
142};
143
144template<class T, class Op>
146{
148};
149
150
152//
153// CLASS NAME
154// PETEBinaryReturn<T1, T2, Op>
155//
156// DESCRIPTION
157// This template describes the default mechanism for calculating the
158// return type to a binary expression given the argument types T1 and
159// T2 and the operation type Op.
160//
161// There are four sensible things one can do automatically:
162// o (Op::tag == PETE_BinaryPromoteTag) make the return type by
163// promoting/converting the "simpler" type into the more "complex."
164// For example, we typically want to do this with addition.
165// o (Op::tag == PETE_BinaryUseLeftTag) return the type of the
166// left-hand operand. For example, this is what happens with operator<<.
167// o (Op::tag == PETE_BinaryUseRightTag) return the type of the
168// right-hand operand.
169// o (otherwise) return a type based entirely on the operation.
170// For example, operator!= always returns a bool.
171// To figure out which approach to take, PETEBinaryReturn uses the
172// tag from the operator and another template, PETE_ComputeBinaryType.
173// Consider addition. The operator would be formed like:
174// struct OpAdd {
175// enum { tag = PETE_BinaryPromoteTag };
176// };
177//
178// Special cases can be handled by directly specializing PETEBinaryReturn.
179// For example, the multipplication between a matrix and a vector might do a
180// matrix/vector product, thereby returning a vector. The appropriate
181// specialization here would be:
182// struct PETEBinaryReturn< Mat<double,3>, Vec<float,3>, OpMultipply > {
183// typedef Vector<double,3> type;
184// };
185// Notice how the element type is promoted.
186//
188
192
193// This is still harder than it has to be. There are bugs in
194// the EDG front end.
195
196template<class T1, class T2, class Op, int op>
198{
199 typedef typename Op::type type;
200};
201
202template<class T1, class T2, class Op>
204{
205 typedef T1 type;
206};
207
208template<class T1, class T2, class Op>
210{
211 typedef T2 type;
212};
213
214template<class T1, class T2, bool lr>
216{
217};
218
219template<class T1, class T2>
220struct PETE_ComputePromoteType<T1, T2, true>
221{
222 typedef T1 type;
223};
224
225template<class T1, class T2>
226struct PETE_ComputePromoteType<T1, T2, false>
227{
228 typedef T2 type;
229};
230
231template<class T1, class T2, int t1, int t2>
233{
234 typedef typename
236};
237
238template<class T1, class T2, class Op>
240{
241 typedef typename PETE_ComputePromoteType2<T1, T2,
243};
244
245template<class T1, class T2, class Op>
247{
249};
250
251
253//
254// CLASS NAME
255// PETETrinaryReturn<T1, T2, T3, Op>
256//
257// DESCRIPTION
258// This template describes the default mechanism for calculating the
259// return type to a trinary expression given the argument types T1, T2, and
260// T3 and the operation type Op. The only trinary expression supported
261// in C++ is the ?: operation. In this case, T1 should end up being bool
262// and the result of the calculation is of type Binary_Promotion(T1,T2)
263// with the value being that associated with T2 if T1's associated value
264// turns out to be true and T3 if T1's associated value turns out to be
265// false.
266//
268
269template<class T1, class T2, class T3, class Op>
271{
273};
274
275
277//
278// UNARY OPERATORS: -, +, ~, !, Identity
279//
281
283{
285};
286
288{
290};
291
293{
295};
296
298{
300};
301
302struct OpNot
303{
304 typedef bool type;
306};
307
308template <class T>
309struct OpCast
310{
311 typedef T type;
313};
314
316//
317// UNARY FUNCTIONS: acos, asin, atan, ceil, cos, cosh, exp, fabs, floor,
318// log, log10, sin, sinh, sqrt, tan, tanh
319//
321
323{
325};
326
328{
330};
331
333{
335};
336
337struct FnCeil
338{
340};
341
342struct FnCos
343{
345};
346
348{
350};
351
352struct FnExp
353{
355};
356
357struct FnFabs
358{
360};
361
363{
365};
366
367struct FnLog
368{
370};
371
373{
375};
376
377struct FnSin
378{
380};
381
383{
385};
386
387struct FnSqrt
388{
390};
391
392struct FnTan
393{
395};
396
398{
400};
401
402struct FnErf
403{
405};
406
407
409//
410// BINARY OPERATORS: +, -, *, /, %, <, >, <=, >=, ==, !=, &&, ||, ^, &,
411// |, <<, >>
412//
414
415struct OpAdd
416{
418};
419
421{
423};
424
426{
428};
429
431{
433};
434
435struct OpMod
436{
438};
439
440struct OpLT
441{
442 typedef bool type;
444};
445
446struct OpGT
447{
448 typedef bool type;
450};
451
452struct OpLE
453{
454 typedef bool type;
456};
457
458struct OpGE
459{
460 typedef bool type;
462};
463
464struct OpEQ
465{
466 typedef bool type;
468};
469
470struct OpNE
471{
472 typedef bool type;
474};
475
476struct OpAnd
477{
478 typedef bool type;
480};
481
482struct OpOr
483{
484 typedef bool type;
486};
487
489{
491};
492
494{
496};
497
499{
501};
502
504{
506};
507
509{
511};
512
513
515//
516// BINARY FUNCTIONS: copysign, ldexp, pow, fmod, atan2
517//
519
521{
523};
524
526{
528};
529
530struct FnPow
531{
533};
534
535struct FnFmod
536{
538};
539
541{
543};
544
545
547//
548// ASSIGNMENT OPERATORS: =, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=
549//
551
553{
555};
556
558{
560};
561
563{
565};
566
568{
570};
571
573{
575};
576
578{
580};
581
583{
585};
586
588{
590};
591
593{
595};
596
598{
600};
601
603{
605};
606
607
609//
610// TRINARY OPERATORS: ?: (where)
611//
613
615{
617};
618
619
621//
622// END OF FILE
623//
625
626#endif // TYPE_COMPUTATIONS_H
627
628/***************************************************************************
629 * $RCSfile: TypeComputations.h,v $ $Author: adelmann $
630 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:28 $
631 * IPPL_VERSION_ID: $Id: TypeComputations.h,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $
632 ***************************************************************************/
const int PETE_BinaryUseRightTag
const int PETE_BinaryUseLeftTag
const int PETE_UnaryPassThruTag
const int PETE_BinaryPromoteTag
boost::function< boost::tuple< double, bool >(arguments_t)> type
Definition: function.hpp:21
PETE_ComputeUnaryType< T, Op, Op::tag >::type type
PETE_ComputePromoteType< T1, T2,(t1 >=t2)>::type type
PETE_ComputePromoteType2< T1, T2, PETE_Type2Index< T1 >::val, PETE_Type2Index< T2 >::val >::type type
PETE_ComputeBinaryType< T1, T2, Op, Op::tag >::type type
PETE_ComputeBinaryType< T2, T3, Op, Op::tag >::type type