00001
00002 #ifndef RIVET_Cmp_HH
00003 #define RIVET_Cmp_HH
00004
00005 #include "Rivet/Rivet.hh"
00006 #include "Rivet/Projection.hh"
00007 #include "Cmp.fhh"
00008 #include <typeinfo>
00009
00010
00011 namespace Rivet {
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 template <typename T>
00024 class Cmp {
00025
00026 public:
00027
00028
00029 enum CmpState {
00030 undefined = -2,
00031 ordered = -1,
00032 equivalent = 0,
00033 unordered = 1
00034 };
00035
00036 public:
00037
00038
00039
00040
00041 inline Cmp(const T & t1, const T & t2);
00042
00043
00044 template <typename U>
00045 inline Cmp(const Cmp<U> &);
00046
00047
00048 inline ~Cmp() {};
00049
00050
00051 template <typename U>
00052 inline const Cmp<T> & operator=(const Cmp<U> &);
00053
00054
00055
00056 public:
00057
00058
00059 inline operator int () const;
00060
00061
00062 template <typename U>
00063 inline const Cmp<T> & operator||(const Cmp<U> & c) const;
00064
00065 private:
00066
00067
00068 inline void compare() const;
00069
00070 private:
00071
00072
00073 mutable int value;
00074
00075
00076 pair<const T *, const T *> objects;
00077
00078 };
00079
00080
00081 template <typename T>
00082 inline Cmp<T> cmp(const T & t1, const T & t2) {
00083 return Cmp<T>(t1, t2);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 template <>
00099 class Cmp<Projection> {
00100
00101 public:
00102
00103
00104 enum CmpState {
00105 undefined = -2,
00106 ordered = -1,
00107 equivalent = 0,
00108 unordered = 1
00109 };
00110
00111 public:
00112
00113
00114
00115
00116 inline Cmp(const Projection & p1, const Projection & p2);
00117
00118
00119 template <typename U>
00120 inline Cmp(const Cmp<U> &);
00121
00122
00123 inline ~Cmp() {};
00124
00125
00126 template <typename U>
00127 inline const Cmp<Projection> & operator=(const Cmp<U> &);
00128
00129
00130
00131 public:
00132
00133
00134 inline operator int () const;
00135
00136
00137 template <typename U>
00138 inline const Cmp<Projection> & operator||(const Cmp<U> & c) const;
00139
00140 private:
00141
00142
00143 inline void compare() const;
00144
00145 private:
00146
00147
00148 mutable int value;
00149
00150
00151 pair<const Projection *, const Projection *> objects;
00152
00153 };
00154
00155
00156
00157
00158
00159
00160
00161
00162 inline Cmp<Projection> pcmp(const Projection & p1, const Projection & p2) {
00163 return Cmp<Projection>(p1, p2);
00164 }
00165
00166
00167 template <typename T>
00168 inline Cmp<T>::Cmp(const T & t1, const T & t2)
00169 : value(undefined), objects(&t1, &t2) {}
00170
00171 template <typename T>
00172 template <typename U>
00173 inline Cmp<T>::Cmp(const Cmp<U> & x)
00174 : value(x.operator int()), objects(0, 0) {}
00175
00176 template <typename T>
00177 template <typename U>
00178 inline const Cmp<T> & Cmp<T>::operator=(const Cmp<U> & x) {
00179 value = x.operator int();
00180 return *this;
00181 }
00182
00183 template <typename T>
00184 template <typename U>
00185 inline const Cmp<T> & Cmp<T>::operator||(const Cmp<U> & x) const {
00186 compare();
00187 if ( value == equivalent ) value = x.operator int();
00188 return *this;
00189 }
00190
00191 template <typename T>
00192 inline Cmp<T>::operator int() const {
00193 compare();
00194 return value;
00195 }
00196
00197 template <typename T>
00198 inline void Cmp<T>::compare() const {
00199 if ( value == undefined ) {
00200 less<T> l;
00201 if ( l(*objects.first, *objects.second) ) value = ordered;
00202 else if ( l(*objects.second, *objects.first) ) value = unordered;
00203 else value = equivalent;
00204 }
00205 }
00206
00207 inline Cmp<Projection>::Cmp(const Projection & p1, const Projection & p2)
00208 : value(undefined), objects(&p1, &p2) {}
00209
00210 template <typename U>
00211 inline Cmp<Projection>::Cmp(const Cmp<U> & x)
00212 : value(x.operator int()), objects(0, 0) {}
00213
00214 template <typename U>
00215 inline const Cmp<Projection> & Cmp<Projection>::operator=(const Cmp<U> & x) {
00216 value = x.operator int();
00217 return *this;
00218 }
00219
00220 template <typename U>
00221 inline const Cmp<Projection> &
00222 Cmp<Projection>::operator||(const Cmp<U> & x) const {
00223 compare();
00224 if ( value == equivalent ) value = x.operator int();
00225 return *this;
00226 }
00227
00228 inline Cmp<Projection>::operator int() const {
00229 compare();
00230 return value;
00231 }
00232
00233 inline void Cmp<Projection>::compare() const {
00234 if ( value == undefined ) {
00235 const std::type_info & id1 = typeid(*objects.first);
00236 const std::type_info & id2 = typeid(*objects.second);
00237 if ( id1.before(id2) ) value = ordered;
00238 else if ( id2.before(id1) ) value = unordered;
00239 else {
00240 int c = objects.first->compare(*objects.second);
00241 if ( c < 0 ) value = ordered;
00242 else if ( c > 0 ) value = unordered;
00243 else value = equivalent;
00244 }
00245 }
00246 }
00247
00248
00249 }
00250
00251
00252 #endif