SLIP  1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Array4d.hpp
Go to the documentation of this file.
1 /*
2  * Copyright(c):
3  * Signal Image and Communications (SIC) Department
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * - University of Poitiers, France http://www.univ-poitiers.fr
6  * - XLIM Institute UMR CNRS 7252 http://www.xlim.fr/
7  *
8  * and
9  *
10  * D2 Fluid, Thermic and Combustion
11  * - University of Poitiers, France http://www.univ-poitiers.fr
12  * - PPRIME Institute - UPR CNRS 3346 http://www.pprime.fr
13  * - ISAE-ENSMA http://www.ensma.fr
14  *
15  * Contributor(s):
16  * The SLIP team,
17  * Benoit Tremblais <tremblais_AT_sic.univ-poitiers.fr>,
18  * Laurent David <laurent.david_AT_lea.univ-poitiers.fr>,
19  * Ludovic Chatellier <ludovic.chatellier_AT_univ-poitiers.fr>,
20  * Lionel Thomas <lionel.thomas_AT_univ-poitiers.fr>,
21  * Denis Arrivault <arrivault_AT_sic.univ-poitiers.fr>,
22  * Julien Dombre <julien.dombre_AT_univ-poitiers.fr>.
23  *
24  * Description:
25  * The Simple Library of Image Processing (SLIP) is a new image processing
26  * library. It is written in the C++ language following as much as possible
27  * the ISO/ANSI C++ standard. It is consequently compatible with any system
28  * satisfying the ANSI C++ complience. It works on different Unix , Linux ,
29  * Mircrosoft Windows and Mac OS X plateforms. SLIP is a research library that
30  * was created by the Signal, Image and Communications (SIC) departement of
31  * the XLIM, UMR 7252 CNRS Institute in collaboration with the Fluids, Thermic
32  * and Combustion departement of the P', UPR 3346 CNRS Institute of the
33  * University of Poitiers.
34  *
35  * The SLIP Library source code has been registered to the APP (French Agency
36  * for the Protection of Programs) by the University of Poitiers and CNRS,
37  * under registration number IDDN.FR.001.300034.000.S.P.2010.000.21000.
38 
39  * http://www.sic.sp2mi.univ-poitiers.fr/slip/
40  *
41  * This software is governed by the CeCILL-C license under French law and
42  * abiding by the rules of distribution of free software. You can use,
43  * modify and/ or redistribute the software under the terms of the CeCILL-C
44  * license as circulated by CEA, CNRS and INRIA at the following URL
45  * http://www.cecill.info.
46  * As a counterpart to the access to the source code and rights to copy,
47  * modify and redistribute granted by the license, users are provided only
48  * with a limited warranty and the software's author, the holder of the
49  * economic rights, and the successive licensors have only limited
50  * liability.
51  *
52  * In this respect, the user's attention is drawn to the risks associated
53  * with loading, using, modifying and/or developing or reproducing the
54  * software by the user in light of its specific status of free software,
55  * that may mean that it is complicated to manipulate, and that also
56  * therefore means that it is reserved for developers and experienced
57  * professionals having in-depth computer knowledge. Users are therefore
58  * encouraged to load and test the software's suitability as regards their
59  * requirements in conditions enabling the security of their systems and/or
60  * data to be ensured and, more generally, to use and operate it in the
61  * same conditions as regards security.
62  *
63  * The fact that you are presently reading this means that you have had
64  * knowledge of the CeCILL-C license and that you accept its terms.
65  */
66 
76 #ifndef SLIP_ARRAY4D_HPP
77 #define SLIP_ARRAY4D_HPP
78 #include <iostream>
79 #include <iterator>
80 #include <cassert>
81 #include <string>
82 #include <cstddef>
83 #include "Box4d.hpp"
84 #include "Point4d.hpp"
85 #include "DPoint4d.hpp"
86 #include "stride_iterator.hpp"
87 #include "iterator4d_box.hpp"
88 #include "iterator4d_range.hpp"
89 
90 #include <boost/serialization/access.hpp>
91 #include <boost/serialization/split_member.hpp>
92 #include <boost/serialization/string.hpp>
93 #include <boost/serialization/complex.hpp>
94 #include <boost/serialization/version.hpp>
95 
96 namespace slip
97 {
98 template<class T>
99 class stride_iterator;
100 }
101 namespace slip
102 {
103 
104 template <typename T>
105 class Array4d;
106 
107 template <typename T>
108 std::ostream& operator<<(std::ostream & out,
109  const slip::Array4d<T>& a);
110 
111 template<typename T>
112 bool operator==(const slip::Array4d<T>& x,
113  const slip::Array4d<T>& y);
114 
115 template<typename T>
116 bool operator!=(const slip::Array4d<T>& x,
117  const slip::Array4d<T>& y);
118 
119 template<typename T>
120 bool operator<(const slip::Array4d<T>& x,
121  const slip::Array4d<T>& y);
122 
123 template<typename T>
124 bool operator>(const slip::Array4d<T>& x,
125  const slip::Array4d<T>& y);
126 
127 template<typename T>
128 bool operator<=(const slip::Array4d<T>& x,
129  const slip::Array4d<T>& y);
130 
131 template<typename T>
132 bool operator>=(const slip::Array4d<T>& x,
133  const slip::Array4d<T>& y);
134 
159 template <typename T>
160 class Array4d
161 {
162 public:
163 
164  typedef T value_type;
165  typedef Array4d<T> self;
166  typedef const Array4d<T> const_self;
167 
169  typedef value_type const & const_reference;
170 
171  typedef value_type * pointer;
172  typedef value_type const * const_pointer;
173 
174  typedef ptrdiff_t difference_type;
175  typedef std::size_t size_type;
176 
177  typedef value_type * iterator;
178  typedef value_type const * const_iterator;
179 
180  typedef std::reverse_iterator<iterator> reverse_iterator;
181  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
182 
183  //slab, slice, row and col iterator
192 
201 
202  typedef std::reverse_iterator<slab_iterator> reverse_slab_iterator;
203  typedef std::reverse_iterator<const_slab_iterator> const_reverse_slab_iterator;
204  typedef std::reverse_iterator<slice_iterator> reverse_slice_iterator;
205  typedef std::reverse_iterator<const_slice_iterator> const_reverse_slice_iterator;
206  typedef std::reverse_iterator<iterator> reverse_row_iterator;
207  typedef std::reverse_iterator<const_iterator> const_reverse_row_iterator;
208  typedef std::reverse_iterator<col_iterator> reverse_col_iterator;
209  typedef std::reverse_iterator<const_col_iterator> const_reverse_col_iterator;
210  typedef std::reverse_iterator<slice_range_iterator> reverse_slab_range_iterator;
211  typedef std::reverse_iterator<const_slice_range_iterator> const_reverse_slab_range_iterator;
212  typedef std::reverse_iterator<slice_range_iterator> reverse_slice_range_iterator;
213  typedef std::reverse_iterator<const_slice_range_iterator> const_reverse_slice_range_iterator;
214  typedef std::reverse_iterator<row_range_iterator> reverse_row_range_iterator;
215  typedef std::reverse_iterator<const_row_range_iterator> const_reverse_row_range_iterator;
216  typedef std::reverse_iterator<col_range_iterator> reverse_col_range_iterator;
217  typedef std::reverse_iterator<const_col_range_iterator> const_reverse_col_range_iterator;
218 
219  //iterator 4d
224 
225  typedef std::reverse_iterator<iterator4d> reverse_iterator4d;
226  typedef std::reverse_iterator<const_iterator4d> const_reverse_iterator4d;
227  typedef std::reverse_iterator<iterator4d_range> reverse_iterator4d_range;
228  typedef std::reverse_iterator<const_iterator4d_range> const_reverse_iterator4d_range;
229 
230  //default iterator of the container
233 
234  //Range
236 
237  static const std::size_t DIM = 4;
238 
243 
247  Array4d();
248 
258  Array4d(const std::size_t d1,
259  const std::size_t d2,
260  const std::size_t d3,
261  const std::size_t d4);
262 
271  Array4d(const std::size_t d1,
272  const std::size_t d2,
273  const std::size_t d3,
274  const std::size_t d4,
275  const T& val);
284  Array4d(const std::size_t d1,
285  const std::size_t d2,
286  const std::size_t d3,
287  const std::size_t d4,
288  const T* val);
289 
302  template<typename InputIterator>
303  Array4d(const size_type d1,
304  const size_type d2,
305  const size_type d3,
306  const size_type d4,
307  InputIterator first,
308  InputIterator last):
309  d1_(d1),d2_(d2),d3_(d3),d4_(d4),size_(d1 * d2 * d3 * d4),data_(0)
310  {
311  this->allocate();
312 
313 std::fill_n(this->begin(),this->size_,T());
314  std::copy(first,last, this->begin());
315  }
316 
320  Array4d(const Array4d<T>& rhs);
321 
322 
326  ~Array4d();
327 
328 
340  void resize(std::size_t d1,
341  std::size_t d2,
342  std::size_t d3,
343  std::size_t d4,
344  const T& val = T());
349 
350  //****************************************************************************
351  // One dimensional iterators
352  //****************************************************************************
353 
354 
355 
356  //----------------------Global iterators------------------------------
357 
377  const_iterator begin() const;
378 
398  iterator begin();
399 
419  iterator end();
420 
440  const_iterator end() const;
441 
462 
483 
504 
525 
528  //****************************************************************************
529  // One dimensional stride iterators
530  //****************************************************************************
531 
536  //--------------------One dimensional slab iterators----------------------
537 
561  slab_iterator slab_begin(const size_type slice, const size_type row, const size_type col);
562 
586  const_slab_iterator slab_begin(const size_type slice, const size_type row, const size_type col) const;
587 
611  slab_iterator slab_end(const size_type slice, const size_type row, const size_type col);
612 
636  const_slab_iterator slab_end(const size_type slice, const size_type row, const size_type col) const;
637 
638 
663  reverse_slab_iterator slab_rbegin(const size_type slice, const size_type row, const size_type col);
664 
689  const_reverse_slab_iterator slab_rbegin(const size_type slice, const size_type row, const size_type col) const;
690 
715  reverse_slab_iterator slab_rend(const size_type slice, const size_type row, const size_type col);
716 
717 
742  const_reverse_slab_iterator slab_rend(const size_type slice, const size_type row, const size_type col) const;
743 
750  //--------------------One dimensional slice iterators----------------------
751 
752 
776  slice_iterator slice_begin(const size_type slab, const size_type row, const size_type col);
777 
801  const_slice_iterator slice_begin(const size_type slab, const size_type row, const size_type col) const;
802 
826  slice_iterator slice_end(const size_type slab, const size_type row, const size_type col);
827 
851  const_slice_iterator slice_end(const size_type slab, const size_type row, const size_type col) const;
852 
853 
878  reverse_slice_iterator slice_rbegin(const size_type slab, const size_type row, const size_type col);
879 
904  const_reverse_slice_iterator slice_rbegin(const size_type slab, const size_type row, const size_type col) const;
905 
930  reverse_slice_iterator slice_rend(const size_type slab, const size_type row, const size_type col);
931 
932 
957  const_reverse_slice_iterator slice_rend(const size_type slab, const size_type row, const size_type col) const;
958 
965  //-------------------row iterators----------
966 
980  row_iterator row_begin(const size_type slab, const size_type slice,
981  const size_type row);
982 
996  const_row_iterator row_begin(const size_type slab, const size_type slice,
997  const size_type row) const;
998 
999 
1013  row_iterator row_end(const size_type slab, const size_type slice,
1014  const size_type row);
1015 
1016 
1030  const_row_iterator row_end(const size_type slab, const size_type slice,
1031  const size_type row) const;
1032 
1033 
1047  reverse_row_iterator row_rbegin(const size_type slab, const size_type slice,
1048  const size_type row);
1049 
1063  const_reverse_row_iterator row_rbegin(const size_type slab, const size_type slice,
1064  const size_type row) const;
1065 
1066 
1080  reverse_row_iterator row_rend(const size_type slab, const size_type slice,
1081  const size_type row);
1082 
1083 
1097  const_reverse_row_iterator row_rend(const size_type slab, const size_type slice,
1098  const size_type row) const;
1099 
1105  //-------------------col iterators----------
1106 
1120  col_iterator col_begin(const size_type slab, const size_type slice,
1121  const size_type col);
1122 
1123 
1137  const_col_iterator col_begin(const size_type slab, const size_type slice,
1138  const size_type col) const;
1139 
1153  col_iterator col_end(const size_type slab, const size_type slice,
1154  const size_type col);
1155 
1156 
1170  const_col_iterator col_end(const size_type slab, const size_type slice,
1171  const size_type col) const;
1172 
1173 
1187  reverse_col_iterator col_rbegin(const size_type slab, const size_type slice,
1188  const size_type col);
1189 
1190 
1204  const_reverse_col_iterator col_rbegin(const size_type slab, const size_type slice,
1205  const size_type col) const;
1206 
1220  reverse_col_iterator col_rend(const size_type slab, const size_type slice,
1221  const size_type col);
1222 
1223 
1237  const_reverse_col_iterator col_rend(const size_type slab, const size_type slice,
1238  const size_type col) const;
1239 
1242  //****************************************************************************
1243  // One dimensional range iterators
1244  //****************************************************************************
1245 
1250  //------------------------slab range iterators -----------------------
1251 
1279  slab_range_iterator slab_begin(const size_type slice,const size_type row,const size_type col,
1280  const slip::Range<int>& range);
1281 
1282 
1310  slab_range_iterator slab_end(const size_type slice,const size_type row,const size_type col,
1311  const slip::Range<int>& range);
1312 
1313 
1340  const_slab_range_iterator slab_begin(const size_type slice,const size_type row,const size_type col,
1341  const slip::Range<int>& range) const;
1342 
1369  const_slab_range_iterator slab_end(const size_type slice,const size_type row,const size_type col,
1370  const slip::Range<int>& range) const;
1371 
1372 
1401  reverse_slab_range_iterator slab_rbegin(const size_type slice,const size_type row,const size_type col,
1402  const slip::Range<int>& range);
1403 
1404 
1433  reverse_slab_range_iterator slab_rend(const size_type slice,const size_type row,const size_type col,
1434  const slip::Range<int>& range);
1435 
1436 
1466  const slip::Range<int>& range) const;
1467 
1497  const slip::Range<int>& range) const;
1498 
1499 
1507  //------------------------slice range iterators -----------------------
1508 
1536  slice_range_iterator slice_begin(const size_type slab,const size_type row,const size_type col,
1537  const slip::Range<int>& range);
1538 
1539 
1567  slice_range_iterator slice_end(const size_type slab,const size_type row,const size_type col,
1568  const slip::Range<int>& range);
1569 
1570 
1597  const_slice_range_iterator slice_begin(const size_type slab,const size_type row,const size_type col,
1598  const slip::Range<int>& range) const;
1599 
1626  const_slice_range_iterator slice_end(const size_type slab,const size_type row,const size_type col,
1627  const slip::Range<int>& range) const;
1628 
1629 
1659  const slip::Range<int>& range);
1660 
1661 
1690  reverse_slice_range_iterator slice_rend(const size_type slab,const size_type row,const size_type col,
1691  const slip::Range<int>& range);
1692 
1693 
1723  const slip::Range<int>& range) const;
1724 
1754  const slip::Range<int>& range) const;
1755 
1756 
1763  //------------------------row range iterators -----------------------
1764 
1792  row_range_iterator row_begin(const size_type slab,const size_type slice,const size_type row,
1793  const slip::Range<int>& range);
1794 
1822  row_range_iterator row_end(const size_type slab,const size_type slice,const size_type row,
1823  const slip::Range<int>& range);
1824 
1825 
1853  const_row_range_iterator row_begin(const size_type slab,const size_type slice,const size_type row,
1854  const slip::Range<int>& range) const;
1855 
1856 
1883  const_row_range_iterator row_end(const size_type slab,const size_type slice,const size_type row,
1884  const slip::Range<int>& range) const;
1885 
1912  reverse_row_range_iterator row_rbegin(const size_type slab,const size_type slice,const size_type row,
1913  const slip::Range<int>& range);
1914 
1915 
1943  reverse_row_range_iterator row_rend(const size_type slab,const size_type slice,const size_type row,
1944  const slip::Range<int>& range);
1945 
1946 
1947 
1973  const_reverse_row_range_iterator row_rbegin(const size_type slab,const size_type slice,const size_type row,
1974  const slip::Range<int>& range) const;
1975 
1976 
2004  const_reverse_row_range_iterator row_rend(const size_type slab,const size_type slice,const size_type row,
2005  const slip::Range<int>& range) const;
2006 
2012  //------------------------col range iterators -----------------------
2013 
2041  col_range_iterator col_begin(const size_type slab,const size_type slice,const size_type col,
2042  const slip::Range<int>& range);
2043 
2072  col_range_iterator col_end(const size_type slab,const size_type slice,const size_type col,
2073  const slip::Range<int>& range);
2074 
2075 
2103  const_col_range_iterator col_begin(const size_type slab,const size_type slice,const size_type col,
2104  const slip::Range<int>& range) const;
2105 
2134  const_col_range_iterator col_end(const size_type slab,const size_type slice,const size_type col,
2135  const slip::Range<int>& range) const;
2136 
2163  reverse_col_range_iterator col_rbegin(const size_type slab,const size_type slice,const size_type col,
2164  const slip::Range<int>& range);
2165 
2193  reverse_col_range_iterator col_rend(const size_type slab,const size_type slice,const size_type col,
2194  const slip::Range<int>& range);
2195 
2222  const_reverse_col_range_iterator col_rbegin(const size_type slab,const size_type slice,const size_type col,
2223  const slip::Range<int>& range) const;
2224 
2251  const_reverse_col_range_iterator col_rend(const size_type slab,const size_type slice,const size_type col,
2252  const slip::Range<int>& range) const;
2253 
2256  //****************************************************************************
2257  // Four dimensional iterators
2258  //****************************************************************************
2259 
2264 
2265  //------------------------ Global iterators------------------------------------
2266 
2284 
2285 
2303 
2304 
2322 
2323 
2341 
2359 
2377 
2395 
2396 
2414 
2421 
2422  //------------------------ Box iterators------------------------------------
2423 
2445 
2446 
2469 
2470 
2493 
2494 
2517 
2518 
2519 
2543 
2567 
2591 
2592 
2616 
2617 
2625 
2626  //------------------------ Range iterators------------------------------------
2627 
2655  iterator4d_range first_front_upper_left(const range & slab_range, const range & slice_range,
2656  const range & row_range, const range & col_range);
2657 
2685  iterator4d_range last_back_bottom_right(const range & slab_range, const range & slice_range,
2686  const range & row_range, const range & col_range);
2687 
2688 
2716  const_iterator4d_range first_front_upper_left(const range & slab_range, const range & slice_range,
2717  const range & row_range, const range & col_range) const;
2718 
2719 
2747  const_iterator4d_range last_back_bottom_right(const range & slab_range, const range & slice_range,
2748  const range & row_range, const range & col_range) const;
2749 
2778  reverse_iterator4d_range rfirst_front_upper_left(const range & slab_range, const range & slice_range,
2779  const range & row_range, const range & col_range);
2780 
2809  reverse_iterator4d_range rlast_back_bottom_right(const range & slab_range, const range & slice_range,
2810  const range & row_range, const range & col_range);
2811 
2840  const_reverse_iterator4d_range rfirst_front_upper_left(const range & slab_range, const range & slice_range,
2841  const range & row_range, const range & col_range) const;
2842 
2871  const_reverse_iterator4d_range rlast_back_bottom_right(const range & slab_range, const range & slice_range,
2872  const range & row_range, const range & col_range) const;
2873 
2874 
2877  //********************************************************************
2878 
2888  friend std::ostream& operator<< <>(std::ostream & out,
2889  const self& a);
2890 
2905  self& operator=(const Array4d<T> & rhs);
2906 
2907 
2908 
2916  self& operator=(const T& value);
2917 
2918 
2924  void fill(const T& value)
2925  {
2926  std::fill_n(this->begin(),this->size_,value);
2927  }
2928 
2935  void fill(const T* value)
2936  {
2937  std::copy(value,value + this->size_, this->begin());
2938  }
2939 
2948  template<typename InputIterator>
2949  void fill(InputIterator first,
2950  InputIterator last)
2951  {
2952  std::copy(first,last, this->begin());
2953  }
2968  friend bool operator== <>(const Array4d<T>& x,
2969  const Array4d<T>& y);
2970 
2977  friend bool operator!= <>(const Array4d<T>& x,
2978  const Array4d<T>& y);
2979 
2986  friend bool operator< <>(const Array4d<T>& x,
2987  const Array4d<T>& y);
2988 
2995  friend bool operator> <>(const Array4d<T>& x,
2996  const Array4d<T>& y);
2997 
3004  friend bool operator<= <>(const Array4d<T>& x,
3005  const Array4d<T>& y);
3006 
3013  friend bool operator>= <>(const Array4d<T>& x,
3014  const Array4d<T>& y);
3015 
3016 
3023 
3024  T*** operator[](const size_type l);
3025 
3026  const T** const* operator[](const size_type l) const;
3027 
3028 
3044  reference operator()(const size_type l, const size_type k,
3045  const size_type i,
3046  const size_type j);
3047 
3063  const_reference operator()(const size_type l, const size_type k,
3064  const size_type i,
3065  const size_type j) const;
3066 
3073  std::string name() const;
3074 
3079  size_type dim1() const;
3080 
3085  size_type slabs() const;
3086 
3091  size_type dim2() const;
3092 
3097  size_type slices() const;
3098 
3103  size_type dim3() const;
3104 
3109  size_type rows() const;
3110 
3115  size_type dim4() const;
3116 
3121  size_type cols() const;
3122 
3127  size_type columns() const;
3128 
3129 
3130 
3134  size_type size() const;
3135 
3136 
3140  size_type max_size() const;
3141 
3142 
3146  bool empty()const;
3147 
3157  void swap(Array4d& M);
3158 
3159 
3160 
3161 
3162 private:
3163  size_type d1_;
3164  size_type d2_;
3165  size_type d3_;
3166  size_type d4_;
3167  size_type size_;
3168  T**** data_;
3169 
3176  void allocate();
3177 
3184  void desallocate();
3185 
3190  void copy_attributes(const self& rhs);
3191 
3192 
3194  template<class Archive>
3195  void save(Archive & ar, const unsigned int version) const
3196  {
3197  ar & this->d1_ & this->d2_ & this->d3_ & this->d4_& this->size_ ;
3198  for (size_t i = 0; i < this->size_; ++i)
3199  {
3200  ar & (***data_)[i];
3201  }
3202  }
3203  template<class Archive>
3204  void load(Archive & ar, const unsigned int version)
3205  {
3206  ar & this->d1_ & this->d2_ & this->d3_ & this->d4_& this->size_ ;
3207  desallocate();
3208  allocate();
3209  for (size_t i = 0; i < this->size_; ++i)
3210  {
3211  ar & (***data_)[i];
3212  }
3213  }
3214  BOOST_SERIALIZATION_SPLIT_MEMBER();
3215 
3216 };
3217  // end of Containers4d group
3219 
3240 }//slip::
3241 
3242 
3243 namespace slip
3244 {
3245 
3247 // Constructors
3249 template<typename T>
3250 inline
3252 d1_(0),d2_(0),d3_(0),d4_(0),size_(0),data_(0)
3253 {}
3254 
3255 
3256 template<typename T>
3257 inline
3259  const typename Array4d<T>::size_type d2,
3260  const typename Array4d<T>::size_type d3,
3261  const typename Array4d<T>::size_type d4):
3262  d1_(d1),d2_(d2),d3_(d3),d4_(d4),size_(d1 * d2 * d3 * d4),data_(0)
3263  {
3264  this->allocate();
3265  std::fill_n(this->data_[0][0][0],this->size_,T());
3266  }
3267 
3268 template<typename T>
3269 inline
3271  const typename Array4d<T>::size_type d2,
3272  const typename Array4d<T>::size_type d3,
3273  const typename Array4d<T>::size_type d4,
3274  const T& val):
3275  d1_(d1),d2_(d2),d3_(d3),d4_(d4),size_(d1 * d2 * d3 * d4),data_(0)
3276  {
3277  this->allocate();
3278  std::fill_n(this->data_[0][0][0],this->size_,val);
3279  }
3280 
3281 template<typename T>
3282 inline
3284  const typename Array4d<T>::size_type d2,
3285  const typename Array4d<T>::size_type d3,
3286  const typename Array4d<T>::size_type d4,
3287  const T* val):
3288  d1_(d1),d2_(d2),d3_(d3),d4_(d4),size_(d1 * d2 * d3 * d4),data_(0)
3289  {
3290  this->allocate();
3291  std::copy(val,val + this->size_, this->data_[0][0][0]);
3292  }
3293 
3294 template<typename T>
3295 inline
3297 d1_(rhs.d1_),d2_(rhs.d2_),d3_(rhs.d3_),d4_(rhs.d4_),size_(rhs.size_),data_(0)
3298 {
3299  this->allocate();
3300  if(this->size_ != 0)
3301  {
3302  std::copy(rhs.data_[0][0][0],rhs.data_[0][0][0] + this->size_,this->data_[0][0][0]);
3303  }
3304 }
3305 
3306 template<typename T>
3307 inline
3309 {
3310  this->desallocate();
3311 }
3312 
3314 
3315 
3317 // Assignment operators
3319 template<typename T>
3320 inline
3322 {
3323  if(this != &rhs)
3324  {
3325  if( this->d1_ != rhs.d1_ || this->d2_ != rhs.d2_ || this->d3_ != rhs.d3_ || this->d4_ != rhs.d4_)
3326  {
3327  this->desallocate();
3328  this->copy_attributes(rhs);
3329  this->allocate();
3330  }
3331  if(rhs.size_ != 0)
3332  {
3333  std::copy(rhs.data_[0][0][0],rhs.data_[0][0][0] + this->size_,this->data_[0][0][0]);
3334  }
3335  }
3336  return *this;
3337 }
3338 
3339 template<typename T>
3340 inline
3342 {
3343  this->fill(value);
3344  return *this;
3345 }
3347 
3348 
3349 template<typename T>
3350 inline
3352  const typename Array4d<T>::size_type d2,
3353  const typename Array4d<T>::size_type d3,
3354  const typename Array4d<T>::size_type d4,
3355  const T& val)
3356  {
3357  if( this->d1_ != d1 || this->d2_ != d2 || this->d3_ != d3 || this->d4_ != d4)
3358  {
3359  this->desallocate();
3360  this->d1_ = d1;
3361  this->d2_ = d2;
3362  this->d3_ = d3;
3363  this->d4_ = d4;
3364  this->size_ = d1 * d2 * d3 * d4;
3365  this->allocate();
3366  }
3367  if( this->d1_ != 0 && this->d2_ != 0 && this->d3_ != 0 && this->d4_ != 0)
3368  {
3369  std::fill_n(this->data_[0][0][0],this->size_,val);
3370  }
3371 
3372  }
3373 
3374 
3375 
3377 // Iterators
3379 
3380 //****************************************************************************
3381 // One dimensional iterators
3382 //****************************************************************************
3383 
3384 
3385 
3386 //----------------------Global iterators------------------------------
3387 
3388 template<typename T>
3389 inline
3391 {
3392  return this->data_[0][0][0];
3393 }
3394 
3395 template<typename T>
3396 inline
3398 {
3399  return this->data_[0][0][0] + this->size_;
3400 }
3401 
3402 template<typename T>
3403 inline
3405 {
3406  return this->data_[0][0][0];
3407 }
3408 
3409 template<typename T>
3410 inline
3412 {
3413  return this->data_[0][0][0] + this->size_;
3414 }
3415 
3416 template<typename T>
3417 inline
3419 {
3420  return typename Array4d<T>::reverse_iterator(this->end());
3421 }
3422 
3423 template<typename T>
3424 inline
3426 {
3427  return typename Array4d<T>::const_reverse_iterator(this->end());
3428 }
3429 
3430 template<typename T>
3431 inline
3433 {
3434  return typename Array4d<T>::reverse_iterator(this->begin());
3435 }
3436 
3437 
3438 template<typename T>
3439 inline
3441 {
3442  return typename Array4d<T>::const_reverse_iterator(this->begin());
3443 }
3444 
3445 //--------------------One dimensional slab iterators----------------------
3446 
3447 
3448 template<typename T>
3449 inline
3451  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col){
3452  assert(slice < this->d2_);
3453  assert(row < this->d3_);
3454  assert(col < this->d4_);
3455  return typename Array4d<T>::slab_iterator(this->data_[0][slice][row] + col,this->d2_*this->d3_*this->d4_);
3456 }
3457 
3458 
3459 template<typename T>
3460 inline
3461 typename Array4d<T>::const_slab_iterator Array4d<T>::slab_begin(const typename Array4d<T>::size_type slice,
3462  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col) const{
3463  assert(slice < this->d2_);
3464  assert(row < this->d3_);
3465  assert(col < this->d4_);
3466  return typename Array4d<T>::const_slab_iterator(this->data_[0][slice][row] + col,this->d2_*this->d3_*this->d4_);
3467 }
3468 
3469 template<typename T>
3470 inline
3471 typename Array4d<T>::slab_iterator Array4d<T>::slab_end(const typename Array4d<T>::size_type slice,
3472  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col){
3473  assert(slice < this->d2_);
3474  assert(row < this->d3_);
3475  assert(col < this->d4_);
3476  return (this->slab_begin(slice,row,col) + this->d1_);
3477 }
3478 
3479 
3480 template<typename T>
3481 inline
3482 typename Array4d<T>::const_slab_iterator Array4d<T>::slab_end(const typename Array4d<T>::size_type slice,
3483  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col) const{
3484  assert(slice < this->d2_);
3485  assert(row < this->d3_);
3486  assert(col < this->d4_);
3487  slip::Array4d<T> const * tp(this);
3488  return (tp->slab_begin(slice,row,col) + this->d1_);
3489 }
3490 
3491 
3492 template<typename T>
3493 inline
3494 typename Array4d<T>::reverse_slab_iterator Array4d<T>::slab_rbegin(const typename Array4d<T>::size_type slice,
3495  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col){
3496  assert(slice < this->d2_);
3497  assert(row < this->d3_);
3498  assert(col < this->d4_);
3499  return typename Array4d<T>::reverse_slab_iterator(this->slab_end(slice,row,col));
3500 }
3501 
3502 template<typename T>
3503 inline
3504 typename Array4d<T>::const_reverse_slab_iterator Array4d<T>::slab_rbegin(const typename Array4d<T>::size_type slice,
3505  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col) const{
3506  assert(slice < this->d2_);
3507  assert(row < this->d3_);
3508  assert(col < this->d4_);
3509  return typename Array4d<T>::const_reverse_slab_iterator(this->slab_end(slice,row,col));
3510 }
3511 
3512 
3513 template<typename T>
3514 inline
3515 typename Array4d<T>::reverse_slab_iterator Array4d<T>::slab_rend(const typename Array4d<T>::size_type slice,
3516  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col){
3517  assert(slice < this->d2_);
3518  assert(row < this->d3_);
3519  assert(col < this->d4_);
3520  return typename Array4d<T>::reverse_slab_iterator(this->slab_begin(slice,row,col));
3521 }
3522 
3523 template<typename T>
3524 inline
3525 typename Array4d<T>::const_reverse_slab_iterator Array4d<T>::slab_rend(const typename Array4d<T>::size_type slice,
3526  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col) const{
3527  assert(slice < this->d2_);
3528  assert(row < this->d3_);
3529  assert(col < this->d4_);
3530  return typename Array4d<T>::const_reverse_slab_iterator(this->slab_begin(slice,row,col));
3531 }
3532 
3533 
3534 //-------------------- One dimensional slice iterators----------------------
3535 
3536 template<typename T>
3537 inline
3538 typename Array4d<T>::slice_iterator
3539 Array4d<T>::slice_begin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type row,
3540  const typename Array4d<T>::size_type col)
3541  {
3542  assert(slab < this->d1_);
3543  assert(row < this->d3_);
3544  assert(col < this->d4_);
3545  return typename Array4d<T>::slice_iterator(this->data_[slab][0][row] + col,this->d3_*this->d4_);
3546  }
3547 
3548 template<typename T>
3549 inline
3550 typename Array4d<T>::const_slice_iterator
3551 Array4d<T>::slice_begin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type row,
3552  const typename Array4d<T>::size_type col) const
3553  {
3554  assert(slab < this->d1_);
3555  assert(row < this->d3_);
3556  assert(col < this->d4_);
3557  return typename Array4d<T>::const_slice_iterator(this->data_[slab][0][row] + col,this->d3_*this->d4_);
3558  }
3559 
3560 template<typename T>
3561 inline
3562 typename Array4d<T>::slice_iterator
3563 Array4d<T>::slice_end(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type row,
3564  const typename Array4d<T>::size_type col)
3565  {
3566  assert(slab < this->d1_);
3567  assert(row < this->d3_);
3568  assert(col < this->d4_);
3569  return ++(typename Array4d<T>::slice_iterator(this->data_[slab][this->d2_-1][row] + col,this->d3_*this->d4_));
3570  }
3571 
3572 template<typename T>
3573 inline
3574 typename Array4d<T>::const_slice_iterator
3575 Array4d<T>::slice_end(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type row,
3576  const typename Array4d<T>::size_type col) const
3577  {
3578  assert(slab < this->d1_);
3579  assert(row < this->d3_);
3580  assert(col < this->d4_);
3581  return ++(typename Array4d<T>::const_slice_iterator(this->data_[slab][this->d2_-1][row] + col,this->d3_*this->d4_));
3582  }
3583 
3584 template<typename T>
3585 inline
3586 typename Array4d<T>::reverse_slice_iterator
3587 Array4d<T>::slice_rbegin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type row,
3588  const typename Array4d<T>::size_type col)
3589  {
3590  assert(slab < this->d1_);
3591  assert(row < this->d3_);
3592  assert(col < this->d4_);
3593  return typename Array4d<T>::reverse_slice_iterator(this->slice_end(slab,row,col));
3594  }
3595 
3596 template<typename T>
3597 inline
3598 typename Array4d<T>::const_reverse_slice_iterator
3599 Array4d<T>::slice_rbegin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type row,
3600  const typename Array4d<T>::size_type col) const
3601  {
3602  assert(slab < this->d1_);
3603  assert(row < this->d3_);
3604  assert(col < this->d4_);
3605  return typename Array4d<T>::const_reverse_slice_iterator(this->slice_end(slab,row,col));
3606  }
3607 
3608 template<typename T>
3609 inline
3610 typename Array4d<T>::reverse_slice_iterator
3611 Array4d<T>::slice_rend(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type row,
3612  const typename Array4d<T>::size_type col)
3613  {
3614  assert(slab < this->d1_);
3615  assert(row < this->d3_);
3616  assert(col < this->d4_);
3617  return typename Array4d<T>::reverse_slice_iterator(this->slice_begin(slab,row,col));
3618  }
3619 
3620 template<typename T>
3621 inline
3622 typename Array4d<T>::const_reverse_slice_iterator
3623 Array4d<T>::slice_rend(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type row,
3624  const typename Array4d<T>::size_type col) const
3625  {
3626  assert(slab < this->d1_);
3627  assert(row < this->d3_);
3628  assert(col < this->d4_);
3629  return typename Array4d<T>::const_reverse_slice_iterator(this->slice_begin(slab,row,col));
3630  }
3631 
3632 //--------------------One dimensional row iterators----------------------
3633 
3634 template<typename T>
3635 inline
3636 typename Array4d<T>::row_iterator
3637 Array4d<T>::row_begin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3638  const typename Array4d<T>::size_type row)
3639  {
3640  assert(slab < this->d1_);
3641  assert(slice < this->d2_);
3642  assert(row < this->d3_);
3643  return this->data_[slab][slice][row];
3644  }
3645 
3646 template<typename T>
3647 inline
3648 typename Array4d<T>::const_row_iterator
3649 Array4d<T>::row_begin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3650  const typename Array4d<T>::size_type row) const
3651  {
3652  assert(slab < this->d1_);
3653  assert(slice < this->d2_);
3654  assert(row < this->d3_);
3655  return this->data_[slab][slice][row];
3656  }
3657 
3658 template<typename T>
3659 inline
3660 typename Array4d<T>::row_iterator
3661 Array4d<T>::row_end(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3662  const typename Array4d<T>::size_type row)
3663  {
3664  assert(slab < this->d1_);
3665  assert(slice < this->d2_);
3666  assert(row < this->d3_);
3667  return this->data_[slab][slice][row] + this->d4_;
3668  }
3669 
3670 template<typename T>
3671 inline
3672 typename Array4d<T>::const_row_iterator
3673 Array4d<T>::row_end(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3674  const typename Array4d<T>::size_type row) const
3675  {
3676  assert(slab < this->d1_);
3677  assert(slice < this->d2_);
3678  assert(row < this->d3_);
3679  return this->data_[slab][slice][row] + this->d4_;
3680  }
3681 
3682 
3683 template<typename T>
3684 inline
3685 typename Array4d<T>::reverse_row_iterator
3686 Array4d<T>::row_rbegin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3687  const typename Array4d<T>::size_type row)
3688  {
3689  assert(slab < this->d1_);
3690  assert(slice < this->d2_);
3691  assert(row < this->d3_);
3692  return typename Array4d<T>::reverse_row_iterator(this->row_end(slab,slice,row));
3693  }
3694 
3695 template<typename T>
3696 inline
3697 typename Array4d<T>::const_reverse_row_iterator
3698 Array4d<T>::row_rbegin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3699  const typename Array4d<T>::size_type row) const
3700  {
3701  assert(slab < this->d1_);
3702  assert(slice < this->d2_);
3703  assert(row < this->d3_);
3704  return typename Array4d<T>::const_reverse_row_iterator(this->row_end(slab,slice,row));
3705  }
3706 
3707 
3708 template<typename T>
3709 inline
3710 typename Array4d<T>::reverse_row_iterator
3711 Array4d<T>::row_rend(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3712  const typename Array4d<T>::size_type row)
3713  {
3714  assert(slab < this->d1_);
3715  assert(slice < this->d2_);
3716  assert(row < this->d3_);
3717  return typename Array4d<T>::reverse_row_iterator(this->row_begin(slab,slice,row));
3718  }
3719 
3720 template<typename T>
3721 inline
3722 typename Array4d<T>::const_reverse_row_iterator
3723 Array4d<T>::row_rend(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3724  const typename Array4d<T>::size_type row) const
3725  {
3726  assert(slab < this->d1_);
3727  assert(slice < this->d2_);
3728  assert(row < this->d3_);
3729  return typename Array4d<T>::const_reverse_row_iterator(this->row_begin(slab,slice,row));
3730  }
3731 
3732 //--------------------One dimensional col iterators----------------------
3733 
3734 template<typename T>
3735 inline
3736 typename Array4d<T>::col_iterator
3737 Array4d<T>::col_begin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3738  const typename Array4d<T>::size_type col)
3739  {
3740  assert(slab < this->d1_);
3741  assert(slice < this->d2_);
3742  assert(col < this->d4_);
3743  return typename Array4d<T>::col_iterator(this->data_[slab][slice][0] + col,this->d4_);
3744  }
3745 
3746 template<typename T>
3747 inline
3748 typename Array4d<T>::const_col_iterator
3749 Array4d<T>::col_begin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3750  const typename Array4d<T>::size_type col) const
3751  {
3752  assert(slab < this->d1_);
3753  assert(slice < this->d2_);
3754  assert(col < this->d4_);
3755  return typename Array4d<T>::const_col_iterator(this->data_[slab][slice][0] + col,this->d4_);
3756  }
3757 
3758 
3759 template<typename T>
3760 inline
3761 typename Array4d<T>::col_iterator
3762 Array4d<T>::col_end(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3763  const typename Array4d<T>::size_type col)
3764  {
3765  assert(slab < this->d1_);
3766  assert(slice < this->d2_);
3767  assert(col < this->d4_);
3768  return ++(typename Array4d<T>::col_iterator(this->data_[slab][slice][this->d3_- 1] + col,this->d4_));
3769  }
3770 
3771 template<typename T>
3772 inline
3773 typename Array4d<T>::const_col_iterator
3774 Array4d<T>::col_end(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3775  const typename Array4d<T>::size_type col) const
3776  {
3777  assert(slab < this->d1_);
3778  assert(slice < this->d2_);
3779  assert(col < this->d4_);
3780  return ++(typename Array4d<T>::const_col_iterator(this->data_[slab][slice][this->d3_- 1] + col,this->d4_));
3781 
3782  }
3783 
3784 template<typename T>
3785 inline
3786 typename Array4d<T>::reverse_col_iterator
3787 Array4d<T>::col_rbegin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3788  const typename Array4d<T>::size_type col)
3789  {
3790  assert(slab < this->d1_);
3791  assert(slice < this->d2_);
3792  assert(col < this->d4_);
3793  return typename Array4d<T>::reverse_col_iterator(this->col_end(slab,slice,col));
3794  }
3795 
3796 template<typename T>
3797 inline
3798 typename Array4d<T>::const_reverse_col_iterator
3799 Array4d<T>::col_rbegin(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3800  const typename Array4d<T>::size_type col) const
3801  {
3802  assert(slab < this->d1_);
3803  assert(slice < this->d2_);
3804  assert(col < this->d4_);
3805  return typename Array4d<T>::const_reverse_col_iterator(this->col_end(slab,slice,col));
3806  }
3807 
3808 
3809 template<typename T>
3810 inline
3811 typename Array4d<T>::reverse_col_iterator
3812 Array4d<T>::col_rend(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3813  const typename Array4d<T>::size_type col)
3814  {
3815  assert(slab < this->d1_);
3816  assert(slice < this->d2_);
3817  assert(col < this->d4_);
3818  return typename Array4d<T>::reverse_col_iterator(this->col_begin(slab,slice,col));
3819  }
3820 
3821 template<typename T>
3822 inline
3823 typename Array4d<T>::const_reverse_col_iterator
3824 Array4d<T>::col_rend(const typename Array4d<T>::size_type slab, const typename Array4d<T>::size_type slice,
3825  const typename Array4d<T>::size_type col) const
3826  {
3827  assert(slab < this->d1_);
3828  assert(slice < this->d2_);
3829  assert(col < this->d4_);
3830  return typename Array4d<T>::const_reverse_col_iterator(this->col_begin(slab,slice,col));
3831  }
3832 
3833 //--------------------slab range iterators----------------------
3834 
3835 template<typename T>
3836 inline
3837 typename Array4d<T>::slab_range_iterator Array4d<T>::slab_begin(const typename Array4d<T>::size_type slice,
3838  const typename Array4d<T>::size_type row,const typename Array4d<T>::size_type col,
3839  const slip::Range<int>& range){
3840  assert(slice < this->d2_);
3841  assert(row < this->d3_);
3842  assert(col < this->d4_);
3843  assert(range.is_valid());
3844  assert(range.start() >= 0);
3845  assert(range.stop() >= 0);
3846  assert(range.start() < (int)this->d1_);
3847  assert(range.stop() < (int)this->d1_);
3848  return slip::stride_iterator<typename Array4d<T>::slab_iterator>(this->slab_begin(slice,row,col) + range.start(),
3849  range.stride());
3850 }
3851 
3852 
3853 template<typename T>
3854 inline
3855 typename Array4d<T>::slab_range_iterator Array4d<T>::slab_end(const typename Array4d<T>::size_type slice,
3856  const typename Array4d<T>::size_type row,const typename Array4d<T>::size_type col,
3857  const slip::Range<int>& range){
3858  assert(slice < this->d2_);
3859  assert(row < this->d3_);
3860  assert(col < this->d4_);
3861  assert(range.start() < (int)this->d1_);
3862  assert(range.stop() < (int)this->d1_);
3863  return ++(slip::stride_iterator<typename Array4d<T>::slab_iterator>(this->slab_begin(slice,row,col,range)
3864  + range.iterations()));
3865 }
3866 
3867 
3868 template<typename T>
3869 inline
3870 typename Array4d<T>::const_slab_range_iterator Array4d<T>::slab_begin(const typename Array4d<T>::size_type slice,
3871  const typename Array4d<T>::size_type row,const typename Array4d<T>::size_type col,
3872  const slip::Range<int>& range) const{
3873  assert(slice < this->d2_);
3874  assert(row < this->d3_);
3875  assert(col < this->d4_);
3876  assert(range.is_valid());
3877  assert(range.start() >= 0);
3878  assert(range.stop() >= 0);
3879  assert(range.start() < (int)this->d1_);
3880  assert(range.stop() < (int)this->d1_);
3881  return slip::stride_iterator<typename Array4d<T>::const_slab_iterator>(this->slab_begin(slice,row,col) +
3882  range.start(),range.stride());
3883 
3884 }
3885 
3886 template<typename T>
3887 inline
3888 typename Array4d<T>::const_slab_range_iterator Array4d<T>::slab_end(const typename Array4d<T>::size_type slice,
3889  const typename Array4d<T>::size_type row,const typename Array4d<T>::size_type col,
3890  const slip::Range<int>& range) const{
3891  assert(slice < this->d2_);
3892  assert(row < this->d3_);
3893  assert(col < this->d4_);
3894  assert(range.start() < (int)this->d1_);
3895  assert(range.stop() < (int)this->d1_);
3896  return ++(slip::stride_iterator<typename Array4d<T>::const_slab_iterator>(this->slab_begin(slice,row,col,range)
3897  + range.iterations()));
3898 }
3899 
3900 template<typename T>
3901 inline
3902 typename Array4d<T>::reverse_slab_range_iterator Array4d<T>::slab_rbegin(const typename Array4d<T>::size_type slice,
3903  const typename Array4d<T>::size_type row,const typename Array4d<T>::size_type col,
3904  const slip::Range<int>& range){
3905  assert(slice < this->d2_);
3906  assert(row < this->d3_);
3907  assert(col < this->d4_);
3908  assert(range.start() < (int)this->d1_);
3909  return typename Array4d<T>::reverse_slab_range_iterator(this->slab_end(slice,row,col,range));
3910 }
3911 
3912 
3913 template<typename T>
3914 inline
3915 typename Array4d<T>::reverse_slab_range_iterator Array4d<T>::slab_rend(const Array4d<T>::size_type slice,
3916  const Array4d<T>::size_type row, const Array4d<T>::size_type col,
3917  const slip::Range<int>& range){
3918  assert(slice < this->d2_);
3919  assert(row < this->d3_);
3920  assert(col < this->d4_);
3921  assert(range.start() < (int)this->d1_);
3922  return typename Array4d<T>::reverse_slab_range_iterator(this->slab_begin(slice,row,col,range));
3923 }
3924 
3925 
3926 template<typename T>
3927 inline
3928 typename Array4d<T>::const_reverse_slab_range_iterator Array4d<T>::slab_rbegin(const typename Array4d<T>::size_type slice,
3929  const typename Array4d<T>::size_type row,const typename Array4d<T>::size_type col,
3930  const slip::Range<int>& range) const{
3931  assert(slice < this->d2_);
3932  assert(row < this->d3_);
3933  assert(col < this->d4_);
3934  assert(range.start() < (int)this->d1_);
3935  return typename Array4d<T>::const_reverse_slab_range_iterator(this->slab_end(slice,row,col,range));
3936 }
3937 
3938 template<typename T>
3939 inline
3940 typename Array4d<T>::const_reverse_slab_range_iterator Array4d<T>::slab_rend(const typename Array4d<T>::size_type slice,
3941  const typename Array4d<T>::size_type row,const typename Array4d<T>::size_type col,
3942  const slip::Range<int>& range) const{
3943  assert(slice < this->d2_);
3944  assert(row < this->d3_);
3945  assert(col < this->d4_);
3946  assert(range.start() < (int)this->d1_);
3947  return typename Array4d<T>::const_reverse_slab_range_iterator(this->slab_begin(slice,row,col,range));
3948 }
3949 
3950 
3951 //--------------------Constant slice range iterators----------------------
3952 
3953 template<typename T>
3954 inline
3955 typename Array4d<T>::slice_range_iterator
3956 Array4d<T>::slice_begin(const typename Array4d<T>::size_type slab,
3957  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col,
3958  const slip::Range<int>& range)
3959  {
3960  assert(slab < this->d1_);
3961  assert(row < this->d3_);
3962  assert(col < this->d4_);
3963  assert(range.is_valid());
3964  assert(range.start() >= 0);
3965  assert(range.stop() >= 0);
3966  assert(range.start() < (int)this->d2_);
3967  assert(range.stop() < (int)this->d2_);
3968  return slip::stride_iterator<typename Array4d<T>::slice_iterator>(this->slice_begin(slab,row,col) + range.start(),range.stride());
3969  }
3970 
3971 template<typename T>
3972 inline
3973 typename Array4d<T>::const_slice_range_iterator
3974 Array4d<T>::slice_begin(const typename Array4d<T>::size_type slab,
3975  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col,
3976  const slip::Range<int>& range) const
3977  {
3978  assert(slab < this->d1_);
3979  assert(row < this->d3_);
3980  assert(col < this->d4_);
3981  assert(range.is_valid());
3982  assert(range.start() >= 0);
3983  assert(range.stop() >= 0);
3984  assert(range.start() < (int)this->d2_);
3985  assert(range.stop() < (int)this->d2_);
3986  return slip::stride_iterator<typename Array4d<T>::const_slice_iterator>(this->slice_begin(slab,row,col) + range.start(),range.stride());
3987  }
3988 
3989 template<typename T>
3990 inline
3991 typename Array4d<T>::slice_range_iterator
3992 Array4d<T>::slice_end(const typename Array4d<T>::size_type slab,
3993  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col,
3994  const slip::Range<int>& range)
3995  {
3996  assert(slab < this->d1_);
3997  assert(row < this->d3_);
3998  assert(col < this->d4_);
3999  assert(range.start() < (int)this->d2_);
4000  assert(range.stop() < (int)this->d2_);
4001  return ++(slip::stride_iterator<typename Array4d<T>::slice_iterator>(this->slice_begin(slab,row,col,range) + range.iterations()));
4002  }
4003 
4004 template<typename T>
4005 inline
4006 typename Array4d<T>::const_slice_range_iterator
4007 Array4d<T>::slice_end(const typename Array4d<T>::size_type slab,
4008  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col,
4009  const slip::Range<int>& range) const
4010  {
4011  assert(slab < this->d1_);
4012  assert(row < this->d3_);
4013  assert(col < this->d4_);
4014  assert(range.start() < (int)this->d2_);
4015  assert(range.stop() < (int)this->d2_);
4016  return ++(slip::stride_iterator<typename Array4d<T>::const_slice_iterator>(this->slice_begin(slab,row,col,range) + range.iterations()));
4017  }
4018 
4019 template<typename T>
4020 inline
4021 typename Array4d<T>::reverse_slice_range_iterator
4022 Array4d<T>::slice_rbegin(const typename Array4d<T>::size_type slab,
4023  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col,
4024  const slip::Range<int>& range)
4025  {
4026  assert(slab < this->d1_);
4027  assert(row < this->d3_);
4028  assert(col < this->d4_);
4029  assert(range.start() < (int)this->d2_);
4030  return typename Array4d<T>::reverse_slice_range_iterator(this->slice_end(slab,row,col,range));
4031  }
4032 
4033 template<typename T>
4034 inline
4035 typename Array4d<T>::const_reverse_slice_range_iterator
4036 Array4d<T>::slice_rbegin(const typename Array4d<T>::size_type slab,
4037  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col,
4038  const slip::Range<int>& range) const
4039  {
4040  assert(slab < this->d1_);
4041  assert(row < this->d3_);
4042  assert(col < this->d4_);
4043  assert(range.start() < (int)this->d2_);
4044  return typename Array4d<T>::const_reverse_slice_range_iterator(this->slice_end(slab,row,col,range));
4045  }
4046 
4047 template<typename T>
4048 inline
4049 typename Array4d<T>::reverse_slice_range_iterator
4050 Array4d<T>::slice_rend(const typename Array4d<T>::size_type slab,
4051  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col,
4052  const slip::Range<int>& range)
4053  {
4054  assert(slab < this->d1_);
4055  assert(row < this->d3_);
4056  assert(col < this->d4_);
4057  assert(range.start() < (int)this->d2_);
4058  return typename Array4d<T>::reverse_slice_range_iterator(this->slice_begin(slab,row,col,range));
4059  }
4060 
4061 template<typename T>
4062 inline
4063 typename Array4d<T>::const_reverse_slice_range_iterator
4064 Array4d<T>::slice_rend(const typename Array4d<T>::size_type slab,
4065  const typename Array4d<T>::size_type row, const typename Array4d<T>::size_type col,
4066  const slip::Range<int>& range) const
4067  {
4068  assert(slab < this->d1_);
4069  assert(row < this->d3_);
4070  assert(col < this->d4_);
4071  assert(range.start() < (int)this->d2_);
4072  return typename Array4d<T>::const_reverse_slice_range_iterator(this->slice_begin(slab,row,col,range));
4073  }
4074 
4075 //--------------------Constant row range iterators----------------------
4076 
4077 template<typename T>
4078 inline
4079 typename Array4d<T>::row_range_iterator
4080 Array4d<T>::row_begin(const typename Array4d<T>::size_type slab,
4081  const typename Array4d<T>::size_type slice, const typename Array4d<T>::size_type row,const slip::Range<int>& range)
4082  {
4083  assert(slab < this->d1_);
4084  assert(slice < this->d2_);
4085  assert(row < this->d3_);
4086  assert(range.is_valid());
4087  assert(range.start() >= 0);
4088  assert(range.stop() >= 0);
4089  assert(range.start() < (int)this->d4_);
4090  assert(range.stop() < (int)this->d4_);
4091  return slip::stride_iterator<typename Array4d<T>::row_iterator>(this->row_begin(slab,slice,row) + range.start(),range.stride());
4092  }
4093 
4094 template<typename T>
4095 inline
4096 typename Array4d<T>::const_row_range_iterator
4097 Array4d<T>::row_begin(const typename Array4d<T>::size_type slab,
4098  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type row,
4099  const slip::Range<int>& range) const
4100  {
4101  assert(slab < this->d1_);
4102  assert(slice < this->d2_);
4103  assert(row < this->d3_);
4104  assert(range.is_valid());
4105  assert(range.start() >= 0);
4106  assert(range.stop() >= 0);
4107  assert(range.start() < (int)this->d4_);
4108  assert(range.stop() < (int)this->d4_);
4109  return slip::stride_iterator<typename Array4d<T>::const_row_iterator>(this->row_begin(slab,slice,row) + range.start(),range.stride());
4110  }
4111 
4112 template<typename T>
4113 inline
4114 typename Array4d<T>::row_range_iterator
4115 Array4d<T>::row_end(const typename Array4d<T>::size_type slab,
4116  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type row,
4117  const slip::Range<int>& range)
4118  {
4119  assert(slab < this->d1_);
4120  assert(slice < this->d2_);
4121  assert(row < this->d3_);
4122  assert(range.start() < (int)this->d4_);
4123  assert(range.stop() < (int)this->d4_);
4124  return ++(slip::stride_iterator<typename Array4d<T>::row_iterator>(this->row_begin(slab,slice,row) + range.start() + range.stride() * range.iterations(),range.stride()));
4125  }
4126 
4127 template<typename T>
4128 inline
4129 typename Array4d<T>::const_row_range_iterator
4130 Array4d<T>::row_end(const typename Array4d<T>::size_type slab,
4131  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type row,
4132  const slip::Range<int>& range) const
4133  {
4134  assert(slab < this->d1_);
4135  assert(slice < this->d2_);
4136  assert(row < this->d3_);
4137  assert(range.start() < (int)this->d4_);
4138  assert(range.stop() < (int)this->d4_);
4139  return ++(slip::stride_iterator<typename Array4d<T>::const_row_iterator>(this->row_begin(slab,slice,row) + range.start() + range.stride() * range.iterations(),range.stride()));
4140  }
4141 
4142 template<typename T>
4143 inline
4144 typename Array4d<T>::reverse_row_range_iterator
4145 Array4d<T>::row_rbegin(const typename Array4d<T>::size_type slab,
4146  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type row,
4147  const slip::Range<int>& range)
4148  {
4149  assert(slab < this->d1_);
4150  assert(slice < this->d2_);
4151  assert(row < this->d3_);
4152  assert(range.start() < (int)this->d4_);
4153  return typename Array4d<T>::reverse_row_range_iterator(this->row_end(slab,slice,row,range));
4154  }
4155 
4156 template<typename T>
4157 inline
4158 typename Array4d<T>::const_reverse_row_range_iterator
4159 Array4d<T>::row_rbegin(const typename Array4d<T>::size_type slab,
4160  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type row,
4161  const slip::Range<int>& range) const
4162  {
4163  assert(slab < this->d1_);
4164  assert(slice < this->d2_);
4165  assert(row < this->d3_);
4166  assert(range.start() < (int)this->d4_);
4167  return typename Array4d<T>::const_reverse_row_range_iterator(this->row_end(slab,slice,row,range));
4168  }
4169 
4170 template<typename T>
4171 inline
4172 typename Array4d<T>::reverse_row_range_iterator
4173 Array4d<T>::row_rend(const typename Array4d<T>::size_type slab,
4174  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type row,
4175  const slip::Range<int>& range)
4176  {
4177  assert(slab < this->d1_);
4178  assert(slice < this->d2_);
4179  assert(row < this->d3_);
4180  assert(range.start() < (int)this->d4_);
4181  return typename Array4d<T>::reverse_row_range_iterator(this->row_begin(slab,slice,row,range));
4182  }
4183 
4184 template<typename T>
4185 inline
4186 typename Array4d<T>::const_reverse_row_range_iterator
4187 Array4d<T>::row_rend(const typename Array4d<T>::size_type slab,
4188  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type row,
4189  const slip::Range<int>& range) const
4190  {
4191  assert(slab < this->d1_);
4192  assert(slice < this->d2_);
4193  assert(row < this->d3_);
4194  assert(range.start() < (int)this->d4_);
4195  return typename Array4d<T>::const_reverse_row_range_iterator(this->row_begin(slab,slice,row,range));
4196  }
4197 
4198 //--------------------Constant col range iterators----------------------
4199 
4200 template<typename T>
4201 inline
4202 typename Array4d<T>::col_range_iterator
4203 Array4d<T>::col_begin(const typename Array4d<T>::size_type slab,
4204  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type col,
4205  const slip::Range<int>& range)
4206  {
4207  assert(slab < this->d1_);
4208  assert(slice < this->d2_);
4209  assert(col < this->d4_);
4210  assert(range.is_valid());
4211  assert(range.start() >= 0);
4212  assert(range.stop() >= 0);
4213  assert(range.start() < (int)this->d3_);
4214  assert(range.stop() < (int)this->d3_);
4215  return slip::stride_iterator<typename Array4d<T>::col_iterator>(this->col_begin(slab,slice,col) + range.start(),
4216  range.stride());
4217  }
4218 
4219 template<typename T>
4220 inline
4221 typename Array4d<T>::const_col_range_iterator
4222 Array4d<T>::col_begin(const typename Array4d<T>::size_type slab,
4223  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type col,
4224  const slip::Range<int>& range) const
4225  {
4226  assert(slab < this->d1_);
4227  assert(slice < this->d2_);
4228  assert(col < this->d4_);
4229  assert(range.is_valid());
4230  assert(range.start() >= 0);
4231  assert(range.stop() >= 0);
4232  assert(range.start() < (int)this->d3_);
4233  assert(range.stop() < (int)this->d3_);
4234  return slip::stride_iterator<typename Array4d<T>::const_col_iterator>(this->col_begin(slab,slice,col) + range.start(),
4235  range.stride());
4236  }
4237 
4238 template<typename T>
4239 inline
4240 typename Array4d<T>::col_range_iterator
4241 Array4d<T>::col_end(const typename Array4d<T>::size_type slab,
4242  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type col,
4243  const slip::Range<int>& range)
4244  {
4245  assert(slab < this->d1_);
4246  assert(slice < this->d2_);
4247  assert(col < this->d4_);
4248  assert(range.is_valid());
4249  assert(range.start() >= 0);
4250  assert(range.stop() >= 0);
4251  assert(range.start() < (int)this->d3_);
4252  assert(range.stop() < (int)this->d3_);
4253  return ++(slip::stride_iterator<typename Array4d<T>::col_iterator>(this->col_begin(slab,slice,col) + range.start() +
4254  range.stride() * range.iterations(),range.stride()));
4255  }
4256 
4257 template<typename T>
4258 inline
4259 typename Array4d<T>::const_col_range_iterator
4260 Array4d<T>::col_end(const typename Array4d<T>::size_type slab,
4261  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type col,
4262  const slip::Range<int>& range) const
4263  {
4264  assert(slab < this->d1_);
4265  assert(slice < this->d2_);
4266  assert(col < this->d4_);
4267  assert(range.is_valid());
4268  assert(range.start() >= 0);
4269  assert(range.stop() >= 0);
4270  assert(range.start() < (int)this->d3_);
4271  assert(range.stop() < (int)this->d3_);
4272  return ++(slip::stride_iterator<typename Array4d<T>::const_col_iterator>(this->col_begin(slab,slice,col) +
4273  range.start() + range.stride() * range.iterations(),range.stride()));
4274  }
4275 
4276 template<typename T>
4277 inline
4278 typename Array4d<T>::reverse_col_range_iterator
4279 Array4d<T>::col_rbegin(const typename Array4d<T>::size_type slab,
4280  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type col,
4281  const slip::Range<int>& range)
4282  {
4283  assert(slab < this->d1_);
4284  assert(slice < this->d2_);
4285  assert(col < this->d4_);
4286  assert(range.start() < (int)this->d3_);
4287  return typename Array4d<T>::reverse_col_range_iterator(this->col_end(slab,slice,col,range));
4288  }
4289 
4290 template<typename T>
4291 inline
4292 typename Array4d<T>::const_reverse_col_range_iterator
4293 Array4d<T>::col_rbegin(const typename Array4d<T>::size_type slab,
4294  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type col,
4295  const slip::Range<int>& range) const
4296  {
4297  assert(slab < this->d1_);
4298  assert(slice < this->d2_);
4299  assert(col < this->d4_);
4300  assert(range.start() < (int)this->d3_);
4301  return typename Array4d<T>::const_reverse_col_range_iterator(this->col_end(slab,slice,col,range));
4302  }
4303 
4304 template<typename T>
4305 inline
4306 typename Array4d<T>::reverse_col_range_iterator
4307 Array4d<T>::col_rend(const typename Array4d<T>::size_type slab,
4308  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type col,
4309  const slip::Range<int>& range)
4310  {
4311  assert(slab < this->d1_);
4312  assert(slice < this->d2_);
4313  assert(col < this->d4_);
4314  assert(range.start() < (int)this->d3_);
4315  return typename Array4d<T>::reverse_col_range_iterator(this->col_begin(slab,slice,col,range));
4316  }
4317 
4318 template<typename T>
4319 inline
4320 typename Array4d<T>::const_reverse_col_range_iterator
4321 Array4d<T>::col_rend(const typename Array4d<T>::size_type slab,
4322  const typename Array4d<T>::size_type slice,const typename Array4d<T>::size_type col,
4323  const slip::Range<int>& range) const
4324  {
4325  assert(slab < this->d1_);
4326  assert(slice < this->d2_);
4327  assert(col < this->d4_);
4328  assert(range.start() < (int)this->d3_);
4329  return typename Array4d<T>::const_reverse_col_range_iterator(this->col_begin(slab,slice,col,range));
4330  }
4331 
4332 
4333 //****************************************************************************
4334 // Four dimensional iterators
4335 //****************************************************************************
4336 
4337 //------------------------ Global iterators------------------------------------
4338 
4339 template<typename T>
4340 inline
4342 {
4343  return typename Array4d<T>::iterator4d(this,Box4d<int>(0,0,0,0,this->d1_-1,this->d2_-1,this->d3_-1,this->d4_-1));
4344 }
4345 
4346 template<typename T>
4347 inline
4349 {
4350  return typename Array4d<T>::const_iterator4d(this,Box4d<int>(0,0,0,0,this->d1_-1,this->d2_-1,this->d3_-1,this->d4_-1));
4351 }
4352 
4353 
4354 template<typename T>
4355 inline
4357 {
4358  DPoint4d<int> dp(this->d1_,this->d2_,this->d3_,this->d4_);
4359  typename Array4d<T>::iterator4d it = (*this).first_front_upper_left() + dp;
4360  return it;
4361 }
4362 
4363 template<typename T>
4364 inline
4366 {
4367  DPoint4d<int> dp(this->d1_,this->d2_,this->d3_,this->d4_);
4368  typename Array4d<T>::const_iterator4d it = (*this).first_front_upper_left() + dp;
4369  return it;
4370 }
4371 
4372 template<typename T>
4373 inline
4376 {
4377  return typename Array4d<T>::reverse_iterator4d(this->first_front_upper_left());
4378 }
4379 
4380 template<typename T>
4381 inline
4384 {
4385  return typename Array4d<T>::const_reverse_iterator4d(this->first_front_upper_left());
4386 }
4387 
4388 template<typename T>
4389 inline
4392 {
4393  DPoint4d<int> dp(1,1,1,0);
4394  return typename Array4d<T>::reverse_iterator4d(this->last_back_bottom_right() - dp);
4395 }
4396 
4397 template<typename T>
4398 inline
4401 {
4402  DPoint4d<int> dp(1,1,1,0);
4403  return typename Array4d<T>::const_reverse_iterator4d(this->last_back_bottom_right() - dp);
4404 }
4405 
4406 //------------------------ Box iterators------------------------------------
4407 
4408 template<typename T>
4409 inline
4411 {
4412  return typename Array4d<T>::iterator4d(this,box);
4413 }
4414 
4415 template<typename T>
4416 inline
4418 {
4419  return typename Array4d<T>::const_iterator4d(this,box);
4420 }
4421 
4422 
4423 template<typename T>
4424 inline
4425 typename Array4d<T>::iterator4d
4427 {
4428  DPoint4d<int> dp(box.duration(),box.depth(),box.height(),box.width());
4429  typename Array4d<T>::iterator4d it = (*this).first_front_upper_left(box) + dp;
4430  return it;
4431 }
4432 
4433 template<typename T>
4434 inline
4437 {
4438  DPoint4d<int> dp(box.duration(),box.depth(),box.height(),box.width());
4439  typename Array4d<T>::const_iterator4d it = (*this).first_front_upper_left(box) + dp;
4440  return it;
4441 }
4442 
4443 template<typename T>
4444 inline
4447 {
4448  return typename Array4d<T>::reverse_iterator4d(this->first_front_upper_left(box));
4449 }
4450 
4451 template<typename T>
4452 inline
4455 {
4456  return typename Array4d<T>::const_reverse_iterator4d(this->first_front_upper_left(box));
4457 }
4458 
4459 template<typename T>
4460 inline
4463 {
4464  DPoint4d<int> dp(1,1,1,0);
4465  return typename Array4d<T>::reverse_iterator4d(this->last_back_bottom_right(box) - dp);
4466 }
4467 
4468 template<typename T>
4469 inline
4472 {
4473  DPoint4d<int> dp(1,1,1,0);
4474  return typename Array4d<T>::const_reverse_iterator4d(this->last_back_bottom_right(box) - dp);
4475 }
4476 
4477 //------------------------ Range iterators------------------------------------
4478 
4479 template<typename T>
4480 inline
4482 Array4d<T>::first_front_upper_left(const typename Array4d<T>::range& slab_range,
4483  const typename Array4d<T>::range& slice_range,
4484  const typename Array4d<T>::range& row_range,
4485  const typename Array4d<T>::range& col_range)
4486  {
4487  return typename Array4d<T>::iterator4d_range(this,slab_range,slice_range,row_range,col_range);
4488  }
4489 
4490 template<typename T>
4491 inline
4492 typename Array4d<T>::iterator4d_range
4493 Array4d<T>::last_back_bottom_right(const typename Array4d<T>::range& slab_range,
4494  const typename Array4d<T>::range& slice_range,
4495  const typename Array4d<T>::range& row_range,
4496  const typename Array4d<T>::range& col_range)
4497  {
4498  DPoint4d<int> dp(slab_range.iterations()+1,slice_range.iterations()+1,row_range.iterations()+1,
4499  col_range.iterations()+1);
4500  return typename Array4d<T>::iterator4d_range((*this).first_front_upper_left(slab_range,slice_range,
4501  row_range,col_range) + dp);
4502  }
4503 
4504 
4505 template<typename T>
4506 inline
4507 typename Array4d<T>::const_iterator4d_range
4508 Array4d<T>::first_front_upper_left(const typename Array4d<T>::range& slab_range,
4509  const typename Array4d<T>::range& slice_range,
4510  const typename Array4d<T>::range& row_range,
4511  const typename Array4d<T>::range& col_range) const
4512  {
4513  return typename Array4d<T>::const_iterator4d_range(this,slab_range,slice_range,row_range,col_range);
4514  }
4515 
4516 
4517 template<typename T>
4518 inline
4519 typename Array4d<T>::const_iterator4d_range
4520 Array4d<T>::last_back_bottom_right(const typename Array4d<T>::range& slab_range,
4521  const typename Array4d<T>::range& slice_range,
4522  const typename Array4d<T>::range& row_range,
4523  const typename Array4d<T>::range& col_range) const
4524  {
4525  DPoint4d<int> dp(slab_range.iterations()+1,slice_range.iterations()+1,row_range.iterations()+1,
4526  col_range.iterations()+1);
4527  return typename Array4d<T>::const_iterator4d_range((*this).first_front_upper_left(slab_range,slice_range,
4528  row_range,col_range) + dp);
4529  }
4530 
4531 template<typename T>
4532 inline
4533 typename Array4d<T>::reverse_iterator4d_range
4534 Array4d<T>::rfirst_front_upper_left(const typename Array4d<T>::range& slab_range,
4535  const typename Array4d<T>::range& slice_range,
4536  const typename Array4d<T>::range& row_range,
4537  const typename Array4d<T>::range& col_range)
4538  {
4539  DPoint4d<int> dp(1,1,1,0);
4540  return typename Array4d<T>::reverse_iterator4d_range(this->last_back_bottom_right(
4541  slab_range,slice_range,row_range,col_range) - dp);
4542  }
4543 
4544 template<typename T>
4545 inline
4546 typename Array4d<T>::const_reverse_iterator4d_range
4547 Array4d<T>::rfirst_front_upper_left(const typename Array4d<T>::range& slab_range,
4548  const typename Array4d<T>::range& slice_range,
4549  const typename Array4d<T>::range& row_range,
4550  const typename Array4d<T>::range& col_range) const
4551  {
4552  DPoint4d<int> dp(1,1,1,0);
4553  return typename Array4d<T>::const_reverse_iterator4d_range(typename Array4d<T>::const_iterator4d_range(
4554  this->last_back_bottom_right(slab_range,slice_range,row_range,col_range)- dp));
4555  }
4556 
4557 template<typename T>
4558 inline
4559 typename Array4d<T>::reverse_iterator4d_range
4560 Array4d<T>::rlast_back_bottom_right(const typename Array4d<T>::range& slab_range,
4561  const typename Array4d<T>::range& slice_range,
4562  const typename Array4d<T>::range& row_range,
4563  const typename Array4d<T>::range& col_range)
4564  {
4565  return typename Array4d<T>::reverse_iterator4d_range(this->first_front_upper_left(slab_range,slice_range,
4566  row_range,col_range));
4567  }
4568 
4569 template<typename T>
4570 inline
4571 typename Array4d<T>::const_reverse_iterator4d_range
4572 Array4d<T>::rlast_back_bottom_right(const typename Array4d<T>::range& slab_range,
4573  const typename Array4d<T>::range& slice_range,
4574  const typename Array4d<T>::range& row_range,
4575  const typename Array4d<T>::range& col_range) const
4576  {
4577  return typename Array4d<T>::const_reverse_iterator4d_range(this->first_front_upper_left(slab_range,slice_range,
4578  row_range,col_range));
4579  }
4580 
4581 
4583 
4584 
4586 // i/o operators
4588 
4589 /* @{ */
4590  template <typename T>
4591 inline
4592 std::ostream& operator<<(std::ostream & out, const Array4d<T>& a)
4593  {
4594  for(std::size_t i = 0; i < a.d1_; ++i)
4595  {
4596  for(std::size_t j = 0; j < a.d2_; ++j)
4597  {
4598  for(std::size_t k = 0; k < a.d3_; ++k)
4599  {
4600  for(std::size_t l = 0; l < a.d4_; ++l)
4601  {
4602  out<<a.data_[i][j][k][l]<<" ";
4603  }
4604  out<<std::endl;
4605  }
4606  out<<std::endl;
4607  }
4608  out<<"----" << std::endl << std::endl;
4609  }
4610  out<<std::endl;
4611  return out;
4612  }
4613  /* @} */
4615 
4616 
4618  // Elements access operators
4620  template<typename T>
4621  inline
4622  T*** Array4d<T>::operator[](const typename Array4d<T>::size_type l)
4623  {
4624  assert(this->data_ != 0);
4625  assert(l < this->d1_);
4626  return this->data_[l];
4627  }
4628 
4629  template<typename T>
4630  inline
4631  const T** const* Array4d<T>::operator[](const typename Array4d<T>::size_type l) const
4632  {
4633  assert(this->data_ != 0);
4634  assert(l < this->d1_);
4635  return const_cast<const T** const*>(this->data_[l]);
4636  }
4637 
4638 
4639 
4640  template<typename T>
4641  inline
4642  typename Array4d<T>::reference
4643  Array4d<T>::operator()(const typename Array4d<T>::size_type l, const typename Array4d<T>::size_type k,
4644  const typename Array4d<T>::size_type i,
4645  const typename Array4d<T>::size_type j)
4646  {
4647  assert(this->data_ != 0);
4648  assert(l < this->d1_);
4649  assert(k < this->d2_);
4650  assert(i < this->d3_);
4651  assert(j < this->d4_);
4652  return this->data_[l][k][i][j];
4653  }
4654 
4655  template<typename T>
4656  inline
4657  typename Array4d<T>::const_reference
4658  Array4d<T>::operator()(const typename Array4d<T>::size_type l, const typename Array4d<T>::size_type k,
4659  const typename Array4d<T>::size_type i,
4660  const typename Array4d<T>::size_type j) const
4661  {
4662  assert(this->data_ != 0);
4663  assert(l < this->d1_);
4664  assert(k < this->d2_);
4665  assert(i < this->d3_);
4666  assert(j < this->d4_);
4667  return this->data_[l][k][i][j];
4668  }
4670 
4671  template<typename T>
4672  inline
4673  std::string
4674  Array4d<T>::name() const {return "Array4d";}
4675 
4676 
4677  template<typename T>
4678  inline
4679  typename Array4d<T>::size_type
4680  Array4d<T>::dim1() const {return this->d1_;}
4681 
4682  template<typename T>
4683  inline
4684  typename Array4d<T>::size_type
4685  Array4d<T>::slabs() const {return this->dim1();}
4686 
4687  template<typename T>
4688  inline
4689  typename Array4d<T>::size_type
4690  Array4d<T>::dim2() const {return this->d2_;}
4691 
4692  template<typename T>
4693  inline
4694  typename Array4d<T>::size_type
4695  Array4d<T>::slices() const {return this->dim2();}
4696 
4697  template<typename T>
4698  inline
4699  typename Array4d<T>::size_type
4700  Array4d<T>::dim3() const {return this->d3_;}
4701 
4702  template<typename T>
4703  inline
4704  typename Array4d<T>::size_type
4705  Array4d<T>::rows() const {return this->dim3();}
4706 
4707  template<typename T>
4708  inline
4709  typename Array4d<T>::size_type
4710  Array4d<T>::dim4() const {return this->d4_;}
4711 
4712  template<typename T>
4713  inline
4714  typename Array4d<T>::size_type
4715  Array4d<T>::cols() const {return this->dim4();}
4716 
4717  template<typename T>
4718  inline
4719  typename Array4d<T>::size_type
4720  Array4d<T>::columns() const {return this->dim4();}
4721 
4722 
4723  template<typename T>
4724  inline
4725  typename Array4d<T>::size_type
4726  Array4d<T>::size() const {return this->size_;}
4727 
4728  template<typename T>
4729  inline
4730  typename Array4d<T>::size_type
4732  {
4733  return typename Array4d<T>::size_type(-1)/sizeof(T);
4734  }
4735 
4736  template<typename T>
4737  inline
4738  bool Array4d<T>::empty()const {return this->size_ == 0;}
4739 
4740  template<typename T>
4741  inline
4743  {
4744  assert(this->d1_ == M.d1_);
4745  assert(this->d2_ == M.d2_);
4746  assert(this->d3_ == M.d3_);
4747  assert(this->d4_ == M.d4_);
4748  std::swap_ranges(this->begin(),this->end(),M.begin());
4749  }
4750 
4751 
4753  // comparison operators
4755 
4756  /* @{ */
4757  template<typename T>
4758  inline
4759  bool operator==(const Array4d<T>& x,
4760  const Array4d<T>& y)
4761  {
4762  return ( x.size() == y.size()
4763  && std::equal(x.begin(),x.end(),y.begin()));
4764  }
4765 
4766  template<typename T>
4767  inline
4768  bool operator!=(const Array4d<T>& x,
4769  const Array4d<T>& y)
4770  {
4771  return !(x == y);
4772  }
4773  /* @} */
4775  /* @{ */
4776  template<typename T>
4777  inline
4778  bool operator<(const Array4d<T>& x,
4779  const Array4d<T>& y)
4780  {
4781  return std::lexicographical_compare(x.begin(), x.end(),
4782  y.begin(), y.end());
4783  }
4784 
4785 
4786  template<typename T>
4787  inline
4788  bool operator>(const Array4d<T>& x,
4789  const Array4d<T>& y)
4790  {
4791  return (y < x);
4792  }
4793 
4794  template<typename T>
4795  inline
4796  bool operator<=(const Array4d<T>& x,
4797  const Array4d<T>& y)
4798  {
4799  return !(y < x);
4800  }
4801 
4802  template<typename T>
4803  inline
4804  bool operator>=(const Array4d<T>& x,
4805  const Array4d<T>& y)
4806  {
4807  return !(x < y);
4808  }
4809  /* @} */
4810 
4812 
4813 
4815  // private methods
4817 
4818  template<typename T>
4819  inline
4820  void Array4d<T>::allocate()
4821  {
4822  if( this->d1_ != 0 && this->d2_ != 0 && this->d3_ != 0 && this->d4_ != 0)
4823  {
4824  this->data_ = new T***[this->d1_];
4825  this->data_[0] = new T**[this->d1_ * this->d2_];
4826  this->data_[0][0] = new T*[this->d1_ * this->d2_ * this->d3_];
4827  this->data_[0][0][0] = new T[this->d1_ * this->d2_ * this->d3_ * this->d4_];
4828 
4829  for(std::size_t l = 0; l < this->d1_; ++l)
4830  {
4831  //if(l != 0) -> d1_ tests are worst than one identity affectation
4832  this->data_[l] = this->data_[0] + l * this->d2_;
4833  for(std::size_t k = 0; k < this->d2_; ++k){
4834  //if(l != 0 || k != 0) -> d1_*d2_ tests are worst than one identity affectation
4835  this->data_[l][k] = this->data_[0][0] + l * this->d2_ * this->d3_ + k * this->d3_;
4836  for(std::size_t i = 0; i < this->d3_; ++i){
4837  //if(l != 0 || k != 0 || i != 0) -> d1_*d2_*d3_ tests are worst than one identity affectation
4838  this->data_[l][k][i] = this->data_[0][0][0] + l * this->d2_ * this->d3_ * this->d4_
4839  + k * this->d3_ * this->d4_ + i * this->d4_;
4840  }
4841  }
4842  }
4843  }
4844  else
4845  {
4846  this->data_ = 0;
4847  }
4848  }
4849 
4850  template<typename T>
4851  inline
4852  void Array4d<T>::desallocate()
4853  {
4854  if(this->data_ != 0)
4855  {
4856  delete[] (this->data_[0][0][0]);
4857  delete[] (this->data_[0][0]);
4858  delete[] (this->data_[0]);
4859  delete[] (this->data_);
4860  }
4861  }
4862 
4863  template<typename T>
4864  inline
4865  void Array4d<T>::copy_attributes(const Array4d<T>& rhs)
4866  {
4867  this->d1_ = rhs.d1_;
4868  this->d2_ = rhs.d2_;
4869  this->d3_ = rhs.d3_;
4870  this->d4_ = rhs.d4_;
4871  this->size_ = rhs.size_;
4872  }
4873 
4874 
4876 
4877 }//slip::
4878 
4879 #endif //SLIP_ARRAY4D_HH
col_iterator col_begin(const size_type slab, const size_type slice, const size_type col)
Returns a read/write iterator that points to the first element of the column column of a given slab s...
reverse_iterator4d rfirst_front_upper_left()
Returns a read/write reverse iterator4d. It points to the last back bottom right element of the Array...
Definition: Array4d.hpp:4391
slip::stride_iterator< const_pointer > const_row_range_iterator
Definition: Array4d.hpp:198
bool operator!=(const Array< T > &x, const Array< T > &y)
Definition: Array.hpp:1448
This is some iterator to iterate a 4d container into a Box area defined by the subscripts of the 4d c...
std::size_t iterations() const
Rerturns the number of iterations of the range.
Definition: Range.hpp:305
reverse_row_iterator row_rend(const size_type slab, const size_type slice, const size_type row)
Returns a read/write reverse iterator that points to the first element of the row row of a given slab...
slip::Array4d< unsigned long > Array4d_ul
unsigned long alias
Definition: Array4d.hpp:3227
reverse_iterator4d rlast_back_bottom_right()
Returns a read/write reverse iterator4d. It points to past the first front upper left element of the ...
Definition: Array4d.hpp:4375
reverse_slice_iterator slice_rend(const size_type slab, const size_type row, const size_type col)
Returns a read/write iterator that points to the one before the first element of the line (slab...
std::reverse_iterator< const_row_range_iterator > const_reverse_row_range_iterator
Definition: Array4d.hpp:215
size_type dim4() const
Returns the number of columns (fourth dimension size) in the Array4d.
Definition: Array4d.hpp:4710
iterator4d last_back_bottom_right()
Returns a read/write iterator4d that points to the past the end element of the Array4d. It points to past the end element of the last back bottom right element of the Array4d.
Definition: Array4d.hpp:4356
slip::stride_iterator< const_slice_iterator > const_slice_range_iterator
Definition: Array4d.hpp:196
slip::stride_iterator< const_pointer > const_slab_iterator
Definition: Array4d.hpp:185
size_type columns() const
Returns the number of columns (fourth dimension size) in the Array4d.
Definition: Array4d.hpp:4720
iterator4d default_iterator
Definition: Array4d.hpp:231
slip::Array4d< unsigned int > Array4d_ui
unsigned int alias
Definition: Array4d.hpp:3235
CoordType depth() const
compute the depth of the Box4d (second dimension size).
Definition: Box4d.hpp:428
value_type const * const_pointer
Definition: Array4d.hpp:172
T *** operator[](const size_type l)
This is some iterator to iterate a 4d container into two Range defined by the indices and strides of ...
iterator end()
Returns a read/write iterator that points one past the last element in the Array4d. Iteration is done in ordinary element order.
Definition: Array4d.hpp:3411
size_type max_size() const
Returns the maximal size (number of elements) in the Array4d.
Definition: Array4d.hpp:4731
self & operator=(const Array4d< T > &rhs)
Assign a Array4d.
Definition: Array4d.hpp:3321
This is some iterator to iterate a 4d container into a Box area defined by the subscripts of the 4d c...
row_iterator row_end(const size_type slab, const size_type slice, const size_type row)
Returns a read/write iterator that points to the past-the-end element of the row row of a given slab ...
size_type slabs() const
Returns the number of slabs (first dimension size, called time dimension too) in the Array4d...
Definition: Array4d.hpp:4685
slip::stride_iterator< col_iterator > col_range_iterator
Definition: Array4d.hpp:199
Provides a class to modelize 4d points.
std::reverse_iterator< slice_range_iterator > reverse_slice_range_iterator
Definition: Array4d.hpp:212
std::reverse_iterator< const_col_iterator > const_reverse_col_iterator
Definition: Array4d.hpp:209
slip::stride_iterator< const_col_iterator > const_col_range_iterator
Definition: Array4d.hpp:200
std::reverse_iterator< const_iterator4d_range > const_reverse_iterator4d_range
Definition: Array4d.hpp:228
Array4d(const size_type d1, const size_type d2, const size_type d3, const size_type d4, InputIterator first, InputIterator last)
Contructs a Array4d from a range.
Definition: Array4d.hpp:303
slab_iterator slab_end(const size_type slice, const size_type row, const size_type col)
Returns a read/write iterator that points to the one past the end element of the line (slice...
value_type const * const_iterator
Definition: Array4d.hpp:178
slip::Array4d< unsigned short > Array4d_us
unsigned long alias
Definition: Array4d.hpp:3231
reverse_slab_iterator slab_rend(const size_type slice, const size_type row, const size_type col)
Returns a read/write iterator that points to the one before the first element of the line (slice...
size_type dim2() const
Returns the number of slices (second dimension size) in the Array4d.
Definition: Array4d.hpp:4690
std::reverse_iterator< const_iterator4d > const_reverse_iterator4d
Definition: Array4d.hpp:226
reverse_iterator rbegin()
Returns a read/write reverse iterator that points to the last element in the Array4d. Iteration is done in reverse element order.
Definition: Array4d.hpp:3418
reverse_row_iterator row_rbegin(const size_type slab, const size_type slice, const size_type row)
Returns a read/write reverse iterator that points to the last element of the row row of a given slab ...
const_iterator4d const_default_iterator
Definition: Array4d.hpp:232
slab_iterator slab_begin(const size_type slice, const size_type row, const size_type col)
Returns a read/write iterator that points to the first element of the line (slice,row,col) through the slabs in the Array4d. Iteration is done in ordinary element order (increasing slab number).
bool operator>(const Array< T > &x, const Array< T > &y)
Definition: Array.hpp:1469
slip::iterator4d_box< self > iterator4d
Definition: Array4d.hpp:220
iterator4d first_front_upper_left()
Returns a read/write iterator4d that points to the first element of the Array4d. It points to the fir...
Definition: Array4d.hpp:4341
const Array4d< T > const_self
Definition: Array4d.hpp:166
reverse_col_iterator col_rbegin(const size_type slab, const size_type slice, const size_type col)
Returns a read/write reverse iterator that points to the last element of the column column of a given...
std::reverse_iterator< const_iterator > const_reverse_row_iterator
Definition: Array4d.hpp:207
std::reverse_iterator< iterator > reverse_iterator
Definition: Array4d.hpp:180
std::reverse_iterator< col_range_iterator > reverse_col_range_iterator
Definition: Array4d.hpp:216
size_type dim3() const
Returns the number of rows (third dimension size) in the Array4d.
Definition: Array4d.hpp:4700
std::reverse_iterator< iterator4d > reverse_iterator4d
Definition: Array4d.hpp:225
Difference of Point4D class, specialization of DPoint<CoordType,DIM> with DIM = 4.
Definition: DPoint4d.hpp:99
reverse_slab_iterator slab_rbegin(const size_type slice, const size_type row, const size_type col)
Returns a read/write iterator that points to the last element of the line (slice,row,col) through the slabs in the Array4d. Iteration is done in reverse element order (decreasing slab number).
void fill(const T *value)
Fills the container range [begin(),begin()+size()) with a copy of the value array.
Definition: Array4d.hpp:2935
reference operator()(const size_type l, const size_type k, const size_type i, const size_type j)
Subscript access to the data contained in the Array4d.
Provides a class to modelize the difference of 4d points.
slip::stride_iterator< slice_iterator > slice_range_iterator
Definition: Array4d.hpp:195
slip::stride_iterator< pointer > col_iterator
Definition: Array4d.hpp:190
void resize(std::size_t d1, std::size_t d2, std::size_t d3, std::size_t d4, const T &val=T())
Resizes a Array4d.
Definition: Array4d.hpp:3351
slip::stride_iterator< const_pointer > const_slice_iterator
Definition: Array4d.hpp:187
slip::Array4d< char > Array4d_c
char alias
Definition: Array4d.hpp:3237
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
Definition: copy_ext.hpp:177
std::reverse_iterator< slice_range_iterator > reverse_slab_range_iterator
Definition: Array4d.hpp:210
bool is_valid() const
Returns true if the range is valid :
Definition: Range.hpp:322
SubType start() const
Accessor of the start subscript of the Range.
Definition: Range.hpp:284
slip::iterator4d_range< self > iterator4d_range
Definition: Array4d.hpp:222
void fill(const T &value)
Fills the container range [begin(),begin()+size()) with copies of value.
Definition: Array4d.hpp:2924
slip::Array4d< unsigned char > Array4d_uc
unsigned char alias
Definition: Array4d.hpp:3239
size_type size() const
Returns the number of elements in the Array4d.
Definition: Array4d.hpp:4726
std::reverse_iterator< const_slice_iterator > const_reverse_slice_iterator
Definition: Array4d.hpp:205
value_type const & const_reference
Definition: Array4d.hpp:169
This is a four-dimensional dynamic and generic container. This container statisfies the Bidirectionna...
Definition: Array4d.hpp:105
std::reverse_iterator< slice_iterator > reverse_slice_iterator
Definition: Array4d.hpp:204
~Array4d()
Destructor of the Array4d.
Definition: Array4d.hpp:3308
slip::stride_iterator< pointer > row_range_iterator
Definition: Array4d.hpp:197
row_iterator row_begin(const size_type slab, const size_type slice, const size_type row)
Returns a read/write iterator that points to the first element of the row row of a given slab slab an...
size_type rows() const
Returns the number of rows (third dimension size) in the Array4d.
Definition: Array4d.hpp:4705
std::reverse_iterator< const_col_range_iterator > const_reverse_col_range_iterator
Definition: Array4d.hpp:217
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: Array4d.hpp:181
std::reverse_iterator< iterator > reverse_row_iterator
Definition: Array4d.hpp:206
slip::Array4d< double > Array4d_d
double alias
Definition: Array4d.hpp:3221
col_iterator col_end(const size_type slab, const size_type slice, const size_type col)
Returns a read/write iterator that points to the past-the-end element of the column column of a given...
std::ostream & operator<<(std::ostream &out, const Array< T > &a)
Definition: Array.hpp:1282
reverse_col_iterator col_rend(const size_type slab, const size_type slice, const size_type col)
Returns a read/write reverse iterator that points to the first element of the column column of a give...
slip::stride_iterator< pointer > slice_iterator
Definition: Array4d.hpp:186
size_type dim1() const
Returns the number of slabs (first dimension size, called time dimension too) in the Array4d...
Definition: Array4d.hpp:4680
CoordType width() const
compute the width of the Box4d (fourth dimension size).
Definition: Box4d.hpp:420
size_type slices() const
Returns the number of slices (second dimension size) in the Array4d.
Definition: Array4d.hpp:4695
Provides a class to manipulate 4d box.
bool empty() const
Returns true if the Array4d is empty. (Thus size() == 0)
Definition: Array4d.hpp:4738
value_type * pointer
Definition: Array4d.hpp:171
size_type cols() const
Returns the number of columns (fourth dimension size) in the Array4d.
Definition: Array4d.hpp:4715
Some const iterator to iterate a 4d container into two Range defined by the indices and strides of th...
std::size_t size_type
Definition: Array4d.hpp:175
slip::stride_iterator< slab_iterator > slab_range_iterator
Definition: Array4d.hpp:193
slip::const_iterator4d_box< const_self > const_iterator4d
Definition: Array4d.hpp:221
slip::Array4d< int > Array4d_i
int alias
Definition: Array4d.hpp:3233
slip::Range< int > range
Definition: Array4d.hpp:235
std::string name() const
Returns the name of the class.
Definition: Array4d.hpp:4674
std::reverse_iterator< const_slice_range_iterator > const_reverse_slice_range_iterator
Definition: Array4d.hpp:213
std::reverse_iterator< col_iterator > reverse_col_iterator
Definition: Array4d.hpp:208
void fill(InputIterator first, InputIterator last)
Fills the container range [begin(),begin()+size()) with a copy of the range [first,last)
Definition: Array4d.hpp:2949
slip::stride_iterator< pointer > slab_iterator
Definition: Array4d.hpp:184
int stride() const
Accessor of the stride of the Range.
Definition: Range.hpp:298
CoordType duration() const
compute the duration of the Box4d (first dimension size).
Definition: Box4d.hpp:432
slip::stride_iterator< const_slab_iterator > const_slab_range_iterator
Definition: Array4d.hpp:194
std::reverse_iterator< row_range_iterator > reverse_row_range_iterator
Definition: Array4d.hpp:214
ptrdiff_t difference_type
Definition: Array4d.hpp:174
value_type & reference
Definition: Array4d.hpp:168
Provides a class to manipulate iterator4d within a slip::Range. It is used to iterate throw 4d contai...
void swap(Array4d &M)
Swaps data with another Array4d.
Definition: Array4d.hpp:4742
Provides a class to iterate a 1d range according to a step.
const_pointer const_row_iterator
Definition: Array4d.hpp:189
value_type * iterator
Definition: Array4d.hpp:177
slip::Array4d< short > Array4d_s
short alias
Definition: Array4d.hpp:3229
CoordType height() const
compute the height of the Box4d (third dimension size).
Definition: Box4d.hpp:424
reverse_iterator rend()
Returns a read/write reverse iterator that points to one before the first element in the Array4d...
Definition: Array4d.hpp:3432
slip::stride_iterator< const_pointer > const_col_iterator
Definition: Array4d.hpp:191
slice_iterator slice_begin(const size_type slab, const size_type row, const size_type col)
Returns a read/write iterator that points to the first element of the line (slab,row,col) through the slices in the Array4d. Iteration is done in ordinary element order (increasing slice number).
bool operator==(const Array< T > &x, const Array< T > &y)
Definition: Array.hpp:1439
std::reverse_iterator< iterator4d_range > reverse_iterator4d_range
Definition: Array4d.hpp:227
slip::const_iterator4d_range< const_self > const_iterator4d_range
Definition: Array4d.hpp:223
slip::Array4d< float > Array4d_f
float alias
Definition: Array4d.hpp:3223
static const std::size_t DIM
Definition: Array4d.hpp:237
slip::Array4d< long > Array4d_l
long alias
Definition: Array4d.hpp:3225
reverse_slice_iterator slice_rbegin(const size_type slab, const size_type row, const size_type col)
Returns a read/write iterator that points to the last element of the line (slab,row,col) through the slices in the Array4d. Iteration is done in reverse element order (decreasing slice number).
Provides a class to manipulate iterator4d within a slip::Box4d. It is used to iterate throw 4d contai...
slice_iterator slice_end(const size_type slab, const size_type row, const size_type col)
Returns a read/write iterator that points to the one past the end element of the line (slab...
Array4d()
Constructs a Array4d.
Definition: Array4d.hpp:3251
std::reverse_iterator< const_slab_iterator > const_reverse_slab_iterator
Definition: Array4d.hpp:203
SubType stop() const
Accessor of the stop subscript of the Range.
Definition: Range.hpp:291
bool operator>=(const Array< T > &x, const Array< T > &y)
Definition: Array.hpp:1485
std::reverse_iterator< const_slice_range_iterator > const_reverse_slab_range_iterator
Definition: Array4d.hpp:211
const_iterator begin() const
Returns a read-only (constant) iterator that points to the first element in the Array4d. Iteration is done in ordinary element order.
Definition: Array4d.hpp:3390
pointer row_iterator
Definition: Array4d.hpp:188
std::reverse_iterator< slab_iterator > reverse_slab_iterator
Definition: Array4d.hpp:202
friend class boost::serialization::access
Definition: Array4d.hpp:3193