OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 
47 template<class Type>
49 {
50  enum { val = 666666 };
51 };
52 
53 template<> struct PETE_Type2Index<bool>
54 {
55  enum { val = 1 };
56 };
57 
58 template<> struct PETE_Type2Index<char>
59 {
60  enum { val = 2 };
61 };
62 
63 template<> struct PETE_Type2Index<short>
64 {
65  enum { val = 3 };
66 };
67 
68 template<> struct PETE_Type2Index<int>
69 {
70  enum { val = 4 };
71 };
72 
73 template<> struct PETE_Type2Index<long>
74 {
75  enum { val = 5 };
76 };
77 
78 template<> struct PETE_Type2Index<float>
79 {
80  enum { val = 6 };
81 };
82 
83 template<> 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 
130 const int PETE_UnaryPassThruTag = 0;
131 
132 template<class T, class Op, int OpTag>
134 {
135  typedef typename Op::type type;
136 };
137 
138 template<class T, class Op>
140 {
141  typedef T type;
142 };
143 
144 template<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 
189 const int PETE_BinaryPromoteTag = -2;
190 const int PETE_BinaryUseLeftTag = -1;
192 
193 // This is still harder than it has to be. There are bugs in
194 // the EDG front end.
195 
196 template<class T1, class T2, class Op, int op>
198 {
199  typedef typename Op::type type;
200 };
201 
202 template<class T1, class T2, class Op>
204 {
205  typedef T1 type;
206 };
207 
208 template<class T1, class T2, class Op>
210 {
211  typedef T2 type;
212 };
213 
214 template<class T1, class T2, bool lr>
216 {
217 };
218 
219 template<class T1, class T2>
220 struct PETE_ComputePromoteType<T1, T2, true>
221 {
222  typedef T1 type;
223 };
224 
225 template<class T1, class T2>
226 struct PETE_ComputePromoteType<T1, T2, false>
227 {
228  typedef T2 type;
229 };
230 
231 template<class T1, class T2, int t1, int t2>
233 {
234  typedef typename
235  PETE_ComputePromoteType<T1, T2, (t1 >= t2)>::type type;
236 };
237 
238 template<class T1, class T2, class Op>
240 {
241  typedef typename PETE_ComputePromoteType2<T1, T2,
243 };
244 
245 template<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 
269 template<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 
302 struct OpNot
303 {
304  typedef bool type;
306 };
307 
308 template <class T>
309 struct 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 
322 struct FnArcCos
323 {
325 };
326 
327 struct FnArcSin
328 {
330 };
331 
332 struct FnArcTan
333 {
335 };
336 
337 struct FnCeil
338 {
340 };
341 
342 struct FnCos
343 {
345 };
346 
347 struct FnHypCos
348 {
350 };
351 
352 struct FnExp
353 {
355 };
356 
357 struct FnFabs
358 {
360 };
361 
362 struct FnFloor
363 {
365 };
366 
367 struct FnLog
368 {
370 };
371 
372 struct FnLog10
373 {
375 };
376 
377 struct FnSin
378 {
380 };
381 
382 struct FnHypSin
383 {
385 };
386 
387 struct FnSqrt
388 {
390 };
391 
392 struct FnTan
393 {
395 };
396 
397 struct FnHypTan
398 {
400 };
401 
402 struct FnErf
403 {
405 };
406 
407 
409 //
410 // BINARY OPERATORS: +, -, *, /, %, <, >, <=, >=, ==, !=, &&, ||, ^, &,
411 // |, <<, >>
412 //
414 
415 struct OpAdd
416 {
418 };
419 
421 {
423 };
424 
426 {
428 };
429 
430 struct OpDivide
431 {
433 };
434 
435 struct OpMod
436 {
438 };
439 
440 struct OpLT
441 {
442  typedef bool type;
444 };
445 
446 struct OpGT
447 {
448  typedef bool type;
450 };
451 
452 struct OpLE
453 {
454  typedef bool type;
456 };
457 
458 struct OpGE
459 {
460  typedef bool type;
462 };
463 
464 struct OpEQ
465 {
466  typedef bool type;
468 };
469 
470 struct OpNE
471 {
472  typedef bool type;
474 };
475 
476 struct OpAnd
477 {
478  typedef bool type;
480 };
481 
482 struct 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 
525 struct FnLdexp
526 {
528 };
529 
530 struct FnPow
531 {
533 };
534 
535 struct FnFmod
536 {
538 };
539 
540 struct FnArcTan2
541 {
543 };
544 
545 
547 //
548 // ASSIGNMENT OPERATORS: =, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=
549 //
551 
552 struct OpAssign
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 
614 struct OpWhere
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