00001
00002
00003
00004
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 #ifdef __GNUC__
00041 #define TOON_ALIGN8 __attribute__ ((aligned(8)))
00042 #else
00043 #define TOON_ALIGN8
00044 #endif
00045
00046 namespace TooN {
00047
00048 namespace Internal
00049 {
00050
00051 template<class Precision> struct DefaultTypes
00052 {
00053 typedef Precision* PointerType;
00054 typedef const Precision* ConstPointerType;
00055 typedef Precision& ReferenceType;
00056 typedef const Precision& ConstReferenceType;
00057 };
00058
00059
00060 template<int Size, class Precision, bool heap> class StackOrHeap;
00061
00062 template<int Size, class Precision> class StackOrHeap<Size,Precision,0>
00063 {
00064 public:
00065 StackOrHeap()
00066 {
00067 debug_initialize(my_data, Size);
00068 }
00069 Precision my_data[Size];
00070 };
00071
00072 template<int Size> class StackOrHeap<Size,double,0>
00073 {
00074 public:
00075 StackOrHeap()
00076 {
00077 debug_initialize(my_data, Size);
00078 }
00079 double my_data[Size] TOON_ALIGN8 ;
00080 };
00081
00082
00083 template<int Size, class Precision> class StackOrHeap<Size, Precision, 1>
00084 {
00085 public:
00086 StackOrHeap()
00087 :my_data(new Precision[Size])
00088 {
00089 debug_initialize(my_data, Size);
00090 }
00091
00092
00093 ~StackOrHeap()
00094 {
00095 delete[] my_data;
00096 }
00097
00098 Precision *my_data;
00099
00100 StackOrHeap(const StackOrHeap& from)
00101 :my_data(new Precision[Size])
00102 {
00103 for(int i=0; i < Size; i++)
00104 my_data[i] = from.my_data[i];
00105 }
00106 };
00107
00114 template<int Size, class Precision> class StaticSizedAllocator: public StackOrHeap<Size, Precision, (sizeof(Precision)*Size>max_bytes_on_stack) >
00115 {
00116 };
00117
00118
00124 template<int Size, class Precision> struct VectorAlloc : public StaticSizedAllocator<Size, Precision>, DefaultTypes<Precision> {
00125
00127 VectorAlloc() { }
00128
00130 VectorAlloc(int ) { }
00131
00133 template<class Op>
00134 VectorAlloc(const Operator<Op>&) {}
00135
00137 int size() const {
00138 return Size;
00139 }
00140
00141 using StaticSizedAllocator<Size, Precision>::my_data;
00142
00143 Precision *get_data_ptr()
00144 {
00145 return my_data;
00146 };
00147
00148 const Precision *get_data_ptr() const
00149 {
00150 return my_data;
00151 }
00152
00153 protected:
00154
00155 Precision *data()
00156 {
00157 return my_data;
00158 };
00159
00160 const Precision *data() const
00161 {
00162 return my_data;
00163 };
00164
00165 void try_destructive_resize(int)
00166 {}
00167
00168 template<class Op> void try_destructive_resize(const Operator<Op>&)
00169 {}
00170 };
00171
00176 template<class Precision> struct VectorAlloc<Dynamic, Precision>: public DefaultTypes<Precision> {
00177 Precision * const my_data;
00178 const int my_size;
00179
00180 VectorAlloc(const VectorAlloc& v)
00181 :my_data(new Precision[v.my_size]), my_size(v.my_size)
00182 {
00183 for(int i=0; i < my_size; i++)
00184 my_data[i] = v.my_data[i];
00185 }
00186
00187 VectorAlloc(int s)
00188 :my_data(new Precision[s]), my_size(s)
00189 {
00190 debug_initialize(my_data, my_size);
00191 }
00192
00193 template <class Op>
00194 VectorAlloc(const Operator<Op>& op)
00195 : my_data(new Precision[op.size()]), my_size(op.size())
00196 {
00197 debug_initialize(my_data, my_size);
00198 }
00199
00200 int size() const {
00201 return my_size;
00202 }
00203
00204 ~VectorAlloc(){
00205 delete[] my_data;
00206 }
00207
00208 Precision *get_data_ptr()
00209 {
00210 return my_data;
00211 };
00212
00213 const Precision *get_data_ptr() const
00214 {
00215 return my_data;
00216 }
00217
00218 protected:
00219
00220 Precision *data()
00221 {
00222 return my_data;
00223 };
00224
00225 const Precision *data() const
00226 {
00227 return my_data;
00228 };
00229
00230 void try_destructive_resize(int)
00231 {}
00232
00233 template<class Op> void try_destructive_resize(const Operator<Op>&)
00234 {}
00235 };
00236
00237
00243 template<class Precision> struct VectorAlloc<Resizable, Precision>: public DefaultTypes<Precision> {
00244 protected:
00245 std::vector<Precision> numbers;
00246
00247 public:
00248
00249 VectorAlloc()
00250 {
00251 }
00252
00253 VectorAlloc(int s)
00254 :numbers(s)
00255 {
00256 debug_initialize(data(), size());
00257 }
00258
00259 template <class Op>
00260 VectorAlloc(const Operator<Op>& op)
00261 :numbers(op.size())
00262 {
00263 debug_initialize(data(), size());
00264 }
00265
00266 int size() const {
00267 return numbers.size();
00268 }
00269
00270 Precision *get_data_ptr()
00271 {
00272 return data();
00273 };
00274
00275 const Precision *get_data_ptr() const
00276 {
00277 return data();
00278 }
00279
00280 protected:
00281
00282 Precision* data() {
00283 return &numbers[0];
00284 }
00285
00286 const Precision* data()const {
00287 return &numbers[0];
00288 }
00289
00290 private:
00291
00292
00293 template<int S> struct SFINAE_dummy{};
00294
00295 protected:
00296
00297
00298
00299
00300
00301
00302
00303
00304 template<class Op>
00305 SFINAE_dummy<sizeof(&Operator<Op>::size)> try_destructive_resize(const Operator<Op>& op)
00306 {
00307 try_destructive_resize(op.size());
00308 }
00309
00310
00311 template<class Op>
00312 void try_destructive_resize(const Op&)
00313 {}
00314
00315 void try_destructive_resize(int newsize)
00316 {
00317 numbers.resize(newsize);
00318 debug_initialize(data(), newsize);
00319 }
00320
00321 public:
00322
00323 void resize(int s)
00324 {
00325 int old_size = size();
00326 numbers.resize(s);
00327 if(s > old_size)
00328 debug_initialize(data()+old_size, s-old_size);
00329 }
00330 };
00331
00336
00337 template<int S, class Precision, class PtrType=Precision*, class ConstPtrType=const Precision*, class RefType=Precision&, class ConstRefType=const Precision&> struct VectorSlice
00338 {
00339 int size() const {
00340 return S;
00341 }
00342
00343
00344
00345 const PtrType my_data;
00346 VectorSlice(PtrType p)
00347 :my_data(p){}
00348
00349 VectorSlice(PtrType p, int )
00350 :my_data(p){}
00351
00352 template<class Op>
00353 VectorSlice(const Operator<Op>& op) : my_data(op.data()) {}
00354
00355 protected:
00356 PtrType data()
00357 {
00358 return my_data;
00359 };
00360
00361 ConstPtrType data() const
00362 {
00363 return my_data;
00364 };
00365
00366 void try_destructive_resize(int)
00367 {}
00368
00369 template<class Op> void try_destructive_resize(const Operator<Op>&)
00370 {}
00371
00372 public:
00373 typedef PtrType PointerType;
00374 typedef ConstPtrType ConstPointerType;
00375 typedef RefType ReferenceType;
00376 typedef ConstRefType ConstReferenceType;
00377 };
00378
00383 template<class Precision, class PtrType, class ConstPtrType, class RefType, class ConstRefType> struct VectorSlice<Dynamic, Precision, PtrType, ConstPtrType, RefType, ConstRefType>
00384 {
00385 const PtrType my_data;
00386 const int my_size;
00387
00388 VectorSlice(PtrType d, int s)
00389 :my_data(d), my_size(s)
00390 { }
00391
00392 template<class Op>
00393 VectorSlice(const Operator<Op>& op) : my_data(op.data()), my_size(op.size()) {}
00394
00395 int size() const {
00396 return my_size;
00397 }
00398
00399 protected:
00400
00401 PtrType data()
00402 {
00403 return my_data;
00404 };
00405
00406 ConstPtrType data() const
00407 {
00408 return my_data;
00409 };
00410
00411 void try_destructive_resize(int)
00412 {}
00413
00414 template<class Op> void try_destructive_resize(const Operator<Op>&)
00415 {}
00416
00417 public:
00418 typedef PtrType PointerType;
00419 typedef ConstPtrType ConstPointerType;
00420 typedef RefType ReferenceType;
00421 typedef ConstRefType ConstReferenceType;
00422 };
00423
00425
00426
00427
00434 template<int s> struct SizeHolder
00435 {
00436
00437 SizeHolder(){}
00438 SizeHolder(int){}
00439
00441 int size() const{
00442 return s;
00443 }
00444 };
00445
00449 template<> struct SizeHolder<-1>
00450 {
00453 SizeHolder(int s)
00454 :my_size(s){}
00456
00457 const int my_size;
00458
00459 int size() const {
00460 return my_size;
00461 }
00462 };
00463
00468 template<int S> struct RowSizeHolder: private SizeHolder<S>
00469 {
00473 RowSizeHolder(int i)
00474 :SizeHolder<S>(i){}
00475
00476 RowSizeHolder()
00477 {}
00478
00482 template<typename Op>
00483 RowSizeHolder(const Operator<Op>& op) : SizeHolder<S>(op.num_rows()) {}
00484
00486 int num_rows() const {return SizeHolder<S>::size();}
00487 };
00488
00489
00494 template<int S> struct ColSizeHolder: private SizeHolder<S>
00495 {
00499 ColSizeHolder(int i)
00500 :SizeHolder<S>(i){}
00501
00502 ColSizeHolder()
00503 {}
00504
00508 template<typename Op>
00509 ColSizeHolder(const Operator<Op>& op) : SizeHolder<S>(op.num_cols()) {}
00510
00512 int num_cols() const {return SizeHolder<S>::size();}
00513 };
00514
00515
00516
00517 template<int R, int C, class Precision, bool FullyStatic=(R>=0 && C>=0)>
00518 struct MatrixAlloc: public StaticSizedAllocator<R*C, Precision>
00519 {
00520 MatrixAlloc(int,int)
00521 {}
00522
00523 MatrixAlloc()
00524 {}
00525
00526 template <class Op>
00527 MatrixAlloc(const Operator<Op>&)
00528 {}
00529
00530 int num_rows() const {
00531 return R;
00532 }
00533
00534 int num_cols() const {
00535 return C;
00536 }
00537
00538 using StaticSizedAllocator<R*C, Precision>::my_data;
00539
00540 Precision* get_data_ptr()
00541 {
00542 return my_data;
00543 }
00544
00545 const Precision* get_data_ptr() const
00546 {
00547 return my_data;
00548 }
00549 };
00550
00551
00552 template<int R, int C, class Precision> struct MatrixAlloc<R, C, Precision, false>
00553 : public RowSizeHolder<R>,
00554 ColSizeHolder<C>
00555 {
00556 Precision* const my_data;
00557
00558 using RowSizeHolder<R>::num_rows;
00559 using ColSizeHolder<C>::num_cols;
00560
00561
00562 MatrixAlloc(const MatrixAlloc& m)
00563 :RowSizeHolder<R>(m.num_rows()),
00564 ColSizeHolder<C>(m.num_cols()),
00565 my_data(new Precision[num_rows()*num_cols()]) {
00566 const int size=num_rows()*num_cols();
00567 for(int i=0; i < size; i++) {
00568 my_data[i] = m.my_data[i];
00569 }
00570 }
00571
00572 MatrixAlloc(int r, int c)
00573 :RowSizeHolder<R>(r),
00574 ColSizeHolder<C>(c),
00575 my_data(new Precision[num_rows()*num_cols()])
00576 {
00577 debug_initialize(my_data, num_rows()*num_cols());
00578 }
00579
00580 template <class Op> MatrixAlloc(const Operator<Op>& op)
00581 :RowSizeHolder<R>(op),
00582 ColSizeHolder<C>(op),
00583 my_data(new Precision[num_rows()*num_cols()])
00584 {
00585 debug_initialize(my_data, num_rows()*num_cols());
00586 }
00587
00588 ~MatrixAlloc() {
00589 delete[] my_data;
00590 }
00591
00592 Precision* get_data_ptr()
00593 {
00594 return my_data;
00595 }
00596
00597 const Precision* get_data_ptr() const
00598 {
00599 return my_data;
00600 }
00601 };
00602
00603
00604 template<int R, int C, class Precision> struct MatrixSlice
00605 : public RowSizeHolder<R>,
00606 ColSizeHolder<C>
00607 {
00608 Precision* const my_data;
00609
00610 using RowSizeHolder<R>::num_rows;
00611 using ColSizeHolder<C>::num_cols;
00612
00613
00614 MatrixSlice(Precision* p)
00615 :my_data(p){}
00616
00617 MatrixSlice(Precision* p, int r, int c)
00618 :RowSizeHolder<R>(r),
00619 ColSizeHolder<C>(c),
00620 my_data(p){}
00621
00622 template<class Op>
00623 MatrixSlice(const Operator<Op>& op)
00624 :RowSizeHolder<R>(op),
00625 ColSizeHolder<C>(op),
00626 my_data(op.data())
00627 {}
00628 };
00629
00630
00632
00633
00634
00635
00636 template<int s> struct StrideHolder
00637 {
00638
00639 StrideHolder(){}
00640 StrideHolder(int){}
00641
00642 template<class Op>
00643 StrideHolder(const Operator<Op>&) {}
00644
00645 int stride() const{
00646 return s;
00647 }
00648 };
00649
00650 template<> struct StrideHolder<-1>
00651 {
00652 StrideHolder(int s)
00653 :my_stride(s){}
00654
00655 template<class Op>
00656 StrideHolder(const Operator<Op>& op) : my_stride(op.stride()) {}
00657
00658 const int my_stride;
00659 int stride() const {
00660 return my_stride;
00661 }
00662 };
00663
00664
00665 template<int S> struct RowStrideHolder: public StrideHolder<S>
00666 {
00667 RowStrideHolder(int i)
00668 :StrideHolder<S>(i){}
00669
00670 RowStrideHolder()
00671 {}
00672
00673 template<class Op>
00674 RowStrideHolder(const Operator<Op>& op)
00675 : StrideHolder<S>(op)
00676 {}
00677
00678 };
00679
00680
00681 template<int S> struct ColStrideHolder: public StrideHolder<S>
00682 {
00683 ColStrideHolder(int i)
00684 :StrideHolder<S>(i){}
00685
00686 ColStrideHolder()
00687 {}
00688
00689 template<class Op>
00690 ColStrideHolder(const Operator<Op>& op)
00691 : StrideHolder<S>(op)
00692 {}
00693 };
00694
00695 }
00696
00697 }
00698
00699
00700 #undef TOON_ALIGN8