ivl 679
|
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