vtf-logo

ArrayIndexing.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00008 #if !defined(__ArrayIndexing_h__)
00009 #define __ArrayIndexing_h__
00010 
00011 // If we are debugging the whole ads package.
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   // Private types.
00033   //
00034 
00035 private:
00036 
00037   typedef ArrayTypes<T> types;
00038   typedef ArrayIndexingBase<N> base_type;
00039 
00040   //
00041   // Public types.
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   // Member data.
00092   //
00093 
00094   // The root for indexing, i.e., the location of (*this)(_ranges.lbounds()).
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   // Private member functions.
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 // CONTINUE Move to a separate file.
00481 //--------------------------------------------------------------------------
00482 // 1-D specialization
00483 //--------------------------------------------------------------------------
00484 
00486 
00491 template<typename T>
00492 class ArrayIndexing<1,T> :
00493   public ArrayIndexingBase<1>
00494 {
00495   //
00496   // Private types.
00497   //
00498 
00499 private:
00500 
00501   typedef ArrayTypes<T> types;
00502   typedef ArrayIndexingBase<1> base_type;
00503 
00504   //
00505   // Public types.
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   // Member data.
00554   //
00555 
00556 private:
00557 
00558   // The root for indexing, i.e., the location of (*this)(_range.lbound()).
00559   // Note that if _range.lbound() != 0 then _root does not point to the 
00560   // beginning of the data.
00561   pointer _root;
00562 
00563   // CONTINUE
00564   // Not implemented.
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   // CONTINUE: Maybe I should get rid of this.  
00586 #if 0
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   // CONTINUE
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

Generated on Fri Aug 24 12:55:22 2007 for Algorithms and Data Structures Package by  doxygen 1.4.7