src/PETE/TypeComputations.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 
00013 //
00014 // FILE NAME
00015 //    TypeComputations.h
00016 //
00017 // CREATED
00018 //    July 11, 1997
00019 //
00020 // DESCRIPTION
00021 //    PETE: Portable Expression Template Engine.
00022 //
00023 //    This header file defines templates used to construct the
00024 //    return types for unary, binary, and trinary operations.
00025 //
00027 
00028 #ifndef TYPE_COMPUTATIONS_H
00029 #define TYPE_COMPUTATIONS_H
00030 
00031 
00033 //
00034 // CLASS NAME
00035 //    PETE_Type2Index<T>
00036 //
00037 // DESCRIPTION
00038 //    This template describes a set of trait classes that associate an
00039 //    index with a type. Each concrete class---a type that is designed
00040 //    to be used like a built-in type---must have a specialization
00041 //    of this class that provides a unique index. This index is used
00042 //    to figure out the default return type of a binary/trinary operation.
00043 //    Specifically, the largest index is chosen.
00044 //
00046 
00047 template<class Type>
00048 struct PETE_Type2Index
00049 {
00050   enum { val = 666666 };
00051 };
00052 
00053 template<> struct PETE_Type2Index<bool>
00054 {
00055   enum { val = 1 };
00056 };
00057 
00058 template<> struct PETE_Type2Index<char>
00059 {
00060   enum { val = 2 };
00061 };
00062 
00063 template<> struct PETE_Type2Index<short>
00064 {
00065   enum { val = 3 };
00066 };
00067 
00068 template<> struct PETE_Type2Index<int>
00069 {
00070   enum { val = 4 };
00071 };
00072 
00073 template<> struct PETE_Type2Index<long>
00074 {
00075   enum { val = 5 };
00076 };
00077 
00078 template<> struct PETE_Type2Index<float>
00079 {
00080   enum { val = 6 };
00081 };
00082 
00083 template<> struct PETE_Type2Index<double>
00084 {
00085   enum { val = 7 };
00086 };
00087 
00088 
00090 //
00091 // CLASS NAME
00092 //    PETE_Index2Type<Index>
00093 //
00094 // DESCRIPTION
00095 //    This template describes a set of trait classes that associate an
00096 //    a type with an index. Each concrete class---a type that is designed
00097 //    to be used like a built-in type---must have a specialization
00098 //    of this class that provides a type given its unique index.
00099 //
00100 // NOTE
00101 //    It is good form to provide these, but they are really only necessary
00102 //    if your compiler (and all compilers you will ever want to port
00103 //    your code to) support partial specialization.
00104 //
00106 
00107 #if !defined(IPPL_USE_PARTIAL_SPECIALIZATION)
00108 
00109 template<int Index>
00110 struct PETE_Index2Type
00111 {
00112 };
00113 
00114 template<> struct PETE_Index2Type<1>
00115 {
00116   typedef bool type;
00117 };
00118 
00119 template<> struct PETE_Index2Type<2>
00120 {
00121   typedef char type;
00122 };
00123 
00124 template<> struct PETE_Index2Type<3>
00125 {
00126   typedef short type;
00127 };
00128 
00129 template<> struct PETE_Index2Type<4>
00130 {
00131   typedef int type;
00132 };
00133 
00134 template<> struct PETE_Index2Type<5>
00135 {
00136   typedef long type;
00137 };
00138 
00139 template<> struct PETE_Index2Type<6>
00140 {
00141   typedef float type;
00142 };
00143 
00144 template<> struct PETE_Index2Type<7>
00145 {
00146   typedef double type;
00147 };
00148 
00149 #endif
00150 
00151 
00153 //
00154 // CLASS NAME
00155 //    PETEUnaryReturn<T, Op>
00156 //
00157 // DESCRIPTION
00158 //    This template describes the default mechanism for calculating the
00159 //    return type to a unary expression given the argument type T and
00160 //    the operation type Op.
00161 //
00162 //    There are two sensible things one can do automatically:
00163 //      o (Op::tag == PETE_UnaryPassThruTag) make the return type 
00164 //        the same as the argument to the function/operation. 
00165 //        For example, operator-(T) should return a T.
00166 //      o (Op::tag != PETE_UnaryPassThruTag) return a type based entirely on 
00167 //        the operation. For example, operator! always returns a bool.
00168 //    To figure out which approach to take, PETEUnaryReturn uses the
00169 //    tag from the operator and another template, PETE_ComputeUnaryType.
00170 //    Consider negation (unary minus). The operator would be formed like:
00171 //      struct OpUnaryMinus {
00172 //        enum { tag = PETE_UnaryPassThruTag };
00173 //      };
00174 //    Logical negation (not) would be formed like:
00175 //      struct OpNot {
00176 //        enum { tag = PETE_Type2Index<bool> };
00177 //        typedef bool type;
00178 //      };
00179 //    The minor redundancy (specifying the tag and the type) is required to 
00180 //    allow easy support for compilers that may or may not support partial
00181 //    specialization.
00182 //
00183 //    Special cases can be handled by directly specializing PETEUnaryReturn.
00184 //    For example, the abs function typically returns a double when the
00185 //    argument is a complex<double>. The appropriate specialization here
00186 //    would be:
00187 //      template<> struct PETEUnaryReturn< complex<double>, FnAbs > {
00188 //        typedef double type;
00189 //      };
00190 //
00192 
00193 const int PETE_UnaryPassThruTag = 0;
00194 
00195 #if defined(IPPL_USE_PARTIAL_SPECIALIZATION)
00196 
00197 template<class T, class Op, int OpTag>
00198 struct PETE_ComputeUnaryType
00199 {
00200   typedef typename Op::type type;
00201 };
00202 
00203 template<class T, class Op>
00204 struct PETE_ComputeUnaryType<T, Op, PETE_UnaryPassThruTag>
00205 {
00206   typedef T type;
00207 };
00208 
00209 template<class T, class Op>
00210 struct PETEUnaryReturn
00211 {
00212   typedef typename PETE_ComputeUnaryType<T, Op, Op::tag>::type type;
00213 };
00214 
00215 #else
00216 
00217 template<int t, int op>
00218 struct PETE_ComputeUnaryType
00219 {
00220   typedef typename 
00221     PETE_Index2Type<(op == PETE_UnaryPassThruTag ? t : op)>::type type;
00222 };
00223 
00224 template<class T, class Op>
00225 struct PETEUnaryReturn
00226 {
00227   typedef typename
00228     PETE_ComputeUnaryType<PETE_Type2Index<T>::val, Op::tag>::type type;
00229 };
00230 
00231 #endif
00232 
00233 
00235 //
00236 // CLASS NAME
00237 //    PETEBinaryReturn<T1, T2, Op>
00238 //
00239 // DESCRIPTION
00240 //    This template describes the default mechanism for calculating the
00241 //    return type to a binary expression given the argument types T1 and
00242 //    T2 and the operation type Op.
00243 //
00244 //    There are four sensible things one can do automatically:
00245 //      o (Op::tag == PETE_BinaryPromoteTag) make the return type by 
00246 //        promoting/converting the "simpler" type into the more "complex." 
00247 //        For example, we typically want to do this with addition. 
00248 //      o (Op::tag == PETE_BinaryUseLeftTag) return the type of the 
00249 //        left-hand operand. For example, this is what happens with operator<<.
00250 //      o (Op::tag == PETE_BinaryUseRightTag) return the type of the 
00251 //        right-hand operand. 
00252 //      o (otherwise) return a type based entirely on the operation. 
00253 //        For example, operator!= always returns a bool.
00254 //    To figure out which approach to take, PETEBinaryReturn uses the
00255 //    tag from the operator and another template, PETE_ComputeBinaryType.
00256 //    Consider addition. The operator would be formed like:
00257 //      struct OpAdd {
00258 //        enum { tag = PETE_BinaryPromoteTag };
00259 //      };
00260 //
00261 //    Special cases can be handled by directly specializing PETEBinaryReturn.
00262 //    For example, the multipplication between a matrix and a vector might do a
00263 //    matrix/vector product, thereby returning a vector. The appropriate 
00264 //    specialization here would be:
00265 //      struct PETEBinaryReturn< Mat<double,3>, Vec<float,3>, OpMultipply > {
00266 //        typedef Vector<double,3> type;
00267 //      };
00268 //    Notice how the element type is promoted.
00269 //
00271 
00272 const int PETE_BinaryPromoteTag = -2;
00273 const int PETE_BinaryUseLeftTag = -1;
00274 const int PETE_BinaryUseRightTag = 0;
00275 
00276 #if defined(IPPL_USE_PARTIAL_SPECIALIZATION)
00277 
00278 // This is still harder than it has to be. There are bugs in
00279 // the EDG front end.
00280 
00281 template<class T1, class T2, class Op, int op>
00282 struct PETE_ComputeBinaryType
00283 {
00284   typedef typename Op::type type;
00285 };
00286 
00287 template<class T1, class T2, class Op>
00288 struct PETE_ComputeBinaryType<T1, T2, Op, PETE_BinaryUseLeftTag>
00289 {
00290   typedef T1 type;
00291 };
00292 
00293 template<class T1, class T2, class Op>
00294 struct PETE_ComputeBinaryType<T1, T2, Op, PETE_BinaryUseRightTag>
00295 {
00296   typedef T2 type;
00297 };
00298 
00299 template<class T1, class T2, bool lr>
00300 struct PETE_ComputePromoteType
00301 {
00302 };
00303 
00304 template<class T1, class T2>
00305 struct PETE_ComputePromoteType<T1, T2, true>
00306 {
00307   typedef T1 type;
00308 };
00309 
00310 template<class T1, class T2>
00311 struct PETE_ComputePromoteType<T1, T2, false>
00312 {
00313   typedef T2 type;
00314 };
00315 
00316 template<class T1, class T2, int t1, int t2>
00317 struct PETE_ComputePromoteType2
00318 {
00319   typedef typename
00320     PETE_ComputePromoteType<T1, T2, (t1 >= t2)>::type type;
00321 };
00322 
00323 template<class T1, class T2, class Op>
00324 struct PETE_ComputeBinaryType<T1, T2, Op, PETE_BinaryPromoteTag>
00325 {
00326   typedef typename PETE_ComputePromoteType2<T1, T2, 
00327     PETE_Type2Index<T1>::val, PETE_Type2Index<T2>::val>::type type;
00328 };
00329 
00330 template<class T1, class T2, class Op>
00331 struct PETEBinaryReturn
00332 {
00333   typedef typename PETE_ComputeBinaryType<T1, T2, Op, Op::tag>::type type;
00334 };
00335 
00336 #else
00337 
00338 template<int t1, int t2, int op>
00339 struct PETE_ComputeBinaryType
00340 {
00341   typedef typename PETE_Index2Type
00342     <(op == PETE_BinaryPromoteTag ? 
00343      (t1 >= t2 ? t1 : t2) : 
00344      (op == PETE_BinaryUseLeftTag ? t1 : 
00345      (op == PETE_BinaryUseRightTag ? t2 : op)))>::type type;
00346 };
00347 
00348 template<class T1, class T2, class Op>
00349 struct PETEBinaryReturn
00350 {
00351   typedef typename PETE_ComputeBinaryType
00352     <PETE_Type2Index<T1>::val, PETE_Type2Index<T2>::val, Op::tag>::type type;
00353 };
00354 
00355 #endif
00356 
00357 
00359 //
00360 // CLASS NAME
00361 //    PETETrinaryReturn<T1, T2, T3, Op>
00362 //
00363 // DESCRIPTION
00364 //    This template describes the default mechanism for calculating the
00365 //    return type to a trinary expression given the argument types T1, T2, and
00366 //    T3 and the operation type Op. The only trinary expression supported
00367 //    in C++ is the ?: operation. In this case, T1 should end up being bool
00368 //    and the result of the calculation is of type Binary_Promotion(T1,T2)
00369 //    with the value being that associated with T2 if T1's associated value 
00370 //    turns out to be true and T3 if T1's associated value turns out to be 
00371 //    false.
00372 //
00374 
00375 #if defined(IPPL_USE_PARTIAL_SPECIALIZATION)
00376 
00377 template<class T1, class T2, class T3, class Op>
00378 struct PETETrinaryReturn
00379 {
00380   typedef typename PETE_ComputeBinaryType<T2, T3, Op, Op::tag>::type type;
00381 };
00382 
00383 #else
00384 
00385 template<class T1, class T2, class T3, class Op>
00386 struct PETETrinaryReturn
00387 {
00388   typedef typename PETE_ComputeBinaryType
00389   <PETE_Type2Index<T2>::val, PETE_Type2Index<T3>::val, Op::tag>::type type;
00390 };
00391 
00392 #endif
00393 
00394 
00396 //
00397 // UNARY OPERATORS: -, +, ~, !, Identity
00398 //
00400 
00401 struct OpIdentity
00402 {
00403 #ifdef IPPL_PURIFY
00404   OpIdentity() {}
00405   OpIdentity(const OpIdentity &) {}
00406   OpIdentity& operator=(const OpIdentity &) { return *this; }
00407 #endif
00408   enum { tag = PETE_UnaryPassThruTag };
00409 };
00410 
00411 struct OpUnaryMinus
00412 {
00413 #ifdef IPPL_PURIFY
00414   OpUnaryMinus() {}
00415   OpUnaryMinus(const OpUnaryMinus &) {}
00416   OpUnaryMinus& operator=(const OpUnaryMinus &) { return *this; }
00417 #endif
00418   enum { tag = PETE_UnaryPassThruTag };
00419 };
00420 
00421 struct OpUnaryPlus
00422 {
00423 #ifdef IPPL_PURIFY
00424   OpUnaryPlus() {}
00425   OpUnaryPlus(const OpUnaryPlus &) {}
00426   OpUnaryPlus& operator=(const OpUnaryPlus &) { return *this; }
00427 #endif
00428   enum { tag = PETE_UnaryPassThruTag };
00429 };
00430 
00431 struct OpBitwiseNot
00432 {
00433 #ifdef IPPL_PURIFY
00434   OpBitwiseNot() {}
00435   OpBitwiseNot(const OpBitwiseNot &) {}
00436   OpBitwiseNot& operator=(const OpBitwiseNot &) { return *this; }
00437 #endif
00438   enum { tag = PETE_UnaryPassThruTag };
00439 };
00440 
00441 struct OpNot
00442 {
00443 #ifdef IPPL_PURIFY
00444   OpNot() {}
00445   OpNot(const OpNot &) {}
00446   OpNot& operator=(const OpNot &) { return *this; }
00447 #endif
00448   typedef bool type;
00449   enum { tag = PETE_Type2Index<bool>::val };
00450 };
00451 
00452 template <class T>
00453 struct OpCast
00454 {
00455 #ifdef IPPL_PURIFY
00456   OpCast() {}
00457   OpCast(const OpCast<T> &) {}
00458   OpCast& operator=(const OpCast<T> &) { return *this; }
00459 #endif
00460   typedef T type;
00461   enum { tag = PETE_Type2Index<T>::val };
00462 };
00463 
00465 //
00466 // UNARY FUNCTIONS: acos, asin, atan, ceil, cos, cosh, exp, fabs, floor,
00467 //                  log, log10, sin, sinh, sqrt, tan, tanh
00468 //
00470 
00471 struct FnArcCos
00472 {
00473 #ifdef IPPL_PURIFY
00474   FnArcCos() {}
00475   FnArcCos(const FnArcCos &) {}
00476   FnArcCos& operator=(const FnArcCos &) { return *this; }
00477 #endif
00478   enum { tag = PETE_UnaryPassThruTag };
00479 };
00480 
00481 struct FnArcSin
00482 {
00483 #ifdef IPPL_PURIFY
00484   FnArcSin() {}
00485   FnArcSin(const FnArcSin &) {}
00486   FnArcSin& operator=(const FnArcSin &) { return *this; }
00487 #endif
00488   enum { tag = PETE_UnaryPassThruTag };
00489 };
00490 
00491 struct FnArcTan
00492 {
00493 #ifdef IPPL_PURIFY
00494   FnArcTan() {}
00495   FnArcTan(const FnArcTan &) {}
00496   FnArcTan& operator=(const FnArcTan &) { return *this; }
00497 #endif
00498   enum { tag = PETE_UnaryPassThruTag };
00499 };
00500 
00501 struct FnCeil
00502 {
00503 #ifdef IPPL_PURIFY
00504   FnCeil() {}
00505   FnCeil(const FnCeil &) {}
00506   FnCeil& operator=(const FnCeil &) { return *this; }
00507 #endif
00508   enum { tag = PETE_UnaryPassThruTag };
00509 };
00510 
00511 struct FnCos
00512 {
00513 #ifdef IPPL_PURIFY
00514   FnCos() {}
00515   FnCos(const FnCos &) {}
00516   FnCos& operator=(const FnCos &) { return *this; }
00517 #endif
00518   enum { tag = PETE_UnaryPassThruTag };
00519 };
00520 
00521 struct FnHypCos
00522 {
00523 #ifdef IPPL_PURIFY
00524   FnHypCos() {}
00525   FnHypCos(const FnHypCos &) {}
00526   FnHypCos& operator=(const FnHypCos &) { return *this; }
00527 #endif
00528   enum { tag = PETE_UnaryPassThruTag };
00529 };
00530 
00531 struct FnExp
00532 {
00533 #ifdef IPPL_PURIFY
00534   FnExp() {}
00535   FnExp(const FnExp &) {}
00536   FnExp& operator=(const FnExp &) { return *this; }
00537 #endif
00538   enum { tag = PETE_UnaryPassThruTag };
00539 };
00540 
00541 struct FnFabs
00542 {
00543 #ifdef IPPL_PURIFY
00544   FnFabs() {}
00545   FnFabs(const FnFabs &) {}
00546   FnFabs& operator=(const FnFabs &) { return *this; }
00547 #endif
00548   enum { tag = PETE_UnaryPassThruTag };
00549 };
00550 
00551 struct FnFloor
00552 {
00553 #ifdef IPPL_PURIFY
00554   FnFloor() {}
00555   FnFloor(const FnFloor &) {}
00556   FnFloor& operator=(const FnFloor &) { return *this; }
00557 #endif
00558   enum { tag = PETE_UnaryPassThruTag };
00559 };
00560 
00561 struct FnLog
00562 {
00563 #ifdef IPPL_PURIFY
00564   FnLog() {}
00565   FnLog(const FnLog &) {}
00566   FnLog& operator=(const FnLog &) { return *this; }
00567 #endif
00568   enum { tag = PETE_UnaryPassThruTag };
00569 };
00570 
00571 struct FnLog10
00572 {
00573 #ifdef IPPL_PURIFY
00574   FnLog10() {}
00575   FnLog10(const FnLog10 &) {}
00576   FnLog10& operator=(const FnLog10 &) { return *this; }
00577 #endif
00578   enum { tag = PETE_UnaryPassThruTag };
00579 };
00580 
00581 struct FnSin
00582 {
00583 #ifdef IPPL_PURIFY
00584   FnSin() {}
00585   FnSin(const FnSin &) {}
00586   FnSin& operator=(const FnSin &) { return *this; }
00587 #endif
00588   enum { tag = PETE_UnaryPassThruTag };
00589 };
00590 
00591 struct FnHypSin
00592 {
00593 #ifdef IPPL_PURIFY
00594   FnHypSin() {}
00595   FnHypSin(const FnHypSin &) {}
00596   FnHypSin& operator=(const FnHypSin &) { return *this; }
00597 #endif
00598   enum { tag = PETE_UnaryPassThruTag };
00599 };
00600 
00601 struct FnSqrt
00602 {
00603 #ifdef IPPL_PURIFY
00604   FnSqrt() {}
00605   FnSqrt(const FnSqrt &) {}
00606   FnSqrt& operator=(const FnSqrt &) { return *this; }
00607 #endif
00608   enum { tag = PETE_UnaryPassThruTag };
00609 };
00610 
00611 struct FnTan
00612 {
00613 #ifdef IPPL_PURIFY
00614   FnTan() {}
00615   FnTan(const FnTan &) {}
00616   FnTan& operator=(const FnTan &) { return *this; }
00617 #endif
00618   enum { tag = PETE_UnaryPassThruTag };
00619 };
00620 
00621 struct FnHypTan
00622 {
00623 #ifdef IPPL_PURIFY
00624   FnHypTan() {}
00625   FnHypTan(const FnHypTan &) {}
00626   FnHypTan& operator=(const FnHypTan &) { return *this; }
00627 #endif
00628   enum { tag = PETE_UnaryPassThruTag };
00629 };
00630 
00631 
00633 //
00634 // BINARY OPERATORS: +, -, *, /, %, <, >, <=, >=, ==, !=, &&, ||, ^, &, 
00635 //                   |, <<, >>
00636 //
00638 
00639 struct OpAdd
00640 {
00641 #ifdef IPPL_PURIFY
00642   OpAdd() {}
00643   OpAdd(const OpAdd &) {}
00644   OpAdd& operator=(const OpAdd &) { return *this; }
00645 #endif
00646   enum { tag = PETE_BinaryPromoteTag };
00647 };
00648 
00649 struct OpSubtract
00650 {
00651 #ifdef IPPL_PURIFY
00652   OpSubtract() {}
00653   OpSubtract(const OpSubtract &) {}
00654   OpSubtract& operator=(const OpSubtract &) { return *this; }
00655 #endif
00656   enum { tag = PETE_BinaryPromoteTag };
00657 };
00658 
00659 struct OpMultipply
00660 {
00661 #ifdef IPPL_PURIFY
00662   OpMultipply() {}
00663   OpMultipply(const OpMultipply &) {}
00664   OpMultipply& operator=(const OpMultipply &) { return *this; }
00665 #endif
00666   enum { tag = PETE_BinaryPromoteTag };
00667 };
00668 
00669 struct OpDivide
00670 {
00671 #ifdef IPPL_PURIFY
00672   OpDivide() {}
00673   OpDivide(const OpDivide &) {}
00674   OpDivide& operator=(const OpDivide &) { return *this; }
00675 #endif
00676   enum { tag = PETE_BinaryPromoteTag };
00677 };
00678 
00679 struct OpMod
00680 {
00681 #ifdef IPPL_PURIFY
00682   OpMod() {}
00683   OpMod(const OpMod &) {}
00684   OpMod& operator=(const OpMod &) { return *this; }
00685 #endif
00686   enum { tag = PETE_BinaryPromoteTag };
00687 };
00688 
00689 struct OpLT
00690 {
00691 #ifdef IPPL_PURIFY
00692   OpLT() {}
00693   OpLT(const OpLT &) {}
00694   OpLT& operator=(const OpLT &) { return *this; }
00695 #endif
00696   typedef bool type;
00697   enum { tag = PETE_Type2Index<bool>::val };
00698 };
00699 
00700 struct OpGT
00701 {
00702 #ifdef IPPL_PURIFY
00703   OpGT() {}
00704   OpGT(const OpGT &) {}
00705   OpGT& operator=(const OpGT &) { return *this; }
00706 #endif
00707   typedef bool type;
00708   enum { tag = PETE_Type2Index<bool>::val };
00709 };
00710 
00711 struct OpLE
00712 {
00713 #ifdef IPPL_PURIFY
00714   OpLE() {}
00715   OpLE(const OpLE &) {}
00716   OpLE& operator=(const OpLE &) { return *this; }
00717 #endif
00718   typedef bool type;
00719   enum { tag = PETE_Type2Index<bool>::val };
00720 };
00721 
00722 struct OpGE
00723 {
00724 #ifdef IPPL_PURIFY
00725   OpGE() {}
00726   OpGE(const OpGE &) {}
00727   OpGE& operator=(const OpGE &) { return *this; }
00728 #endif
00729   typedef bool type;
00730   enum { tag = PETE_Type2Index<bool>::val };
00731 };
00732 
00733 struct OpEQ
00734 {
00735 #ifdef IPPL_PURIFY
00736   OpEQ() {}
00737   OpEQ(const OpEQ &) {}
00738   OpEQ& operator=(const OpEQ &) { return *this; }
00739 #endif
00740   typedef bool type;
00741   enum { tag = PETE_Type2Index<bool>::val };
00742 };
00743 
00744 struct OpNE
00745 {
00746 #ifdef IPPL_PURIFY
00747   OpNE() {}
00748   OpNE(const OpNE &) {}
00749   OpNE& operator=(const OpNE &) { return *this; }
00750 #endif
00751   typedef bool type;
00752   enum { tag = PETE_Type2Index<bool>::val };
00753 };
00754 
00755 struct OpAnd
00756 {
00757 #ifdef IPPL_PURIFY
00758   OpAnd() {}
00759   OpAnd(const OpAnd &) {}
00760   OpAnd& operator=(const OpAnd &) { return *this; }
00761 #endif
00762   typedef bool type;
00763   enum { tag = PETE_Type2Index<bool>::val };
00764 };
00765 
00766 struct OpOr
00767 {
00768 #ifdef IPPL_PURIFY
00769   OpOr() {}
00770   OpOr(const OpOr &) {}
00771   OpOr& operator=(const OpOr &) { return *this; }
00772 #endif
00773   typedef bool type;
00774   enum { tag = PETE_Type2Index<bool>::val };
00775 };
00776 
00777 struct OpBitwiseXor
00778 {
00779 #ifdef IPPL_PURIFY
00780   OpBitwiseXor() {}
00781   OpBitwiseXor(const OpBitwiseXor &) {}
00782   OpBitwiseXor& operator=(const OpBitwiseXor &) { return *this; }
00783 #endif
00784   enum { tag = PETE_BinaryPromoteTag };
00785 };
00786 
00787 struct OpBitwiseAnd
00788 {
00789 #ifdef IPPL_PURIFY
00790   OpBitwiseAnd() {}
00791   OpBitwiseAnd(const OpBitwiseAnd &) {}
00792   OpBitwiseAnd& operator=(const OpBitwiseAnd &) { return *this; }
00793 #endif
00794   enum { tag = PETE_BinaryPromoteTag };
00795 };
00796 
00797 struct OpBitwiseOr
00798 {
00799 #ifdef IPPL_PURIFY
00800   OpBitwiseOr() {}
00801   OpBitwiseOr(const OpBitwiseOr &) {}
00802   OpBitwiseOr& operator=(const OpBitwiseOr &) { return *this; }
00803 #endif
00804   enum { tag = PETE_BinaryPromoteTag };
00805 };
00806 
00807 struct OpLeftShift
00808 {
00809 #ifdef IPPL_PURIFY
00810   OpLeftShift() {}
00811   OpLeftShift(const OpLeftShift &) {}
00812   OpLeftShift& operator=(const OpLeftShift &) { return *this; }
00813 #endif
00814   enum { tag = PETE_BinaryUseLeftTag };
00815 };
00816 
00817 struct OpRightShift
00818 {
00819 #ifdef IPPL_PURIFY
00820   OpRightShift() {}
00821   OpRightShift(const OpRightShift &) {}
00822   OpRightShift& operator=(const OpRightShift &) { return *this; }
00823 #endif
00824   enum { tag = PETE_BinaryUseLeftTag };
00825 };
00826 
00827 
00829 //
00830 // BINARY FUNCTIONS: copysign, ldexp, pow, fmod, atan2
00831 //
00833 
00834 struct FnCopysign
00835 {
00836 #ifdef IPPL_PURIFY
00837   FnCopysign() {}
00838   FnCopysign(const FnCopysign &) {}
00839   FnCopysign& operator=(const FnCopysign &) { return *this; }
00840 #endif
00841   enum { tag = PETE_BinaryPromoteTag };
00842 };
00843 
00844 struct FnLdexp
00845 {
00846 #ifdef IPPL_PURIFY
00847   FnLdexp() {}
00848   FnLdexp(const FnLdexp &) {}
00849   FnLdexp& operator=(const FnLdexp &) { return *this; }
00850 #endif
00851   enum { tag = PETE_BinaryPromoteTag };
00852 };
00853 
00854 struct FnPow
00855 {
00856 #ifdef IPPL_PURIFY
00857   FnPow() {}
00858   FnPow(const FnPow &) {}
00859   FnPow& operator=(const FnPow &) { return *this; }
00860 #endif
00861   enum { tag = PETE_BinaryPromoteTag };
00862 };
00863 
00864 struct FnFmod
00865 {
00866 #ifdef IPPL_PURIFY
00867   FnFmod() {}
00868   FnFmod(const FnFmod &) {}
00869   FnFmod& operator=(const FnFmod &) { return *this; }
00870 #endif
00871   enum { tag = PETE_BinaryPromoteTag };
00872 };
00873 
00874 struct FnArcTan2
00875 {
00876 #ifdef IPPL_PURIFY
00877   FnArcTan2() {}
00878   FnArcTan2(const FnArcTan2 &) {}
00879   FnArcTan2& operator=(const FnArcTan2 &) { return *this; }
00880 #endif
00881   enum { tag = PETE_BinaryPromoteTag };
00882 };
00883 
00884 
00886 //
00887 // ASSIGNMENT OPERATORS: =, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=
00888 //
00890 
00891 struct OpAssign
00892 {
00893 #ifdef IPPL_PURIFY
00894   OpAssign() {}
00895   OpAssign(const OpAssign &) {}
00896   OpAssign& operator=(const OpAssign &) { return *this; }
00897 #endif
00898   enum { tag = PETE_BinaryUseLeftTag };
00899 };
00900 
00901 struct OpAddAssign
00902 {
00903 #ifdef IPPL_PURIFY
00904   OpAddAssign() {}
00905   OpAddAssign(const OpAddAssign &) {}
00906   OpAddAssign& operator=(const OpAddAssign &) { return *this; }
00907 #endif
00908   enum { tag = PETE_BinaryUseLeftTag };
00909 };
00910 
00911 struct OpSubtractAssign
00912 {
00913 #ifdef IPPL_PURIFY
00914   OpSubtractAssign() {}
00915   OpSubtractAssign(const OpSubtractAssign &) {}
00916   OpSubtractAssign& operator=(const OpSubtractAssign &) { return *this; }
00917 #endif
00918   enum { tag = PETE_BinaryUseLeftTag };
00919 };
00920 
00921 struct OpMultipplyAssign
00922 {
00923 #ifdef IPPL_PURIFY
00924   OpMultipplyAssign() {}
00925   OpMultipplyAssign(const OpMultipplyAssign &) {}
00926   OpMultipplyAssign& operator=(const OpMultipplyAssign &) { return *this; }
00927 #endif
00928   enum { tag = PETE_BinaryUseLeftTag };
00929 };
00930 
00931 struct OpDivideAssign
00932 {
00933 #ifdef IPPL_PURIFY
00934   OpDivideAssign() {}
00935   OpDivideAssign(const OpDivideAssign &) {}
00936   OpDivideAssign& operator=(const OpDivideAssign &) { return *this; }
00937 #endif
00938   enum { tag = PETE_BinaryUseLeftTag };
00939 };
00940 
00941 struct OpModAssign
00942 {
00943 #ifdef IPPL_PURIFY
00944   OpModAssign() {}
00945   OpModAssign(const OpModAssign &) {}
00946   OpModAssign& operator=(const OpModAssign &) { return *this; }
00947 #endif
00948   enum { tag = PETE_BinaryUseLeftTag };
00949 };
00950 
00951 struct OpBitwiseXorAssign
00952 {
00953 #ifdef IPPL_PURIFY
00954   OpBitwiseXorAssign() {}
00955   OpBitwiseXorAssign(const OpBitwiseXorAssign &) {}
00956   OpBitwiseXorAssign& operator=(const OpBitwiseXorAssign &) { return *this; }
00957 #endif
00958   enum { tag = PETE_BinaryUseLeftTag };
00959 };
00960 
00961 struct OpBitwiseAndAssign
00962 {
00963 #ifdef IPPL_PURIFY
00964   OpBitwiseAndAssign() {}
00965   OpBitwiseAndAssign(const OpBitwiseAndAssign &) {}
00966   OpBitwiseAndAssign& operator=(const OpBitwiseAndAssign &) { return *this; }
00967 #endif
00968   enum { tag = PETE_BinaryUseLeftTag };
00969 };
00970 
00971 struct OpBitwiseOrAssign
00972 {
00973 #ifdef IPPL_PURIFY
00974   OpBitwiseOrAssign() {}
00975   OpBitwiseOrAssign(const OpBitwiseOrAssign &) {}
00976   OpBitwiseOrAssign& operator=(const OpBitwiseOrAssign &) { return *this; }
00977 #endif
00978   enum { tag = PETE_BinaryUseLeftTag };
00979 };
00980 
00981 struct OpLeftShiftAssign
00982 {
00983 #ifdef IPPL_PURIFY
00984   OpLeftShiftAssign() {}
00985   OpLeftShiftAssign(const OpLeftShiftAssign &) {}
00986   OpLeftShiftAssign& operator=(const OpLeftShiftAssign &) { return *this; }
00987 #endif
00988   enum { tag = PETE_BinaryUseLeftTag };
00989 };
00990 
00991 struct OpRightShiftAssign
00992 {
00993 #ifdef IPPL_PURIFY
00994   OpRightShiftAssign() {}
00995   OpRightShiftAssign(const OpRightShiftAssign &) {}
00996   OpRightShiftAssign& operator=(const OpRightShiftAssign &) { return *this; }
00997 #endif
00998   enum { tag = PETE_BinaryUseLeftTag };
00999 };
01000 
01001 
01003 //
01004 // TRINARY OPERATORS: ?: (where)
01005 //
01007 
01008 struct OpWhere
01009 {
01010 #ifdef IPPL_PURIFY
01011   OpWhere() {}
01012   OpWhere(const OpWhere &) {}
01013   OpWhere& operator=(const OpWhere &) { return *this; }
01014 #endif
01015   enum { tag = PETE_BinaryPromoteTag };
01016 };
01017 
01018 
01020 //
01021 // END OF FILE
01022 //
01024 
01025 #endif // TYPE_COMPUTATIONS_H
01026 
01027 /***************************************************************************
01028  * $RCSfile: TypeComputations.h,v $   $Author: adelmann $
01029  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:28 $
01030  * IPPL_VERSION_ID: $Id: TypeComputations.h,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $ 
01031  ***************************************************************************/

Generated on Mon Jan 16 13:23:54 2006 for IPPL by  doxygen 1.4.6