00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef _TemplateTools_h
00044 #define _TemplateTools_h
00045
00046 #include "NullType.h"
00047 #include "TypeManip.h"
00048 #include "Typelist.h"
00049
00050 #include <limits>
00051 #include <utility>
00052 #include <cstdlib>
00053 #include <cmath>
00054
00055 namespace BSUtilities {
00056
00058
00059
00060
00062
00064
00068 template<bool condition, class Then, class Else>
00069 struct IF
00070 {
00071 typedef Then RET;
00072 };
00073
00074 template<class Then, class Else>
00075 struct IF<false, Then, Else>
00076 {
00077 typedef Else RET;
00078 };
00079
00081
00084 template<bool Arg1, bool Arg2>
00085 struct OR
00086 {
00087 enum {RET = false};
00088 };
00089
00091
00094 template<bool Arg2>
00095 struct OR<true, Arg2>
00096 {
00097 enum {RET = true};
00098 };
00099
00101
00104 template<bool Arg1>
00105 struct OR<Arg1, true>
00106 {
00107 enum {RET = true};
00108 };
00109
00111
00114 template<>
00115 struct OR<true, true>
00116 {
00117 enum {RET = true};
00118 };
00119
00121
00122
00123
00125
00127
00130 template<class X> class EmptyTemplate_1 {};
00131
00133
00136 template<class X, class Y> class EmptyTemplate_2 {};
00137
00139
00141 template<class X, class Y>
00142 struct SameType
00143 {
00144 enum {sameType = false};
00145 };
00146
00148 template<class X>
00149 struct SameType<X, X>
00150 {
00151 enum {sameType = true};
00152 };
00153
00155
00157 template<template<class> class X, template<class> class Y>
00158 struct SameTemplate_1
00159 {
00160 enum {sameTemplate_1 = false};
00161 };
00162
00164
00166 template<template<class> class X>
00167 struct SameTemplate_1<X, X>
00168 {
00169 enum {sameTemplate_1 = true};
00170 };
00171
00173
00175 template<template<class, class> class X, template<class, class> class Y>
00176 struct SameTemplate_2
00177 {
00178 enum {sameTemplate_2 = false};
00179 };
00180
00182
00184 template<template<class, class> class X>
00185 struct SameTemplate_2<X, X>
00186 {
00187 enum {sameTemplate_2 = true};
00188 };
00189
00191
00192
00193
00195
00197
00200 template<class A, class B> struct Concatenate;
00201
00202 template<class Head1, class Head2, class Tail1, class Tail2>
00203 struct Concatenate<Loki::Typelist<Head1, Tail1>,
00204 Loki::Typelist<Head2, Tail2> >
00205 {typedef Loki::Typelist<Head1,
00206 typename Concatenate<Tail1, Loki::Typelist<Head2, Tail2> >
00207 ::Result > Result;};
00208
00209 template<class A> struct Concatenate<A, Loki::NullType>
00210 {typedef A Result;};
00211
00212 template<class B> struct Concatenate<Loki::NullType, B>
00213 {typedef B Result;};
00214
00216
00217
00218
00220
00223 template<long N>
00224 struct Signum {static long const RET = (N < 0L) ? -1L : +1L;};
00225
00228 template<> struct Signum<0L> {static long const RET = 0L;};
00229
00232 template<long N>
00233 struct Abs {static long const RET = (N < 0L) ? -N : N;};
00234
00238 template<long M, long N>
00239 struct Gcd
00240 {
00241 private:
00242 static long const m = Abs<M>::RET;
00243 static long const n = Abs<N>::RET;
00244
00245 public:
00246 static long const RET = Gcd<n, m%n>::RET;
00247 };
00248
00251 template<long M> struct Gcd<M, 0L>
00252 {static long const RET = Abs<M>::RET;};
00253
00256 template<> struct Gcd<0L, 0L> {static long const RET = 1L;};
00257
00259
00262 inline long gcd (const long &i1, const long &i2)
00263 {
00264 if (i2 == 0L && i1 == 0L)
00265 return 1L;
00266 else if (i2 == 0L)
00267 return std::abs(i1);
00268 else
00269 return gcd (std::abs(i2), std::abs (i1%i2));
00270 }
00271
00273
00288 template<class T>
00289 std::pair<long, long> contFrac (const T &value)
00290 {
00291 bool isNegative = (value < T(0.0));
00292
00293 long p1 = 0;
00294 long p2 = 1;
00295 long q1 = 1;
00296 long q2 = 0;
00297
00298 long p0;
00299 long q0;
00300
00301 long i = 0;
00302 T s = std::abs(value);
00303
00304 long limit = std::numeric_limits<long>::max ();
00305
00306 while (p2 < limit && q2 < limit)
00307 {
00308 p0 = p1;
00309 q0 = q1;
00310 p1 = p2;
00311 q1 = q2;
00312
00313 i = long (floor (s));
00314
00315 p2 = p0 + i * p1;
00316 q2 = q0 + i * q1;
00317
00318
00319 if (std::abs(std::abs(value) - T(p2)/T(q2))
00320 > std::numeric_limits<T>::epsilon ())
00321 s = 1/(s - floor(s));
00322
00323 else
00324 {
00325 p1 = p2;
00326 q1 = q2;
00327 break;
00328 }
00329 }
00330
00331 if (isNegative)
00332 p1 = -p1;
00333
00334 return std::make_pair (p1, q1);
00335 }
00336
00341 template<long N, long D=1L>
00342 struct Rational
00343 {
00344 private:
00345 static long const gcd = Signum<D>::RET * Gcd<N,D>::RET;
00346
00347 public:
00348 static long const numerator = N;
00349 static long const denominator = D;
00350
00351 typedef Rational<N/gcd, D/gcd> Canonical;
00352
00354 template<class To>
00355 static To convert()
00356 {return static_cast<To>(N)/static_cast<To>(D);}
00357
00358 };
00359
00361 template<long D>
00362 struct Rational<0L, D>
00363 {
00364 public:
00365 static long const numerator = 0L;
00366 static long const denominator = 1L;
00367
00368 typedef Rational<0L, 1L> Canonical;
00369
00372 template<class To>
00373 static To convert() {return static_cast<To>(0);}
00374 };
00375
00377
00380 template<class R1, class R2> class RationalEquality;
00382 template<long N1, long D1, long N2, long D2>
00383 class RationalEquality<Rational<N1, D1>, Rational<N2, D2> >
00384 {
00385 private:
00386 typedef Rational<N1, D1> R1;
00387 typedef Rational<N2, D2> R2;
00388
00389 public:
00390 enum {RET = ((R1::Canonical::numerator
00391 == R2::Canonical::numerator)
00392 && (R1::Canonical::denominator == R2::Canonical::denominator))
00393 ? 1 : 0 };
00394 };
00395
00397 template<class R1, class R2> class RationalAdd;
00399
00406 template<long N1, long D1, long N2, long D2>
00407 class RationalAdd<Rational<N1, D1>, Rational<N2, D2> >
00408 {
00409 private:
00410 typedef Rational<N1, D1> R1;
00411 typedef Rational<N2, D2> R2;
00412
00413 public:
00414 typedef typename
00415 Rational<R1::Canonical::numerator * R2::Canonical::denominator
00416 + R2::Canonical::numerator * R1::Canonical::denominator,
00417 R1::Canonical::denominator * R2::Canonical::denominator>
00418 ::Canonical RET;
00419 };
00420
00422 template<class R1, class R2> class RationalSub;
00424
00431 template<long N1, long D1, long N2, long D2>
00432 class RationalSub<Rational<N1, D1>, Rational<N2, D2> >
00433 {
00434 private:
00435 typedef Rational<N1, D1> R1;
00436 typedef Rational<N2, D2> R2;
00437
00438 public:
00439 typedef typename
00440 Rational<R1::Canonical::numerator * R2::Canonical::denominator
00441 - R2::Canonical::numerator * R1::Canonical::denominator,
00442 R1::Canonical::denominator * R2::Canonical::denominator>
00443 ::Canonical RET;
00444 };
00445
00447 template<class R1, class R2> class RationalMult;
00449
00455 template<long N1, long D1, long N2, long D2>
00456 class RationalMult<Rational<N1, D1>, Rational<N2, D2> >
00457 {
00458 private:
00459 typedef Rational<N1, D1> R1;
00460 typedef Rational<N2, D2> R2;
00461
00462 public:
00463 typedef typename Rational<R1::Canonical::numerator
00464 * R2::Canonical::numerator, R1::Canonical::denominator
00465 * R2::Canonical::denominator>::Canonical RET;
00466 };
00467
00469 template<class R1, class R2> class RationalDiv;
00471
00477 template<long N1, long D1, long N2, long D2>
00478 class RationalDiv<Rational<N1, D1>, Rational<N2, D2> >
00479 {
00480 private:
00481 typedef Rational<N1, D1> R1;
00482 typedef Rational<N2, D2> R2;
00483
00484 public:
00485 typedef typename Rational<R1::Canonical::numerator
00486 * R2::Canonical::denominator, R1::Canonical::denominator
00487 * R2::Canonical::numerator>::Canonical RET;
00488 };
00489
00491 template<class R1> class RationalNeg;
00493
00498 template<long N1, long D1>
00499 class RationalNeg<Rational<N1, D1> >
00500 {
00501 private:
00502 typedef Rational<N1, D1> R1;
00503
00504 public:
00505 typedef typename Rational<-R1::Canonical::numerator,
00506 R1::Canonical::denominator>::Canonical RET;
00507 };
00508
00509 }
00510
00511 #endif