ivl 679
ivl/details/array/impl/specialization_details/subarray/subarray_iterator.hpp
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>.
00002    A C++ template library extending syntax towards mathematical notation.
00003 
00004    Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr>
00005    Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr>
00006 
00007    ivl is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU Lesser General Public License 
00009    version 3 as published by the Free Software Foundation.
00010 
00011    Alternatively, you can redistribute it and/or modify it under the terms 
00012    of the GNU General Public License version 2 as published by the Free 
00013    Software Foundation.
00014 
00015    ivl is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00018    See the GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License 
00021    and a copy of the GNU Lesser General Public License along 
00022    with ivl. If not, see <http://www.gnu.org/licenses/>. */
00023 
00024 #ifndef IVL_ARRAY_SPECIALIZATION_DETAILS_SUBARRAY_ITERATOR_HPP
00025 #define IVL_ARRAY_SPECIALIZATION_DETAILS_SUBARRAY_ITERATOR_HPP
00026 
00027 namespace ivl {
00028 
00029 namespace data {
00030 
00031 
00032 template <class T, class IT, class BEST_IT,
00033         bool REF_IS_ND, bool CONST, int SPECIALIZED = 0>
00034 class subarray_iterator_type
00035 {
00036 };
00037 
00038 template <class T, class IT, class BEST_IT, bool CONST, int SPECIALIZED>
00039 class subarray_iterator_type<T, IT, BEST_IT, false, CONST, SPECIALIZED>
00040 : public data::data_details::
00041         iter_operator_expander<
00042                 subarray_iterator_type<T, IT, BEST_IT, false, CONST, SPECIALIZED>,
00043                         T, CONST, typename IT::reference>
00044 {
00045 private:
00046         typedef IT reference_iterator;
00047         typedef BEST_IT best_reference_iterator;
00048 
00049         template <class J, class Y, class Z, bool R, bool C, int S>
00050         friend class subarray_iterator_type;
00051 
00052         typedef array_details::subarray_common_tools ctool;
00053 
00054         /*
00055         A little notice:
00056         This code was intended to be here:
00057         friend class data::data_details::iter_operator_expander
00058                 <subarray_iterator_type, T, CONST, typename IT::reference>;
00059         however MSVC does not like it, so instead of making portability hacks
00060         I will rather generalize the declaration. I've also done this in other places.
00061         */
00062         template <class X, class Y, bool C, class Z>
00063         friend class data::data_details::iter_operator_expander;
00064 
00065         typedef typename types::apply_const<T, types::t_expr<CONST> >
00066                 ::type best_value_type;
00067 
00068         typedef typename types::apply_const<typename IT::reference,
00069                 types::t_expr<CONST> >::type best_ref_type;
00070 
00071         // this class is used to disable specific specialization members
00072         class not_a_type { };
00073 
00074         typedef typename types::t_if<types::t_expr<CONST>, not_a_type,
00075                 types::code_word<> >::type invalid_if_const;
00076 
00077 protected:
00078         reference_iterator ir;
00079         const size_t* sizes;
00080         size_t size0;
00081         const ptrdiff_t* const* diffs;
00082         const ptrdiff_t* diff0;
00083         ptrdiff_t step0;
00084         const ptrdiff_t* back;
00085         internal::little_arrayling<ptrdiff_t> pos;
00086         size_t pos0;
00087 
00088         inline size_t get_pos1() const { return pos[1]; }
00089 
00090         inline typename types::apply_const<typename IT::reference>::type base(
00091                 types::code_word<> ok = types::code_word<>()) const
00092                 { return (*ir); }
00093 
00094         inline best_ref_type base(
00095                 invalid_if_const disable = invalid_if_const())
00096                 { return (*ir); }
00097 
00098 public:
00099         typedef subarray_iterator_type this_type;
00100 
00101         // iterator_traits
00102         typedef std::bidirectional_iterator_tag iterator_category;
00103         typedef T value_type;
00104         typedef ptrdiff_t difference_type;
00105         typedef best_value_type* pointer;
00106         typedef best_ref_type reference;
00107 
00108         struct iter_border_walker
00109         {
00110                 char type; // 0: stay. 1: first_to_last. 2: begin_to_end
00111                 ptrdiff_t step;
00112                 iter_border_walker(ptrdiff_t x) : type(0), step(0) { }
00113                 iter_border_walker(ptrdiff_t x, char t) : type(t), step(x) { }
00114         };
00115 
00116         // constructors
00117         subarray_iterator_type() { }
00118         subarray_iterator_type(const this_type& it)
00119         : ir(it.ir), sizes(it.sizes), size0(it.size0), diffs(it.diffs),
00120                 diff0(it.diff0), step0(it.step0), back(it.back),
00121                 pos(it.pos), pos0(it.pos0) { }
00122 
00123         template <class Y, bool C, int S>
00124         subarray_iterator_type(
00125                 const subarray_iterator_type<T, Y, BEST_IT, false, C, S>& it)
00126                         : ir(it.ir), sizes(it.sizes), size0(it.size0), diffs(it.diffs),
00127                 diff0(it.diff0), step0(it.step0), back(it.back),
00128                 pos(it.pos), pos0(it.pos0) { }
00129 
00130         template <class Y>
00131         subarray_iterator_type(
00132                 const Y& ir,
00133                 const best_reference_iterator* iter,
00134                 size_t ndims,
00135                 const size_t* sizes,
00136                 const ptrdiff_t* const* diffs,
00137                 const ptrdiff_t* steps,
00138                 const ptrdiff_t* back,
00139                 bool ending,
00140                 ptrdiff_t outer_pos) :
00141                         ir(ir),
00142                         sizes(sizes),
00143                         diffs(diffs),
00144                         step0(steps[0]),
00145                         back(back),
00146                         pos(ndims + 1)
00147         {
00148                 diff0 = diffs[0];
00149                 size0 = sizes[0];
00150 
00151                 if(!ending) {
00152                         for(size_t j = 0; j <= ndims; j++)
00153                                 pos[j] = 0;
00154 
00155                 } else {
00156 
00157                         for(size_t j = 0; j < ndims; j++)
00158                                 pos[j] = sizes[j] - 1;
00159                 }
00160 
00161                 pos[ndims] = outer_pos;
00162                 pos0 = pos[0];
00163         }
00164 
00165         //copy same type iterator
00166         this_type& operator=(const this_type& it)
00167         {
00168                 ir = it.ir;
00169                 sizes = it.sizes;
00170                 size0 = it.size0;
00171                 diffs = it.diffs;
00172                 diff0 = it.diff0;
00173                 step0 = it.step0;
00174                 back = it.back;
00175                 pos = it.pos;
00176                 pos0 = it.pos0;
00177 
00178                 return *this;
00179         }
00180 
00181         //copy relevant type iterator
00182         template<class Y, bool C, int S>
00183         this_type& operator=(const subarray_iterator_type<T, Y,
00184                                                 BEST_IT, true, C, S>& it)
00185         {
00186                 ir = it.ir;
00187                 sizes = it.sizes;
00188                 size0 = it.size0;
00189                 diffs = it.diffs;
00190                 diff0 = it.diff0;
00191                 step0 = it.step0;
00192                 pos = it.pos;
00193                 pos0 = it.pos0;
00194                 back = it.back;
00195 
00196                 return *this;
00197         }
00198 
00199         // members
00200 
00201         // increment-decrement
00202         inline this_type& operator++()
00203         {
00204                 if(++pos0 >= size0) {
00205                         pos0 = 0;
00206 
00207                         size_t i = 1;
00208                         while(/*i < pos.length() &&*/ ++pos[i] >= ptrdiff_t(sizes[i])) {
00209                                 pos[i++] = 0;
00210                         }
00211 
00212                         ir += back[i - 1];
00213                         if(diffs[i])
00214                                 ir += diffs[i][pos[i] - 1];
00215 
00216                 }
00217                 else {
00218                         ctool::inner_dim_adder<SPECIALIZED>::template
00219                                 operate<ctool::add_op>(ir, diff0, pos0 - 1, step0);
00220                 }
00221                 return *this;
00222         }
00223 
00224         inline this_type& operator--()
00225         {
00226                 if(--pos0 < 0) {
00227                         pos0 = size0 - 1;
00228 
00229                         size_t i = 1;
00230                         while(/*i < pos.length() &&*/ --pos[i] < 0) {
00231                                 pos[i] = sizes[i] - 1;
00232                                 i++;
00233                         }
00234                         ir -= back[i - 1];
00235                         if(diffs[i])
00236                                 ir -= diffs[i][pos[i]];
00237                 }
00238                 else {
00239                         ctool::inner_dim_adder<SPECIALIZED>::template
00240                                 operate<ctool::sub_op>(ir, diff0, pos0, step0);
00241                 }
00242                 return *this;
00243         }
00244 
00245         this_type operator++(int) { this_type tmp(*this); ++(*this); return tmp; }
00246         this_type operator--(int) { this_type tmp(*this); --(*this); return tmp; }
00247 
00249         this_type& operator +=(size_t j)
00250         {
00251                 CHECK(j == 1, ecomp);
00252                 ++(*this);
00253                 return *this;
00254         }
00256         this_type& operator -=(size_t j)
00257         {
00258                 CHECK(j == 1, ecomp);
00259                 --(*this);
00260                 return *this;
00261         }
00262         inline this_type operator +(size_t j) const
00263         {
00264                 CHECK(j == 1, ecomp);
00265                 this_type tmp(*this);
00266                 ++(*this);
00267                 return tmp;
00268         }
00269         inline this_type operator -(size_t j) const
00270         {
00271                 CHECK(j == 1, ecomp);
00272                 this_type tmp(*this);
00273                 --(*this);
00274                 return tmp;
00275         }
00276 
00277         this_type& operator +=(const iter_border_walker& b)
00278         {
00279                 ir += b.step;
00280 
00281                 size_t p = pos.length() - 1;
00282 
00283                 if(b.type == 1 || (b.type && pos[p] != 1)) {
00284                         // first to last or begin to end, added from begin-1
00285 
00286                         for(size_t i = 1; i < p; i++)
00287                                 pos[i] = sizes[i] - 1;
00288 
00289                         pos[p] = 1;
00290 
00291                         pos0 = size0 - 1;
00292 
00293                 } else if(b.type == 2) { // begin to end, added from begin
00294 
00295                         pos[p] = 2; // end
00296 
00297                 }
00298                 return *this;
00299         }
00300 
00301         this_type& operator -=(const iter_border_walker& b)
00302         {
00303                 ir += b.step;
00304 
00305                 size_t p = pos.length() - 1;
00306 
00307                 if(b.type == 1 || (b.type && pos[p] != 1)) {
00308                         // first to last or begin to end, subtracted from end
00309 
00310                         for(size_t i = 1; i < p; i++)
00311                                 pos[i] = 0;
00312 
00313                         pos[p] = 1;
00314 
00315                         pos0 = 0;
00316 
00317                 } else if(b.type == 2) { // begin to end, subtracted from end-1
00318 
00319                         pos[p] = 0; // begin-1
00320 
00321                 }
00322                 return *this;
00323         }
00324 
00325 
00326         inline this_type operator +(const iter_border_walker& b) const
00327         {
00328                 this_type tmp(*this);
00329                 tmp += b;
00330                 return tmp;
00331         }
00332         inline this_type operator -(const iter_border_walker& b) const
00333         {
00334                 this_type tmp(*this);
00335                 tmp -= b;
00336                 return tmp;
00337         }
00338 
00339         // difference is not implemented.
00340         // this is a non-random_access iterator.
00341 
00342 
00343         bool operator==(const this_type& it) const { return (ir == it.ir); }
00344         bool operator!=(const this_type& it) const { return (ir != it.ir); }
00345 
00346 };
00347 
00348 template <class T, class IT, class BEST_IT,
00349         bool CONST, int SPECIALIZED>
00350 class subarray_iterator_type<T, IT, BEST_IT, true, CONST, SPECIALIZED>
00351 : public data::data_details::
00352         iter_operator_expander<
00353                 subarray_iterator_type<T, IT, BEST_IT, true, CONST, SPECIALIZED>, T, CONST,
00354                         typename IT::reference>
00355 {
00356 private:
00357         typedef IT reference_iterator;
00358         typedef BEST_IT best_reference_iterator;
00359 
00360         template <class J, class Y, class Z, bool R, bool C, int S>
00361         friend class subarray_iterator_type;
00362 
00363         typedef array_details::subarray_common_tools ctool;
00364 
00365         template <class X, class Y, bool C, class Z>
00366         friend class data::data_details::iter_operator_expander;
00367 
00368         typedef typename types::apply_const<T, types::t_expr<CONST> >
00369                 ::type best_value_type;
00370 
00371         typedef typename types::apply_const<typename IT::reference,
00372                 types::t_expr<CONST> >::type best_ref_type;
00373 
00374         // this class is used to disable specific specialization members
00375         class not_a_type { };
00376 
00377         typedef typename types::t_if<types::t_expr<CONST>, not_a_type,
00378                 types::code_word<> >::type invalid_if_const;
00379 
00380 
00381 protected:
00382 
00383 
00384 
00385         reference_iterator ir;
00386         const best_reference_iterator* iter;
00387         reference_iterator it1;
00388         const size_t* sizes;
00389         size_t size0;
00390         size_t size1;
00391         const ptrdiff_t* const* diffs;
00392         const ptrdiff_t* diff0;
00393         const ptrdiff_t* diff1;
00394         const ptrdiff_t* steps;
00395         size_t step0;
00396         size_t step1;
00397         const ptrdiff_t* back;
00398         ptrdiff_t back0;
00399         ptrdiff_t back1;
00400         internal::little_arrayling<size_t> pos;
00401         size_t pos0;
00402         size_t pos1;
00403 
00404         inline size_t get_pos1() const { return pos1; }
00405 
00406         inline typename IT::reference base(
00407                 types::code_word<> ok = types::code_word<>()) const
00408                 { return (*ir); }
00409 
00410         inline best_ref_type base(
00411                 invalid_if_const disable = invalid_if_const())
00412                 { return (*ir); }
00413 
00414 public:
00415         typedef subarray_iterator_type this_type;
00416 
00417         // iterator_traits
00418         typedef std::bidirectional_iterator_tag iterator_category;
00419         typedef T value_type;
00420         typedef ptrdiff_t difference_type;
00421         typedef best_value_type* pointer;
00422         typedef best_ref_type reference;
00423 
00424         struct iter_border_walker
00425         {
00426                 char type; // 0: stay. 1: first_to_last. 2: begin_to_end
00427                 iter_border_walker(ptrdiff_t x) : type(0) { }
00428                 iter_border_walker(ptrdiff_t x, char t) : type(t) { }
00429         };
00430 
00431 
00432         // constructors
00433         subarray_iterator_type() { }
00434         subarray_iterator_type(const this_type& it)
00435         : ir(it.ir), iter(it.iter), it1(it.it1), sizes(it.sizes),
00436                 size0(it.size0), size1(it.size1), diffs(it.diffs), diff0(it.diff0),
00437                 diff1(it.diff1), steps(it.steps), step0(it.step0), step1(it.step1),
00438                 back(it.back), back0(it.back0), back1(it.back1), pos(it.pos),
00439                 pos0(it.pos0), pos1(it.pos1) { }
00440 
00441         template <class Y, bool C, int S>
00442         subarray_iterator_type(
00443                 const subarray_iterator_type<T, Y, BEST_IT, false, C, S>& it)
00444         : ir(it.ir), iter(it.iter), it1(it.it1), sizes(it.sizes),
00445                 size0(it.size0), size1(it.size1), diffs(it.diffs), diff0(it.diff0),
00446                 diff1(it.diff1), steps(it.steps), step0(it.step0), step1(it.step1),
00447                 back(it.back), back0(it.back0), back1(it.back1), pos(it.pos),
00448                 pos0(it.pos0), pos1(it.pos1) { }
00449 
00450         template <class Y>
00451         subarray_iterator_type(
00452                 const Y& ir,
00453                 const best_reference_iterator* iter,
00454                 size_t ndims,
00455                 const size_t* sizes,
00456                 const ptrdiff_t* const* diffs,
00457                 const ptrdiff_t* steps,
00458                 const ptrdiff_t* back,
00459                 bool ending,
00460                 ptrdiff_t outer_pos) :
00461                         ir(ir),
00462                         iter(iter),
00463                         sizes(sizes),
00464                         diffs(diffs),
00465                         steps(steps),
00466                         back(back),
00467                         pos(ndims + 1)
00468         {
00469                 diff0 = diffs[0];
00470                 diff1 = diffs[1];
00471                 size0 = sizes[0];
00472                 size1 = sizes[1];
00473                 step0 = steps[0];
00474                 step1 = steps[1];
00475                 back0 = back[0];
00476                 back1 = back[1];
00477 
00478                 if(ndims > 1)
00479                         it1 = iter[1];
00480 
00481                 if(!ending) {
00482 
00483                         for(size_t j = 0; j <= ndims; j++)
00484                                 pos[j] = 0;
00485 
00486                 } else {
00487 
00488                         for(size_t j = 0; j < ndims; j++)
00489                                 pos[j] = sizes[j] - 1;
00490                 }
00491 
00492                 pos[ndims] = outer_pos;
00493                 pos0 = pos[0];
00494                 pos1 = ndims <= 1 ?  0 : pos[1];
00495         }
00496 
00497         // members
00498 
00499         // increment-decrement
00500 
00501         inline this_type& operator++()
00502         {
00503                 int i;
00504 
00505                 if(++pos0 >= size0) {
00506                         pos0 = 0;
00507 
00508                         ir -= back0;
00509                         if(++pos1 < size1) {
00510                                 ctool::inc_along(ir, it1, diff1, pos1 - 1, step1);
00511 
00512                         } else {
00513                                 // TODO: ensure in the case of ndim == 1 to have:
00514                                 // first_to_last1 = 0
00515                                 // pos = minimum 3, instead of 1+1 = 2.
00516                                 // pos1 = 0, pos[1] = 0
00517                                 // sizes[1]=size1 =0 in that case. so sizes = minimum 2.
00518                                 // size1 = 0 is adequate for all the above line.
00519                                 pos1 = 0;
00520                                 ir.move_along(it1, -back1);
00521                                 i = 2;
00522                                 /*if(pos[pos.length() - 1] == 0) { // begin-1 to begin
00523                                         ir = iter[-3];
00524                                         for(; i < pos.length(); i++)
00525                                                 pos[i] = 0;
00526                                         pos[i] = 1;
00527                                         i++; // to disable both while and if below
00528                                 }*/
00529                                 while(i < pos.length() && ++pos[i] >= sizes[i]) {
00530                                         pos[i] = 0;
00531                                         ir.move_along(iter[i], -back[i]);
00532                                         i++;
00533                                 }
00534                                 if(i == pos.length()) { // end-1 to end
00535                                         pos[i] = 2;
00536                                         ir = iter[-1];
00537                                 } else {
00538                                         ctool::inc_along(ir, iter[i],
00539                                                 diffs[i], pos[i] - 1, steps[i]);
00540                                 }
00541                         }
00542                 }
00543                 else {
00544                         ctool::inner_dim_adder<SPECIALIZED>::template
00545                                 operate<ctool::add_op>(ir, diff0, pos0 - 1, step0);
00546                 }
00547                 return *this;
00548         }
00549 
00550         inline this_type& operator--()
00551         {
00552                 int i;
00553 
00554                 if(--pos0 < 0) {
00555                         pos0 = size0 - 1;
00556 
00557                         ir += back0;
00558                         if(--pos1 >= 0) {
00559                                 ctool::dec_along(ir, it1, diff1, pos1, step0);
00560 
00561                         } else {
00562 
00563                                 pos1 = size1 - 1;
00564                                 ir.move_along(it1, back1);
00565                                 i = 2;
00566                                 if(pos[pos.length() - 1] == 2) { // end to end-1
00567                                         ir = iter[-2];
00568                                         for(; i < pos.length(); i++)
00569                                                 pos[i] = sizes[i] - 1;
00570                                         pos[i] = 1;
00571                                         i++;
00572                                 }
00573                                 while(i < pos.length() && --pos[i] < 0) {
00574                                         pos[i] = sizes[i] - 1;
00575                                         ir.move_along(iter[i], back[i]);
00576                                         i++;
00577                                 }
00578                                 /*if(i == pos.length()) { // begin to begin-1
00579                                         pos[i] = 0;
00580                                         ir = iter[-4];
00581                                 } else */{
00582                                         ctool::dec_along(ir, iter[i], diffs[i], pos[i], steps[i]);
00583                                 }
00584                         }
00585                 }
00586                 else {
00587                         ctool::inner_dim_adder<SPECIALIZED>::template
00588                                 operate<ctool::sub_op>(ir, diff0, pos0, step0);
00589                 }
00590                 return *this;
00591         }
00592 
00593         this_type operator++(int) { this_type tmp(*this); ++(*this); return tmp; }
00594         this_type operator--(int) { this_type tmp(*this); --(*this); return tmp; }
00595 
00597         this_type& operator +=(size_t j)
00598         {
00599                 CHECK(j == 1, ecomp);
00600                 ++(*this);
00601                 return *this;
00602         }
00604         this_type& operator -=(size_t j)
00605         {
00606                 CHECK(j == 1, ecomp);
00607                 --(*this);
00608                 return *this;
00609         }
00610         inline this_type operator +(size_t j) const
00611         {
00612                 CHECK(j == 1, ecomp);
00613                 this_type tmp(*this);
00614                 ++(*this);
00615                 return tmp;
00616         }
00617         inline this_type operator -(size_t j) const
00618         {
00619                 CHECK(j == 1, ecomp);
00620                 this_type tmp(*this);
00621                 --(*this);
00622                 return tmp;
00623         }
00624 
00625 
00626         this_type& operator +=(const iter_border_walker& b)
00627         {
00628                 size_t p = pos.length() - 1;
00629 
00630                 if(b.type == 1 /*|| (b.type && pos[p] != 1)*/) {
00631                         // first to last [[or begin to end, added from begin-1]]
00632 
00633                         for(size_t i = 2; i < p; i++)
00634                                 pos[i] = sizes[i] - 1;
00635 
00636                         pos[p] = 1;
00637 
00638                         pos0 = size0 - 1;
00639                         pos1 = size1 - 1;
00640 
00641                         ir = iter[-2];
00642 
00643                 } else if(b.type == 2) { // begin to end, added from begin
00644 
00645                         pos[p] = 2; // end
00646 
00647                         ir = iter[-1];
00648 
00649                 }
00650                 return *this;
00651         }
00652 
00653         this_type& operator -=(const iter_border_walker& b)
00654         {
00655                 size_t p = pos.length() - 1;
00656 
00657                 //if(b.type == 1 || (b.type && pos[p] != 1)) {
00658                         // first to last or begin to end, subtracted from end
00659 
00660                         for(size_t i = 2; i < p; i++)
00661                                 pos[i] = 0;
00662 
00663                         pos[p] = 1;
00664 
00665                         pos0 = 0;
00666                         pos1 = 0;
00667 
00668                         ir = iter[-3];
00669 
00670                 /*} else if(b.type == 2) { // begin to end, subtracted from end-1
00671 
00672                         pos[p] = 0; // begin-1
00673 
00674                         ir = iter[-1];
00675 
00676                 }*/
00677                 return *this;
00678         }
00679 
00680         inline this_type operator +(const iter_border_walker& b) const
00681         {
00682                 this_type tmp(*this);
00683                 tmp += b;
00684                 return tmp;
00685         }
00686         inline this_type operator -(const iter_border_walker& b) const
00687         {
00688                 this_type tmp(*this);
00689                 tmp -= b;
00690                 return tmp;
00691         }
00692 
00693         // difference is not implemented.
00694         // this is a non-random_access iterator.
00695 
00696         //copy same type iterator
00697         this_type& operator=(const this_type& it)
00698         {
00699                 ir = it.ir;
00700                 iter = it.iter;
00701                 it1 = it.it1;
00702                 sizes = it.sizes;
00703                 size0 = it.size0;
00704                 size1 = it.size1;
00705                 diffs = it.diffs;
00706                 diff0 = it.diff0;
00707                 diff1 = it.diff1;
00708                 steps = it.steps;
00709                 step0 = it.step0;
00710                 step1 = it.step1;
00711                 back = it.back;
00712                 back0 = it.back0;
00713                 back1 = it.back1;
00714                 pos = it.pos;
00715                 pos0 = it.pos0;
00716                 pos1 = it.pos1;
00717 
00718                 return *this;
00719         }
00720         //copy relevant type iterator
00721         template<class J, bool C, int S>
00722         this_type& operator=(const subarray_iterator_type<T, J,
00723                                                 BEST_IT, true, C, S>& it)
00724         {
00725                 ir = it.ir;
00726                 iter = it.iter;
00727                 it1 = it.it1;
00728                 sizes = it.sizes;
00729                 size0 = it.size0;
00730                 size1 = it.size1;
00731                 diffs = it.diffs;
00732                 diff0 = it.diff0;
00733                 diff1 = it.diff1;
00734                 steps = it.steps;
00735                 step0 = it.step0;
00736                 step1 = it.step1;
00737                 back = it.back;
00738                 back0 = it.back0;
00739                 back1 = it.back1;
00740                 pos = it.pos;
00741                 pos0 = it.pos0;
00742                 pos1 = it.pos1;
00743 
00744                 return *this;
00745         }
00746 
00747         bool operator==(const this_type& it) const { return (ir == it.ir); }
00748         bool operator!=(const this_type& it) const { return (ir != it.ir); }
00749         bool operator<(const this_type& it) const
00750         {
00751                 size_t p = pos.length() - 1;
00752                 // we will also consider the last pos in the < operator
00753                 // which is not a pos in a valid dimension but rather
00754                 // a 'pseudo pos' indicating if we are after the array data. (end).
00755                 for(; p > 0; p--) if(pos[p] < it.pos[p]) return true;
00756                 return pos0 < it.pos0;
00757         }
00758         bool operator>(const this_type& it) const
00759         {
00760                 // same as above
00761                 size_t p = pos.length() - 1;
00762                 for(; p > 0; p--) if(pos[p] > it.pos[p]) return true;
00763                 return pos0 > it.pos0;
00764         }
00765         bool operator<=(const this_type& it) const
00766                 { return this_type::operator<(it) || this_type::operator==(it); }
00767         bool operator>=(const this_type& it) const
00768                 { return this_type::operator>(it) || this_type::operator==(it); }
00769 
00770 };
00771 
00772 
00773 }; /*namespace data */
00774 
00775 }; /*namespace ivl*/
00776 
00777 #endif // IVL_ARRAY_SPECIALIZATION_DETAILS_SUBARRAY_ITERATOR_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations