OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
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 // PETE_Index2Type<Index>
93 //
94 // DESCRIPTION
95 // This template describes a set of trait classes that associate an
96 // a type with an index. Each concrete class---a type that is designed
97 // to be used like a built-in type---must have a specialization
98 // of this class that provides a type given its unique index.
99 //
100 // NOTE
101 // It is good form to provide these, but they are really only necessary
102 // if your compiler (and all compilers you will ever want to port
103 // your code to) support partial specialization.
104 //
106 
107 #if !defined(IPPL_USE_PARTIAL_SPECIALIZATION)
108 
109 template<int Index>
111 {
112 };
113 
114 template<> struct PETE_Index2Type<1>
115 {
116  typedef bool type;
117 };
118 
119 template<> struct PETE_Index2Type<2>
120 {
121  typedef char type;
122 };
123 
124 template<> struct PETE_Index2Type<3>
125 {
126  typedef short type;
127 };
128 
129 template<> struct PETE_Index2Type<4>
130 {
131  typedef int type;
132 };
133 
134 template<> struct PETE_Index2Type<5>
135 {
136  typedef long type;
137 };
138 
139 template<> struct PETE_Index2Type<6>
140 {
141  typedef float type;
142 };
143 
144 template<> struct PETE_Index2Type<7>
145 {
146  typedef double type;
147 };
148 
149 #endif
150 
151 
153 //
154 // CLASS NAME
155 // PETEUnaryReturn<T, Op>
156 //
157 // DESCRIPTION
158 // This template describes the default mechanism for calculating the
159 // return type to a unary expression given the argument type T and
160 // the operation type Op.
161 //
162 // There are two sensible things one can do automatically:
163 // o (Op::tag == PETE_UnaryPassThruTag) make the return type
164 // the same as the argument to the function/operation.
165 // For example, operator-(T) should return a T.
166 // o (Op::tag != PETE_UnaryPassThruTag) return a type based entirely on
167 // the operation. For example, operator! always returns a bool.
168 // To figure out which approach to take, PETEUnaryReturn uses the
169 // tag from the operator and another template, PETE_ComputeUnaryType.
170 // Consider negation (unary minus). The operator would be formed like:
171 // struct OpUnaryMinus {
172 // enum { tag = PETE_UnaryPassThruTag };
173 // };
174 // Logical negation (not) would be formed like:
175 // struct OpNot {
176 // enum { tag = PETE_Type2Index<bool> };
177 // typedef bool type;
178 // };
179 // The minor redundancy (specifying the tag and the type) is required to
180 // allow easy support for compilers that may or may not support partial
181 // specialization.
182 //
183 // Special cases can be handled by directly specializing PETEUnaryReturn.
184 // For example, the abs function typically returns a double when the
185 // argument is a complex<double>. The appropriate specialization here
186 // would be:
187 // template<> struct PETEUnaryReturn< complex<double>, FnAbs > {
188 // typedef double type;
189 // };
190 //
192 
193 const int PETE_UnaryPassThruTag = 0;
194 
195 #if defined(IPPL_USE_PARTIAL_SPECIALIZATION)
196 
197 template<class T, class Op, int OpTag>
199 {
200  typedef typename Op::type type;
201 };
202 
203 template<class T, class Op>
205 {
206  typedef T type;
207 };
208 
209 template<class T, class Op>
210 struct PETEUnaryReturn
211 {
213 };
214 
215 #else
216 
217 template<int t, int op>
219 {
220  typedef typename
222 };
223 
224 template<class T, class Op>
226 {
227  typedef typename
229 };
230 
231 #endif
232 
233 
235 //
236 // CLASS NAME
237 // PETEBinaryReturn<T1, T2, Op>
238 //
239 // DESCRIPTION
240 // This template describes the default mechanism for calculating the
241 // return type to a binary expression given the argument types T1 and
242 // T2 and the operation type Op.
243 //
244 // There are four sensible things one can do automatically:
245 // o (Op::tag == PETE_BinaryPromoteTag) make the return type by
246 // promoting/converting the "simpler" type into the more "complex."
247 // For example, we typically want to do this with addition.
248 // o (Op::tag == PETE_BinaryUseLeftTag) return the type of the
249 // left-hand operand. For example, this is what happens with operator<<.
250 // o (Op::tag == PETE_BinaryUseRightTag) return the type of the
251 // right-hand operand.
252 // o (otherwise) return a type based entirely on the operation.
253 // For example, operator!= always returns a bool.
254 // To figure out which approach to take, PETEBinaryReturn uses the
255 // tag from the operator and another template, PETE_ComputeBinaryType.
256 // Consider addition. The operator would be formed like:
257 // struct OpAdd {
258 // enum { tag = PETE_BinaryPromoteTag };
259 // };
260 //
261 // Special cases can be handled by directly specializing PETEBinaryReturn.
262 // For example, the multipplication between a matrix and a vector might do a
263 // matrix/vector product, thereby returning a vector. The appropriate
264 // specialization here would be:
265 // struct PETEBinaryReturn< Mat<double,3>, Vec<float,3>, OpMultipply > {
266 // typedef Vector<double,3> type;
267 // };
268 // Notice how the element type is promoted.
269 //
271 
272 const int PETE_BinaryPromoteTag = -2;
273 const int PETE_BinaryUseLeftTag = -1;
275 
276 #if defined(IPPL_USE_PARTIAL_SPECIALIZATION)
277 
278 // This is still harder than it has to be. There are bugs in
279 // the EDG front end.
280 
281 template<class T1, class T2, class Op, int op>
283 {
284  typedef typename Op::type type;
285 };
286 
287 template<class T1, class T2, class Op>
289 {
290  typedef T1 type;
291 };
292 
293 template<class T1, class T2, class Op>
295 {
296  typedef T2 type;
297 };
298 
299 template<class T1, class T2, bool lr>
300 struct PETE_ComputePromoteType
301 {
302 };
303 
304 template<class T1, class T2>
305 struct PETE_ComputePromoteType<T1, T2, true>
306 {
307  typedef T1 type;
308 };
309 
310 template<class T1, class T2>
311 struct PETE_ComputePromoteType<T1, T2, false>
312 {
313  typedef T2 type;
314 };
315 
316 template<class T1, class T2, int t1, int t2>
317 struct PETE_ComputePromoteType2
318 {
319  typedef typename
320  PETE_ComputePromoteType<T1, T2, (t1 >= t2)>::type type;
321 };
322 
323 template<class T1, class T2, class Op>
325 {
326  typedef typename PETE_ComputePromoteType2<T1, T2,
328 };
329 
330 template<class T1, class T2, class Op>
331 struct PETEBinaryReturn
332 {
334 };
335 
336 #else
337 
338 template<int t1, int t2, int op>
340 {
341  typedef typename PETE_Index2Type
342  <(op == PETE_BinaryPromoteTag ?
343  (t1 >= t2 ? t1 : t2) :
344  (op == PETE_BinaryUseLeftTag ? t1 :
345  (op == PETE_BinaryUseRightTag ? t2 : op)))>::type type;
346 };
347 
348 template<class T1, class T2, class Op>
350 {
351  typedef typename PETE_ComputeBinaryType
353 };
354 
355 #endif
356 
357 
359 //
360 // CLASS NAME
361 // PETETrinaryReturn<T1, T2, T3, Op>
362 //
363 // DESCRIPTION
364 // This template describes the default mechanism for calculating the
365 // return type to a trinary expression given the argument types T1, T2, and
366 // T3 and the operation type Op. The only trinary expression supported
367 // in C++ is the ?: operation. In this case, T1 should end up being bool
368 // and the result of the calculation is of type Binary_Promotion(T1,T2)
369 // with the value being that associated with T2 if T1's associated value
370 // turns out to be true and T3 if T1's associated value turns out to be
371 // false.
372 //
374 
375 #if defined(IPPL_USE_PARTIAL_SPECIALIZATION)
376 
377 template<class T1, class T2, class T3, class Op>
378 struct PETETrinaryReturn
379 {
381 };
382 
383 #else
384 
385 template<class T1, class T2, class T3, class Op>
387 {
388  typedef typename PETE_ComputeBinaryType
390 };
391 
392 #endif
393 
394 
396 //
397 // UNARY OPERATORS: -, +, ~, !, Identity
398 //
400 
402 {
403 #ifdef IPPL_PURIFY
404  OpIdentity() {}
405  OpIdentity(const OpIdentity &) {}
406  OpIdentity& operator=(const OpIdentity &) { return *this; }
407 #endif
409 };
410 
412 {
413 #ifdef IPPL_PURIFY
414  OpUnaryMinus() {}
415  OpUnaryMinus(const OpUnaryMinus &) {}
416  OpUnaryMinus& operator=(const OpUnaryMinus &) { return *this; }
417 #endif
419 };
420 
422 {
423 #ifdef IPPL_PURIFY
424  OpUnaryPlus() {}
425  OpUnaryPlus(const OpUnaryPlus &) {}
426  OpUnaryPlus& operator=(const OpUnaryPlus &) { return *this; }
427 #endif
429 };
430 
432 {
433 #ifdef IPPL_PURIFY
434  OpBitwiseNot() {}
435  OpBitwiseNot(const OpBitwiseNot &) {}
436  OpBitwiseNot& operator=(const OpBitwiseNot &) { return *this; }
437 #endif
439 };
440 
441 struct OpNot
442 {
443 #ifdef IPPL_PURIFY
444  OpNot() {}
445  OpNot(const OpNot &) {}
446  OpNot& operator=(const OpNot &) { return *this; }
447 #endif
448  typedef bool type;
450 };
451 
452 template <class T>
453 struct OpCast
454 {
455 #ifdef IPPL_PURIFY
456  OpCast() {}
457  OpCast(const OpCast<T> &) {}
458  OpCast& operator=(const OpCast<T> &) { return *this; }
459 #endif
460  typedef T type;
462 };
463 
465 //
466 // UNARY FUNCTIONS: acos, asin, atan, ceil, cos, cosh, exp, fabs, floor,
467 // log, log10, sin, sinh, sqrt, tan, tanh
468 //
470 
471 struct FnArcCos
472 {
473 #ifdef IPPL_PURIFY
474  FnArcCos() {}
475  FnArcCos(const FnArcCos &) {}
476  FnArcCos& operator=(const FnArcCos &) { return *this; }
477 #endif
479 };
480 
481 struct FnArcSin
482 {
483 #ifdef IPPL_PURIFY
484  FnArcSin() {}
485  FnArcSin(const FnArcSin &) {}
486  FnArcSin& operator=(const FnArcSin &) { return *this; }
487 #endif
489 };
490 
491 struct FnArcTan
492 {
493 #ifdef IPPL_PURIFY
494  FnArcTan() {}
495  FnArcTan(const FnArcTan &) {}
496  FnArcTan& operator=(const FnArcTan &) { return *this; }
497 #endif
499 };
500 
501 struct FnCeil
502 {
503 #ifdef IPPL_PURIFY
504  FnCeil() {}
505  FnCeil(const FnCeil &) {}
506  FnCeil& operator=(const FnCeil &) { return *this; }
507 #endif
509 };
510 
511 struct FnCos
512 {
513 #ifdef IPPL_PURIFY
514  FnCos() {}
515  FnCos(const FnCos &) {}
516  FnCos& operator=(const FnCos &) { return *this; }
517 #endif
519 };
520 
521 struct FnHypCos
522 {
523 #ifdef IPPL_PURIFY
524  FnHypCos() {}
525  FnHypCos(const FnHypCos &) {}
526  FnHypCos& operator=(const FnHypCos &) { return *this; }
527 #endif
529 };
530 
531 struct FnExp
532 {
533 #ifdef IPPL_PURIFY
534  FnExp() {}
535  FnExp(const FnExp &) {}
536  FnExp& operator=(const FnExp &) { return *this; }
537 #endif
539 };
540 
541 struct FnFabs
542 {
543 #ifdef IPPL_PURIFY
544  FnFabs() {}
545  FnFabs(const FnFabs &) {}
546  FnFabs& operator=(const FnFabs &) { return *this; }
547 #endif
549 };
550 
551 struct FnFloor
552 {
553 #ifdef IPPL_PURIFY
554  FnFloor() {}
555  FnFloor(const FnFloor &) {}
556  FnFloor& operator=(const FnFloor &) { return *this; }
557 #endif
559 };
560 
561 struct FnLog
562 {
563 #ifdef IPPL_PURIFY
564  FnLog() {}
565  FnLog(const FnLog &) {}
566  FnLog& operator=(const FnLog &) { return *this; }
567 #endif
569 };
570 
571 struct FnLog10
572 {
573 #ifdef IPPL_PURIFY
574  FnLog10() {}
575  FnLog10(const FnLog10 &) {}
576  FnLog10& operator=(const FnLog10 &) { return *this; }
577 #endif
579 };
580 
581 struct FnSin
582 {
583 #ifdef IPPL_PURIFY
584  FnSin() {}
585  FnSin(const FnSin &) {}
586  FnSin& operator=(const FnSin &) { return *this; }
587 #endif
589 };
590 
591 struct FnHypSin
592 {
593 #ifdef IPPL_PURIFY
594  FnHypSin() {}
595  FnHypSin(const FnHypSin &) {}
596  FnHypSin& operator=(const FnHypSin &) { return *this; }
597 #endif
599 };
600 
601 struct FnSqrt
602 {
603 #ifdef IPPL_PURIFY
604  FnSqrt() {}
605  FnSqrt(const FnSqrt &) {}
606  FnSqrt& operator=(const FnSqrt &) { return *this; }
607 #endif
609 };
610 
611 struct FnTan
612 {
613 #ifdef IPPL_PURIFY
614  FnTan() {}
615  FnTan(const FnTan &) {}
616  FnTan& operator=(const FnTan &) { return *this; }
617 #endif
619 };
620 
621 struct FnHypTan
622 {
623 #ifdef IPPL_PURIFY
624  FnHypTan() {}
625  FnHypTan(const FnHypTan &) {}
626  FnHypTan& operator=(const FnHypTan &) { return *this; }
627 #endif
629 };
630 
631 struct FnErf
632 {
633 #ifdef IPPL_PURIFY
634  FnErf() {}
635  FnErf(const FnErf &) {}
636  FnErf& operator=(const FnErf &) { return *this; }
637 #endif
639 };
640 
641 
643 //
644 // BINARY OPERATORS: +, -, *, /, %, <, >, <=, >=, ==, !=, &&, ||, ^, &,
645 // |, <<, >>
646 //
648 
649 struct OpAdd
650 {
651 #ifdef IPPL_PURIFY
652  OpAdd() {}
653  OpAdd(const OpAdd &) {}
654  OpAdd& operator=(const OpAdd &) { return *this; }
655 #endif
657 };
658 
660 {
661 #ifdef IPPL_PURIFY
662  OpSubtract() {}
663  OpSubtract(const OpSubtract &) {}
664  OpSubtract& operator=(const OpSubtract &) { return *this; }
665 #endif
667 };
668 
670 {
671 #ifdef IPPL_PURIFY
672  OpMultipply() {}
673  OpMultipply(const OpMultipply &) {}
674  OpMultipply& operator=(const OpMultipply &) { return *this; }
675 #endif
677 };
678 
679 struct OpDivide
680 {
681 #ifdef IPPL_PURIFY
682  OpDivide() {}
683  OpDivide(const OpDivide &) {}
684  OpDivide& operator=(const OpDivide &) { return *this; }
685 #endif
687 };
688 
689 struct OpMod
690 {
691 #ifdef IPPL_PURIFY
692  OpMod() {}
693  OpMod(const OpMod &) {}
694  OpMod& operator=(const OpMod &) { return *this; }
695 #endif
697 };
698 
699 struct OpLT
700 {
701 #ifdef IPPL_PURIFY
702  OpLT() {}
703  OpLT(const OpLT &) {}
704  OpLT& operator=(const OpLT &) { return *this; }
705 #endif
706  typedef bool type;
708 };
709 
710 struct OpGT
711 {
712 #ifdef IPPL_PURIFY
713  OpGT() {}
714  OpGT(const OpGT &) {}
715  OpGT& operator=(const OpGT &) { return *this; }
716 #endif
717  typedef bool type;
719 };
720 
721 struct OpLE
722 {
723 #ifdef IPPL_PURIFY
724  OpLE() {}
725  OpLE(const OpLE &) {}
726  OpLE& operator=(const OpLE &) { return *this; }
727 #endif
728  typedef bool type;
730 };
731 
732 struct OpGE
733 {
734 #ifdef IPPL_PURIFY
735  OpGE() {}
736  OpGE(const OpGE &) {}
737  OpGE& operator=(const OpGE &) { return *this; }
738 #endif
739  typedef bool type;
741 };
742 
743 struct OpEQ
744 {
745 #ifdef IPPL_PURIFY
746  OpEQ() {}
747  OpEQ(const OpEQ &) {}
748  OpEQ& operator=(const OpEQ &) { return *this; }
749 #endif
750  typedef bool type;
752 };
753 
754 struct OpNE
755 {
756 #ifdef IPPL_PURIFY
757  OpNE() {}
758  OpNE(const OpNE &) {}
759  OpNE& operator=(const OpNE &) { return *this; }
760 #endif
761  typedef bool type;
763 };
764 
765 struct OpAnd
766 {
767 #ifdef IPPL_PURIFY
768  OpAnd() {}
769  OpAnd(const OpAnd &) {}
770  OpAnd& operator=(const OpAnd &) { return *this; }
771 #endif
772  typedef bool type;
774 };
775 
776 struct OpOr
777 {
778 #ifdef IPPL_PURIFY
779  OpOr() {}
780  OpOr(const OpOr &) {}
781  OpOr& operator=(const OpOr &) { return *this; }
782 #endif
783  typedef bool type;
785 };
786 
788 {
789 #ifdef IPPL_PURIFY
790  OpBitwiseXor() {}
791  OpBitwiseXor(const OpBitwiseXor &) {}
792  OpBitwiseXor& operator=(const OpBitwiseXor &) { return *this; }
793 #endif
795 };
796 
798 {
799 #ifdef IPPL_PURIFY
800  OpBitwiseAnd() {}
801  OpBitwiseAnd(const OpBitwiseAnd &) {}
802  OpBitwiseAnd& operator=(const OpBitwiseAnd &) { return *this; }
803 #endif
805 };
806 
808 {
809 #ifdef IPPL_PURIFY
810  OpBitwiseOr() {}
811  OpBitwiseOr(const OpBitwiseOr &) {}
812  OpBitwiseOr& operator=(const OpBitwiseOr &) { return *this; }
813 #endif
815 };
816 
818 {
819 #ifdef IPPL_PURIFY
820  OpLeftShift() {}
821  OpLeftShift(const OpLeftShift &) {}
822  OpLeftShift& operator=(const OpLeftShift &) { return *this; }
823 #endif
825 };
826 
828 {
829 #ifdef IPPL_PURIFY
830  OpRightShift() {}
831  OpRightShift(const OpRightShift &) {}
832  OpRightShift& operator=(const OpRightShift &) { return *this; }
833 #endif
835 };
836 
837 
839 //
840 // BINARY FUNCTIONS: copysign, ldexp, pow, fmod, atan2
841 //
843 
845 {
846 #ifdef IPPL_PURIFY
847  FnCopysign() {}
848  FnCopysign(const FnCopysign &) {}
849  FnCopysign& operator=(const FnCopysign &) { return *this; }
850 #endif
852 };
853 
854 struct FnLdexp
855 {
856 #ifdef IPPL_PURIFY
857  FnLdexp() {}
858  FnLdexp(const FnLdexp &) {}
859  FnLdexp& operator=(const FnLdexp &) { return *this; }
860 #endif
862 };
863 
864 struct FnPow
865 {
866 #ifdef IPPL_PURIFY
867  FnPow() {}
868  FnPow(const FnPow &) {}
869  FnPow& operator=(const FnPow &) { return *this; }
870 #endif
872 };
873 
874 struct FnFmod
875 {
876 #ifdef IPPL_PURIFY
877  FnFmod() {}
878  FnFmod(const FnFmod &) {}
879  FnFmod& operator=(const FnFmod &) { return *this; }
880 #endif
882 };
883 
884 struct FnArcTan2
885 {
886 #ifdef IPPL_PURIFY
887  FnArcTan2() {}
888  FnArcTan2(const FnArcTan2 &) {}
889  FnArcTan2& operator=(const FnArcTan2 &) { return *this; }
890 #endif
892 };
893 
894 
896 //
897 // ASSIGNMENT OPERATORS: =, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=
898 //
900 
901 struct OpAssign
902 {
903 #ifdef IPPL_PURIFY
904  OpAssign() {}
905  OpAssign(const OpAssign &) {}
906  OpAssign& operator=(const OpAssign &) { return *this; }
907 #endif
909 };
910 
912 {
913 #ifdef IPPL_PURIFY
914  OpAddAssign() {}
915  OpAddAssign(const OpAddAssign &) {}
916  OpAddAssign& operator=(const OpAddAssign &) { return *this; }
917 #endif
919 };
920 
922 {
923 #ifdef IPPL_PURIFY
924  OpSubtractAssign() {}
926  OpSubtractAssign& operator=(const OpSubtractAssign &) { return *this; }
927 #endif
929 };
930 
932 {
933 #ifdef IPPL_PURIFY
934  OpMultipplyAssign() {}
936  OpMultipplyAssign& operator=(const OpMultipplyAssign &) { return *this; }
937 #endif
939 };
940 
942 {
943 #ifdef IPPL_PURIFY
944  OpDivideAssign() {}
945  OpDivideAssign(const OpDivideAssign &) {}
946  OpDivideAssign& operator=(const OpDivideAssign &) { return *this; }
947 #endif
949 };
950 
952 {
953 #ifdef IPPL_PURIFY
954  OpModAssign() {}
955  OpModAssign(const OpModAssign &) {}
956  OpModAssign& operator=(const OpModAssign &) { return *this; }
957 #endif
959 };
960 
962 {
963 #ifdef IPPL_PURIFY
964  OpBitwiseXorAssign() {}
966  OpBitwiseXorAssign& operator=(const OpBitwiseXorAssign &) { return *this; }
967 #endif
969 };
970 
972 {
973 #ifdef IPPL_PURIFY
974  OpBitwiseAndAssign() {}
976  OpBitwiseAndAssign& operator=(const OpBitwiseAndAssign &) { return *this; }
977 #endif
979 };
980 
982 {
983 #ifdef IPPL_PURIFY
984  OpBitwiseOrAssign() {}
986  OpBitwiseOrAssign& operator=(const OpBitwiseOrAssign &) { return *this; }
987 #endif
989 };
990 
992 {
993 #ifdef IPPL_PURIFY
994  OpLeftShiftAssign() {}
996  OpLeftShiftAssign& operator=(const OpLeftShiftAssign &) { return *this; }
997 #endif
999 };
1000 
1002 {
1003 #ifdef IPPL_PURIFY
1004  OpRightShiftAssign() {}
1006  OpRightShiftAssign& operator=(const OpRightShiftAssign &) { return *this; }
1007 #endif
1009 };
1010 
1011 
1013 //
1014 // TRINARY OPERATORS: ?: (where)
1015 //
1017 
1018 struct OpWhere
1019 {
1020 #ifdef IPPL_PURIFY
1021  OpWhere() {}
1022  OpWhere(const OpWhere &) {}
1023  OpWhere& operator=(const OpWhere &) { return *this; }
1024 #endif
1026 };
1027 
1028 
1030 //
1031 // END OF FILE
1032 //
1034 
1035 #endif // TYPE_COMPUTATIONS_H
1036 
1037 /***************************************************************************
1038  * $RCSfile: TypeComputations.h,v $ $Author: adelmann $
1039  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:28 $
1040  * IPPL_VERSION_ID: $Id: TypeComputations.h,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $
1041  ***************************************************************************/
short short short short OpGE
Definition: rbendmap.h:8
short short short short short OpNE
const int PETE_BinaryUseLeftTag
const int PETE_BinaryPromoteTag
PETE_ComputeUnaryType< PETE_Type2Index< T >::val, Op::tag >::type type
const int PETE_BinaryUseRightTag
PETE_Index2Type<(op==PETE_UnaryPassThruTag?t:op)>::type type
PETE_ComputeBinaryType< PETE_Type2Index< T2 >::val, PETE_Type2Index< T3 >::val, Op::tag >::type type
const int PETE_UnaryPassThruTag
short short short OpLE
PETE_ComputeBinaryType< PETE_Type2Index< T1 >::val, PETE_Type2Index< T2 >::val, Op::tag >::type type
PETE_Index2Type<(op==PETE_BinaryPromoteTag?(t1 >=t2?t1:t2):(op==PETE_BinaryUseLeftTag?t1:(op==PETE_BinaryUseRightTag?t2:op)))>::type type