00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef INDEX_INLINES_H
00012 #define INDEX_INLINES_H
00013
00014
00015 #include "Utility/Unique.h"
00016 #include "Utility/PAssert.h"
00017
00019
00021 inline
00022 Index::Index()
00023 : First(0),
00024 Stride(0),
00025 Length(0),
00026 BaseFirst(0),
00027 Base(Unique::get())
00028 {
00029 }
00030
00032
00034
00035 inline
00036 Index::Index(unsigned n)
00037 : First(0),
00038 Stride(1),
00039 Length(n),
00040 BaseFirst(0),
00041 Base(Unique::get())
00042 {
00043 }
00044
00045
00047
00049 inline
00050 Index::Index(int f, int l)
00051 : First(f),
00052 Stride(1),
00053 Length(l-f+1),
00054 BaseFirst(0),
00055 Base(Unique::get())
00056 {
00057 PAssert(l-f+1>=0);
00058 }
00059
00060 inline
00061 Index::Index(int f, int l, int s)
00062 : First(f),
00063 Stride(s),
00064 BaseFirst(0),
00065 Base(Unique::get())
00066 {
00067 PAssert(s!=0);
00068 if ( f==l ) {
00069 Length = 1;
00070 }
00071 else if ( (l>f) ^ (s<0) ) {
00072 Length = (l-f)/s + 1;
00073 }
00074 else {
00075 Length = 0;
00076 }
00077 }
00078
00080
00082
00083 inline
00084 Index::Index(int m, int a, const Index &b)
00085 : First(b.First*m+a),
00086 Stride(b.Stride*m),
00087 Length(b.Length),
00088 BaseFirst( b.BaseFirst ),
00089 Base(b.Base)
00090 {
00091 }
00092
00093 inline
00094 Index::Index(int f, int s, const Index *b)
00095 : First(f),
00096 Stride(s),
00097 Length(b->Length),
00098 BaseFirst(b->BaseFirst),
00099 Base(b->Base)
00100 {
00101 }
00102
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00115
00116 inline int Index::first() const
00117 {
00118 return First;
00119 }
00120
00121 inline int Index::stride() const
00122 {
00123 return Stride;
00124 }
00125
00126 inline bool Index::empty() const
00127 {
00128 return Length==0;
00129 }
00130
00131 inline int Index::length() const
00132 {
00133 return Length;
00134 }
00135
00136 inline int Index::last() const
00137 {
00138 return Length==0 ? First : First + Stride*(Length-1);
00139 }
00140
00141 inline int Index::min() const
00142 {
00143 return Stride>=0 ? First : First+Stride*(Length-1);
00144 }
00145
00146 inline int Index::max() const
00147 {
00148 return Stride>=0 ? First+Stride*(Length-1) : First;
00149 }
00150
00151 inline int Index::getBase() const
00152 {
00153 return Base;
00154 }
00155
00157
00158
00159
00161
00162 inline Index operator+(const Index& i, int off)
00163 {
00164 return Index(1,off,i);
00165 }
00166
00167 inline Index operator+(int off, const Index& i)
00168 {
00169 return Index(1,off,i);
00170 }
00171
00172 inline Index operator-(const Index& i, int off)
00173 {
00174 return Index(1,-off,i);
00175 }
00176
00177 inline Index operator-(int off, const Index& i)
00178 {
00179 return Index(-1,off,i);
00180 }
00181
00182 inline Index operator-(const Index& i)
00183 {
00184 return Index(-1,0,i);
00185 }
00186
00187 inline Index operator*(const Index& i, int m)
00188 {
00189 return Index(m,0,i);
00190 }
00191
00192 inline Index operator*(int m, const Index& i)
00193 {
00194 return Index(m,0,i);
00195 }
00196
00197 inline Index operator/(const Index& i, int d)
00198 {
00199 return Index(i.First/d, i.Stride/d, &i);
00200 }
00201
00203
00204
00205
00207
00208 inline bool Index::sameBase(const Index& i) const
00209 {
00210 return Base == i.Base;
00211 }
00212
00214
00215 inline Index Index::plugBase(const Index &a) const
00216 {
00217 Index ret;
00218 ret.BaseFirst = a.BaseFirst;
00219 ret.Length = a.Length;
00220 ret.Stride = Stride;
00221 ret.First = First + Stride*(a.BaseFirst-BaseFirst);
00222 ret.Base = Base;
00223 return ret;
00224 }
00225
00227
00228 inline Index Index::reverse() const
00229 {
00230 Index j;
00231 j.First = last();
00232 j.Length = Length;
00233 j.Stride = -Stride;
00234 j.Base = Base;
00235 j.BaseFirst = BaseFirst;
00236 return j;
00237 }
00238
00240
00241
00242 inline bool Index::touches(const Index&a) const
00243 {
00244 return (min()<=a.max())&&(max()>=a.min());
00245 }
00246
00247
00248 inline bool Index::contains(const Index&a) const
00249 {
00250 return (min()<=a.min())&&(max()>=a.max());
00251 }
00252
00253 inline bool Index::containsAllPoints(const Index &b) const
00254 {
00255
00256 int a0 = min();
00257 int a1 = max();
00258 int s = stride();
00259 int b0 = b.min();
00260 int b1 = b.max();
00261 int t = b.stride();
00262 if (s < 0)
00263 s = -s;
00264 if (t < 0)
00265 t = -t;
00266
00267
00268
00269
00270 bool quicktest = (a0 <= b0 && a1 >= b1);
00271 if (!quicktest || s == 1)
00272 return quicktest;
00273
00274
00275
00276
00277
00278
00279 return (t % s == 0) && ((b0-a0) % s == 0) && ((a1-b1) % s == 0);
00280 }
00281
00282
00283
00284
00285 inline bool Index::split(Index& l, Index& r) const
00286 {
00287 PAssert(Stride==1);
00288 PAssert(Length > 1);
00289
00290
00291
00292
00293 int first = First;
00294 int length = Length;
00295 int mid = first + length/2 - 1;
00296 l = Index(first, mid);
00297 r = Index(mid+1,first+length-1);
00298 return true;
00299
00300 }
00301
00302
00303 inline bool Index::split(Index& l, Index& r, double a) const
00304 {
00305 PAssert(Stride==1);
00306 PAssert(Length > 1);
00307 PAssert((a<1.0)&&(a>0.0));
00308
00309
00310
00311
00312 int first = First;
00313 int length = Length;
00314 int mid = first + static_cast<int>(length*a+0.5) - 1;
00315 l = Index(first, mid);
00316 r = Index(mid+1,first+length-1);
00317 return true;
00318
00319 }
00320
00322
00323 #define INDEX_PETE_DOUBLE_OPERATOR(OP,APP) \
00324 \
00325 inline \
00326 PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<double> > \
00327 OP ( const Index& idx, double x ) \
00328 { \
00329 typedef \
00330 PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<double> > \
00331 Return_t; \
00332 return Return_t( idx.MakeExpression(), PETE_Scalar<double>(x) ); \
00333 } \
00334 \
00335 inline \
00336 PETE_TBTree< APP , PETE_Scalar<double> , Index::PETE_Expr_t > \
00337 OP ( double x , const Index& idx ) \
00338 { \
00339 typedef \
00340 PETE_TBTree< APP , PETE_Scalar<double> , Index::PETE_Expr_t > \
00341 Return_t; \
00342 return Return_t( PETE_Scalar<double>(x) , idx.MakeExpression()); \
00343 }
00344
00345 INDEX_PETE_DOUBLE_OPERATOR(operator+,OpAdd)
00346 INDEX_PETE_DOUBLE_OPERATOR(operator-,OpSubtract)
00347 INDEX_PETE_DOUBLE_OPERATOR(operator*,OpMultipply)
00348 INDEX_PETE_DOUBLE_OPERATOR(operator/,OpDivide)
00349 INDEX_PETE_DOUBLE_OPERATOR(operator%,OpMod)
00350
00351 INDEX_PETE_DOUBLE_OPERATOR(lt,OpLT)
00352 INDEX_PETE_DOUBLE_OPERATOR(le,OpLE)
00353 INDEX_PETE_DOUBLE_OPERATOR(gt,OpGT)
00354 INDEX_PETE_DOUBLE_OPERATOR(ge,OpGE)
00355 INDEX_PETE_DOUBLE_OPERATOR(eq,OpEQ)
00356 INDEX_PETE_DOUBLE_OPERATOR(ne,OpNE)
00357
00358 INDEX_PETE_DOUBLE_OPERATOR(Max,FnMax)
00359 INDEX_PETE_DOUBLE_OPERATOR(Min,FnMin)
00360
00361 #undef INDEX_PETE_DOUBLE_OPERATOR
00362
00364
00365 #define INDEX_PETE_FLOAT_OPERATOR(OP,APP) \
00366 \
00367 inline \
00368 PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<float> > \
00369 OP ( const Index& idx, float x ) \
00370 { \
00371 typedef \
00372 PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<float> > \
00373 Return_t; \
00374 return Return_t( idx.MakeExpression(), PETE_Scalar<float>(x) ); \
00375 } \
00376 \
00377 inline \
00378 PETE_TBTree< APP , PETE_Scalar<float> , Index::PETE_Expr_t > \
00379 OP ( float x , const Index& idx ) \
00380 { \
00381 typedef \
00382 PETE_TBTree< APP , PETE_Scalar<float> , Index::PETE_Expr_t > \
00383 Return_t; \
00384 return Return_t( PETE_Scalar<float>(x) , idx.MakeExpression()); \
00385 }
00386
00387 INDEX_PETE_FLOAT_OPERATOR(operator+,OpAdd)
00388 INDEX_PETE_FLOAT_OPERATOR(operator-,OpSubtract)
00389 INDEX_PETE_FLOAT_OPERATOR(operator*,OpMultipply)
00390 INDEX_PETE_FLOAT_OPERATOR(operator/,OpDivide)
00391 INDEX_PETE_FLOAT_OPERATOR(operator%,OpMod)
00392
00393 INDEX_PETE_FLOAT_OPERATOR(lt,OpLT)
00394 INDEX_PETE_FLOAT_OPERATOR(le,OpLE)
00395 INDEX_PETE_FLOAT_OPERATOR(gt,OpGT)
00396 INDEX_PETE_FLOAT_OPERATOR(ge,OpGE)
00397 INDEX_PETE_FLOAT_OPERATOR(eq,OpEQ)
00398 INDEX_PETE_FLOAT_OPERATOR(ne,OpNE)
00399
00400 INDEX_PETE_FLOAT_OPERATOR(Max,FnMax)
00401 INDEX_PETE_FLOAT_OPERATOR(Min,FnMin)
00402
00403 #undef INDEX_PETE_FLOAT_OPERATOR
00404
00406
00407 #define INDEX_PETE_INT_OPERATOR(OP,APP) \
00408 \
00409 inline \
00410 PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<int> > \
00411 OP ( const Index& idx, int x ) \
00412 { \
00413 typedef \
00414 PETE_TBTree< APP , Index::PETE_Expr_t , PETE_Scalar<int> > \
00415 Return_t; \
00416 return Return_t( idx.MakeExpression(), PETE_Scalar<int>(x) ); \
00417 } \
00418 \
00419 inline \
00420 PETE_TBTree< APP , PETE_Scalar<int> , Index::PETE_Expr_t > \
00421 OP ( int x , const Index& idx ) \
00422 { \
00423 typedef \
00424 PETE_TBTree< APP , PETE_Scalar<int> , Index::PETE_Expr_t > \
00425 Return_t; \
00426 return Return_t( PETE_Scalar<int>(x) , idx.MakeExpression()); \
00427 }
00428
00429 INDEX_PETE_INT_OPERATOR(operator%,OpMod)
00430
00431 INDEX_PETE_INT_OPERATOR(lt,OpLT)
00432 INDEX_PETE_INT_OPERATOR(le,OpLE)
00433 INDEX_PETE_INT_OPERATOR(gt,OpGT)
00434 INDEX_PETE_INT_OPERATOR(ge,OpGE)
00435 INDEX_PETE_INT_OPERATOR(eq,OpEQ)
00436 INDEX_PETE_INT_OPERATOR(ne,OpNE)
00437
00438 INDEX_PETE_INT_OPERATOR(Max,FnMax)
00439 INDEX_PETE_INT_OPERATOR(Min,FnMin)
00440
00441 #undef INDEX_PETE_INT_OPERATOR
00442
00444
00445 #endif // INDEX_INLINES_H
00446
00447
00448
00449
00450
00451