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