00001
00002
00008 #if !defined(__ArrayIndexing_h__)
00009 #define __ArrayIndexing_h__
00010
00011
00012 #if defined(DEBUG_ads) && !defined(DEBUG_ArrayIndexing)
00013 #define DEBUG_ArrayIndexing
00014 #endif
00015
00016 #include "ArrayIndexIterator.h"
00017
00018 #include <numeric>
00019 #include <iterator>
00020
00021 BEGIN_NAMESPACE_ADS
00022
00024
00028 template<int N, typename T = double>
00029 class ArrayIndexing :
00030 public ArrayIndexingBase<N> {
00031
00032
00033
00034
00035 private:
00036
00037 typedef ArrayTypes<T> types;
00038 typedef ArrayIndexingBase<N> base_type;
00039
00040
00041
00042
00043
00044 public:
00045
00047 typedef typename types::value_type value_type;
00049
00052 typedef typename types::parameter_type parameter_type;
00054
00057 typedef typename types::unqualified_value_type unqualified_value_type;
00058
00060 typedef typename types::pointer pointer;
00062 typedef typename types::const_pointer const_pointer;
00063
00065 typedef typename types::reference reference;
00067 typedef typename types::const_reference const_reference;
00068
00070
00076 typedef typename types::size_type size_type;
00078 typedef typename types::difference_type difference_type;
00079
00081 typedef FixedArray<N,int> index_type;
00083 typedef IndexRange<N,int> range_type;
00084
00086 typedef ArrayIndexIterator<N> index_iterator;
00087
00088 private:
00089
00090
00091
00092
00093
00094
00095 pointer _root;
00096
00097 protected:
00098
00099
00101
00102
00104 ArrayIndexing();
00105
00107 ArrayIndexing(const ArrayIndexing& x);
00108
00110 ArrayIndexing&
00111 operator=(const ArrayIndexing& x);
00112
00114 template<typename Type>
00115 ArrayIndexing(const index_type& extents, Type* data);
00116
00118 template<typename Type>
00119 void
00120 rebuild(const index_type& extents, Type* data);
00121
00123 template<typename Type>
00124 ArrayIndexing(const range_type& ranges, Type* data);
00125
00127 template<typename Type>
00128 void
00129 rebuild(const range_type& ranges, Type* data);
00130
00132 void
00133 swap(ArrayIndexing& x) {
00134 base_type::swap(x);
00135 std::swap(_root, x._root);
00136 }
00137
00139 ~ArrayIndexing()
00140 {}
00141
00142
00143
00144 public:
00145
00146
00148
00149
00151 static
00152 int
00153 rank() {
00154 return base_type::rank();
00155 }
00156
00157
00158
00160
00161
00163 const index_type&
00164 extents() const {
00165 return base_type::extents();
00166 }
00167
00169 size_type
00170 extent(const int i) const {
00171 return base_type::extent(i);
00172 }
00173
00175 const range_type&
00176 ranges() const {
00177 return base_type::ranges();
00178 }
00179
00181 const index_type&
00182 lbounds() const {
00183 return base_type::lbounds();
00184 }
00185
00187 const index_type&
00188 ubounds() const {
00189 return base_type::ubounds();
00190 }
00191
00193 int
00194 lbound(const int i) const {
00195 return base_type::lbound(i);
00196 }
00197
00199 int
00200 ubound(const int i) const {
00201 return base_type::ubound(i);
00202 }
00203
00205 const index_type&
00206 strides() const {
00207 return base_type::strides();
00208 }
00209
00211 index_iterator
00212 indices_begin() const {
00213 return index_iterator(*this);
00214 }
00215
00217 index_iterator
00218 indices_end() const {
00219 index_iterator x(*this);
00220 x += computeProduct(extents());
00221 return x;
00222 }
00223
00225 const_pointer
00226 root() const {
00227 return _root;
00228 }
00229
00230
00231
00233
00234
00236 parameter_type
00237 operator()(const index_type& mi) const {
00238 return _root[base_type::root_offset(mi)];
00239 }
00240
00242
00245 parameter_type
00246 operator()(const int i0, const int i1) const
00247 {
00248 return _root[base_type::root_offset(i0, i1)];
00249 }
00250
00252
00255 parameter_type
00256 operator()(const int i0, const int i1, const int i2) const
00257 {
00258 return _root[base_type::root_offset(i0, i1, i2)];
00259 }
00260
00262
00265 parameter_type
00266 operator()(const ads::FixedArray<1,int>& index,
00267 const ads::FixedArray<1,int>& offset) const
00268 {
00269 return _root[base_type::root_offset(index[0] + offset[0])];
00270 }
00271
00273
00276 parameter_type
00277 operator()(const ads::FixedArray<2,int>& index,
00278 const ads::FixedArray<2,int>& offset) const
00279 {
00280 return _root[base_type::root_offset(index[0] + offset[0],
00281 index[1] + offset[1])];
00282 }
00283
00285
00288 parameter_type
00289 operator()(const ads::FixedArray<3,int>& index,
00290 const ads::FixedArray<3,int>& offset) const
00291 {
00292 return _root[base_type::root_offset(index[0] + offset[0],
00293 index[1] + offset[1],
00294 index[2] + offset[2])];
00295 }
00296
00297
00298
00300
00301
00303 int
00304 index(const index_type& mi) const
00305 {
00306 return base_type::index(mi);
00307 }
00308
00310
00313 int
00314 index(const int i0, const int i1) const
00315 {
00316 return base_type::index(i0, i1);
00317 }
00318
00320
00323 int
00324 index(const int i0, const int i1, const int i2) const
00325 {
00326 return base_type::index(i0, i1, i2);
00327 }
00328
00330
00333 void
00334 index_to_indices(const int index, int& i, int& j) const
00335 {
00336 return base_type::index_to_indices(index, i, j);
00337 }
00338
00340
00343 void
00344 index_to_indices(int index, int& i, int& j, int& k) const
00345 {
00346 return base_type::index_to_indices(index, i, j, k);
00347 }
00348
00350
00353 void
00354 index_to_indices(const int index, ads::FixedArray<2,int>& multi_index)
00355 const
00356 {
00357 return base_type::index_to_indices(index, multi_index);
00358 }
00359
00361
00364 void
00365 index_to_indices(const int index, ads::FixedArray<3,int>& multi_index)
00366 const
00367 {
00368 return base_type::index_to_indices(index, multi_index);
00369 }
00370
00371
00372
00374
00375
00377 pointer
00378 root()
00379 {
00380 return _root;
00381 }
00382
00383
00384
00386
00387
00389 reference
00390 operator()(const index_type& mi)
00391 {
00392 return _root[base_type::root_offset(mi)];
00393 }
00394
00396
00399 reference
00400 operator()(const int i0, const int i1)
00401 {
00402 return _root[base_type::root_offset(i0, i1)];
00403 }
00404
00406
00409 reference
00410 operator()(const int i0, const int i1, const int i2)
00411 {
00412 return _root[base_type::root_offset(i0, i1, i2)];
00413 }
00414
00415
00416
00418
00419
00421 void
00422 put(std::ostream& out) const
00423 {
00424 base_type::put(out);
00425 }
00426
00428 void
00429 write(std::ostream& out) const
00430 {
00431 base_type::write(out);
00432 }
00433
00435
00441 void
00442 pretty_print(std::ostream& out) const;
00443
00444
00445
00447
00448
00450 template<typename T2>
00451 bool
00452 operator==(const ArrayIndexing<N,T2>& x) const
00453 {
00454 return base_type::operator==(x);
00455 }
00456
00457
00458
00459 private:
00460
00461
00462
00463
00464
00465 void
00466 compute_root(const const_pointer data);
00467 };
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00486
00491 template<typename T>
00492 class ArrayIndexing<1,T> :
00493 public ArrayIndexingBase<1>
00494 {
00495
00496
00497
00498
00499 private:
00500
00501 typedef ArrayTypes<T> types;
00502 typedef ArrayIndexingBase<1> base_type;
00503
00504
00505
00506
00507
00508 public:
00509
00511 typedef typename types::value_type value_type;
00513
00516 typedef typename types::parameter_type parameter_type;
00518
00521 typedef typename types::unqualified_value_type unqualified_value_type;
00522
00524 typedef typename types::pointer pointer;
00526 typedef typename types::const_pointer const_pointer;
00527
00529 typedef typename types::reference reference;
00531 typedef typename types::const_reference const_reference;
00532
00534
00540 typedef typename types::size_type size_type;
00542 typedef typename types::difference_type difference_type;
00543
00545 typedef FixedArray<1,int> index_type;
00547 typedef IndexRange<1,int> range_type;
00548
00550 typedef ArrayIndexIterator<1> index_iterator;
00551
00552
00553
00554
00555
00556 private:
00557
00558
00559
00560
00561 pointer _root;
00562
00563
00564
00565 ArrayIndexing& operator=(const ArrayIndexing&);
00566
00567 protected:
00568
00569
00571
00572
00574 ArrayIndexing() :
00575 base_type(),
00576 _root(0)
00577 {}
00578
00580 ArrayIndexing(const ArrayIndexing& x) :
00581 base_type(x),
00582 _root(x._root)
00583 {}
00584
00585
00586 #if 0
00587
00588 ArrayIndexing&
00589 operator=(const ArrayIndexing& x) {
00590 if (&x != this) {
00591 base_type::operator=(x);
00592 _root = x._root;
00593 }
00594 return *this;
00595 }
00596 #endif
00597
00599 explicit
00600 ArrayIndexing(const index_type& extent, const pointer data) :
00601 base_type(extent),
00602 _root(data)
00603 {}
00604
00606 void
00607 rebuild(const index_type& extent, const pointer data) {
00608 base_type::rebuild(extent);
00609 _root = data;
00610 }
00611
00613 explicit
00614 ArrayIndexing(const size_type size, const pointer data) :
00615 base_type(size),
00616 _root(data)
00617 {}
00618
00620 void
00621 rebuild(const size_type size, const pointer data) {
00622 base_type::rebuild(size);
00623 _root = data;
00624 }
00625
00627 explicit
00628 ArrayIndexing(const range_type& range, const pointer data) :
00629 base_type(range),
00630 _root(data - range.lbound())
00631 {}
00632
00634 void
00635 rebuild(const range_type& range, const pointer data) {
00636 base_type::rebuild(range);
00637 _root = data - range.lbound();
00638 }
00639
00641 void
00642 swap(ArrayIndexing& x) {
00643 base_type::swap(x);
00644 std::swap(_root, x._root);
00645 }
00646
00648 ~ArrayIndexing()
00649 {}
00650
00651
00652
00653 public:
00654
00655
00657
00658
00660 static
00661 int
00662 rank() {
00663 return base_type::rank();
00664 }
00665
00666
00667
00669
00670
00672 index_type
00673 extents() const {
00674 return base_type::extents();
00675 }
00676
00678 size_type
00679 extent(const int i) const {
00680 return base_type::extent(i);
00681 }
00682
00684 const range_type&
00685 ranges() const {
00686 return base_type::ranges();
00687 }
00688
00690 const index_type&
00691 lbounds() const {
00692 return base_type::lbounds();
00693 }
00694
00696 const index_type&
00697 ubounds() const {
00698 return base_type::ubounds();
00699 }
00700
00702 int
00703 lbound(const int i) const {
00704 return base_type::lbound(i);
00705 }
00706
00708 int
00709 ubound(const int i) const {
00710 return base_type::ubound(i);
00711 }
00712
00714 index_type
00715 strides() const {
00716 return base_type::strides();
00717 }
00718
00720 index_iterator
00721 indices_begin() const {
00722 return index_iterator(*this);
00723 }
00724
00726 index_iterator
00727 indices_end() const {
00728 index_iterator x(*this);
00729 x += extents()[0];
00730 return x;
00731 }
00732
00734 const_pointer
00735 root() const {
00736 return _root;
00737 }
00738
00739
00740
00742
00743
00745
00746 parameter_type
00747 operator()(const index_type& mi) const {
00748 return operator()(mi[0]);
00749 }
00750
00752
00758 parameter_type
00759 operator()(const int i) const {
00760 #ifdef DEBUG_ArrayIndexing
00761 assert(range().is_in(i));
00762 #endif
00763 return _root[i];
00764 }
00765
00766
00767
00769
00770
00772 const range_type&
00773 range() const {
00774 return base_type::range();
00775 }
00776
00778 int
00779 lbound() const {
00780 return base_type::lbound();
00781 }
00782
00784 int
00785 ubound() const {
00786 return base_type::ubound();
00787 }
00788
00789
00790
00792
00793
00795 int
00796 index(const index_type& mi) const {
00797 return base_type::index(mi);
00798 }
00799
00801 int
00802 index(const int i0) const {
00803 return base_type::index(i0);
00804 }
00805
00807 void
00808 index_to_indices(int index, int& i) const {
00809 base_type::index_to_indices(index, i);
00810 }
00811
00813 void
00814 index_to_indices(int index, ads::FixedArray<1,int>& multi_index) const {
00815 base_type::index_to_indices(index, multi_index);
00816 }
00817
00818
00819
00821
00822
00824 pointer
00825 root() {
00826 return _root;
00827 }
00828
00829
00830
00832
00833
00835 reference
00836 operator()(const index_type& mi) {
00837 return operator()(mi[0]);
00838 }
00839
00841
00847 reference
00848 operator()(const int i) {
00849 #ifdef DEBUG_ArrayIndexing
00850 assert(range().is_in(i));
00851 #endif
00852 return _root[i];
00853 }
00854
00855
00856
00858
00859
00861 void
00862 put(std::ostream& out) const {
00863 base_type::put(out);
00864 }
00865
00867 void
00868 write(std::ostream& out) const {
00869 base_type::write(out);
00870 }
00871
00873
00876 void
00877 pretty_print(std::ostream& out) const;
00878
00879
00880
00882
00883
00885 template<typename T2>
00886 bool
00887 operator==(const ArrayIndexing<1,T2>& x) const {
00888 return base_type::operator==(x);
00889 }
00890
00891
00892 };
00893
00894 END_NAMESPACE_ADS
00895
00896 #define __ArrayIndexing_ipp__
00897 #include "ArrayIndexing.ipp"
00898 #undef __ArrayIndexing_ipp__
00899
00900 #endif