BWAPI
|
00001 // Copyright (c) 1997 Utrecht University (The Netherlands), 00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany), 00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg 00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria), 00005 // and Tel-Aviv University (Israel). All rights reserved. 00006 // 00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public License as 00009 // published by the Free Software Foundation; version 2.1 of the License. 00010 // See the file LICENSE.LGPL distributed with CGAL. 00011 // 00012 // Licensees holding a valid commercial license may use this file in 00013 // accordance with the commercial license agreement provided with the software. 00014 // 00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 // 00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Circulator/include/CGAL/circulator.h $ 00019 // $Id: circulator.h 46436 2008-10-23 10:29:50Z afabri $ 00020 // 00021 // 00022 // Author(s) : Lutz Kettner <kettner@inf.ethz.ch> 00023 00024 #ifndef CGAL_CIRCULATOR_H 00025 #define CGAL_CIRCULATOR_H 00026 00027 #include <CGAL/basic.h> 00028 #include <cstddef> 00029 #include <functional> 00030 #include <iterator> 00031 #include <CGAL/circulator_bases.h> 00032 00033 // These are name redefinitions for backwards compatibility 00034 // with the pre iterator-traits style adaptors. 00035 00036 #define Forward_container_from_circulator \ 00037 Container_from_circulator 00038 #define Bidirectional_container_from_circulator \ 00039 Container_from_circulator 00040 #define Random_access_container_from_circulator \ 00041 Container_from_circulator 00042 00043 #define Forward_circulator_from_iterator \ 00044 Circulator_from_iterator 00045 #define Forward_const_circulator_from_iterator \ 00046 Circulator_from_iterator 00047 #define Bidirectional_circulator_from_iterator \ 00048 Circulator_from_iterator 00049 #define Bidirectional_const_circulator_from_iterator \ 00050 Circulator_from_iterator 00051 #define Random_access_circulator_from_iterator \ 00052 Circulator_from_iterator 00053 #define Random_access_const_circulator_from_iterator \ 00054 Circulator_from_iterator 00055 00056 #define Forward_circulator_from_container \ 00057 Circulator_from_container 00058 #define Bidirectional_circulator_from_container \ 00059 Circulator_from_container 00060 #define Random_access_circulator_from_container \ 00061 Circulator_from_container 00062 00063 #define Forward_const_circulator_from_container \ 00064 Const_circulator_from_container 00065 #define Bidirectional_const_circulator_from_container \ 00066 Const_circulator_from_container 00067 #define Random_access_const_circulator_from_container \ 00068 Const_circulator_from_container 00069 00070 00071 00072 CGAL_BEGIN_NAMESPACE 00073 00074 template <class C> 00075 struct I_Circulator_traits { 00076 typedef Iterator_tag category; 00077 }; 00078 00079 template <> 00080 struct I_Circulator_traits<Forward_circulator_tag> { 00081 typedef Circulator_tag category; 00082 }; 00083 00084 template <> 00085 struct I_Circulator_traits<Bidirectional_circulator_tag> { 00086 typedef Circulator_tag category; 00087 }; 00088 00089 template <> 00090 struct I_Circulator_traits<Random_access_circulator_tag> { 00091 typedef Circulator_tag category; 00092 }; 00093 00094 // Circulator_size_traits are used by general adaptors for 00095 // iterators and circulators. For example the N_step_adaptor 00096 // works for iterators as well as for circulators. Circulators 00097 // need a local type called size_type which is not needed for 00098 // iterators. But a general adaptor has to declare this type 00099 // in any case and the following Circulator_size_traits helps 00100 // in this case. It declares size_type to be std::size_t for 00101 // iterators and to be C::size_type for any circulator C. 00102 template <class Tag, class IC> 00103 struct I_Circulator_size_traits { 00104 typedef std::size_t size_type; 00105 }; 00106 00107 template <class C> 00108 struct I_Circulator_size_traits< Forward_circulator_tag, C> { 00109 typedef typename C::size_type size_type; 00110 }; 00111 template <class C> 00112 struct I_Circulator_size_traits< Bidirectional_circulator_tag, C> { 00113 typedef typename C::size_type size_type; 00114 }; 00115 template <class C> 00116 struct I_Circulator_size_traits< Random_access_circulator_tag, C> { 00117 typedef typename C::size_type size_type; 00118 }; 00119 00120 template <class CCtg> 00121 struct I_Iterator_from_circulator_traits { 00122 typedef CCtg iterator_category; 00123 }; 00124 00125 template <> 00126 struct I_Iterator_from_circulator_traits< Forward_circulator_tag> { 00127 typedef std::forward_iterator_tag iterator_category; 00128 }; 00129 00130 template <> 00131 struct I_Iterator_from_circulator_traits< 00132 Bidirectional_circulator_tag> { 00133 typedef std::bidirectional_iterator_tag iterator_category; 00134 }; 00135 00136 template <> 00137 struct I_Iterator_from_circulator_traits< 00138 Random_access_circulator_tag> { 00139 typedef std::random_access_iterator_tag iterator_category; 00140 }; 00141 00142 template <class ICtg> 00143 struct I_Circulator_from_iterator_traits { 00144 typedef ICtg iterator_category; 00145 }; 00146 00147 template <> 00148 struct I_Circulator_from_iterator_traits< std::forward_iterator_tag> { 00149 typedef Forward_circulator_tag iterator_category; 00150 }; 00151 00152 template <> 00153 struct I_Circulator_from_iterator_traits<std::bidirectional_iterator_tag> { 00154 typedef Bidirectional_circulator_tag iterator_category; 00155 }; 00156 00157 template <> 00158 struct I_Circulator_from_iterator_traits<std::random_access_iterator_tag> { 00159 typedef Random_access_circulator_tag iterator_category; 00160 }; 00161 00162 template <class C> 00163 struct Circulator_traits { 00164 typedef std::iterator_traits<C> traits; 00165 typedef typename traits::iterator_category ICAT; 00166 typedef I_Circulator_traits<ICAT> C_traits; 00167 typedef typename C_traits::category category; 00168 00169 typedef I_Iterator_from_circulator_traits<ICAT> Ic_traits; 00170 typedef typename Ic_traits::iterator_category iterator_category; 00171 00172 typedef I_Circulator_from_iterator_traits<ICAT> Ci_traits; 00173 typedef typename Ci_traits::iterator_category circulator_category; 00174 }; 00175 00176 template <class C> 00177 typename Circulator_traits<C>::category 00178 query_circulator_or_iterator( const C&) { 00179 typedef typename Circulator_traits<C>::category category; 00180 return category(); 00181 } 00182 /* A function that asserts a specific compile time tag */ 00183 /* forcing its two arguments to have equal type. */ 00184 /* It is encapsulated with #ifdef since it will be defined also elsewhere. */ 00185 #ifndef CGAL_ASSERT_COMPILE_TIME_TAG 00186 #define CGAL_ASSERT_COMPILE_TIME_TAG 1 00187 template <class Base> 00188 struct I_Assert_tag_class { 00189 void match_compile_time_tag( const Base&) const {} 00190 }; 00191 template< class Tag, class Derived> 00192 inline void Assert_compile_time_tag( const Tag&, const Derived& b) { 00193 I_Assert_tag_class<Tag> x; 00194 x.match_compile_time_tag(b); 00195 } 00196 #endif 00197 00198 template <class C> inline 00199 void Assert_circulator( const C &) { 00200 typedef typename Circulator_traits<C>::category category; 00201 Assert_compile_time_tag( Circulator_tag(), category()); 00202 } 00203 template <class I> inline 00204 void Assert_iterator( const I &) { 00205 typedef typename Circulator_traits<I>::category category; 00206 Assert_compile_time_tag( Iterator_tag(), category()); 00207 } 00208 template <class I> inline 00209 void Assert_input_category( const I &/*i*/) { 00210 typedef typename std::iterator_traits<I>::iterator_category category; 00211 Assert_compile_time_tag( std::input_iterator_tag(), 00212 category()); 00213 } 00214 00215 template <class I> inline 00216 void Assert_output_category( const I &/*i*/) { 00217 typedef typename std::iterator_traits<I>::iterator_category category; 00218 Assert_compile_time_tag( std::output_iterator_tag(), 00219 category()); 00220 } 00221 template <class IC> inline 00222 void Assert_forward_category( const IC &/*ic*/) { 00223 typedef typename std::iterator_traits<IC>::iterator_category category; 00224 Assert_compile_time_tag( std::forward_iterator_tag(), 00225 category()); 00226 } 00227 template <class IC> inline 00228 void Assert_bidirectional_category( const IC &/*ic*/) { 00229 typedef typename std::iterator_traits<IC>::iterator_category category; 00230 Assert_compile_time_tag( std::bidirectional_iterator_tag(), 00231 category()); 00232 } 00233 template <class IC> inline 00234 void Assert_random_access_category( const IC &/*ic*/) { 00235 typedef typename std::iterator_traits<IC>::iterator_category category; 00236 Assert_compile_time_tag( std::random_access_iterator_tag(), 00237 category()); 00238 } 00239 00240 // The assert at-least-category functions use the following 00241 // functions to resolve properly. Note the proper order of the 00242 // arguments: 1st is the to be type, 2nd is the actual type. 00243 inline void I_Has_to_be_at_least( std::input_iterator_tag, 00244 std::input_iterator_tag){} 00245 inline void I_Has_to_be_at_least( std::input_iterator_tag, 00246 std::forward_iterator_tag){} 00247 inline void I_Has_to_be_at_least( std::input_iterator_tag, 00248 std::bidirectional_iterator_tag){} 00249 inline void I_Has_to_be_at_least( std::input_iterator_tag, 00250 std::random_access_iterator_tag){} 00251 00252 inline void I_Has_to_be_at_least( std::output_iterator_tag, 00253 std::output_iterator_tag){} 00254 inline void I_Has_to_be_at_least( std::output_iterator_tag, 00255 std::forward_iterator_tag){} 00256 inline void I_Has_to_be_at_least( std::output_iterator_tag, 00257 std::bidirectional_iterator_tag){} 00258 inline void I_Has_to_be_at_least( std::output_iterator_tag, 00259 std::random_access_iterator_tag){} 00260 00261 inline void I_Has_to_be_at_least( std::forward_iterator_tag, 00262 std::forward_iterator_tag){} 00263 inline void I_Has_to_be_at_least( std::forward_iterator_tag, 00264 std::bidirectional_iterator_tag){} 00265 inline void I_Has_to_be_at_least( std::forward_iterator_tag, 00266 std::random_access_iterator_tag){} 00267 00268 inline void I_Has_to_be_at_least( std::bidirectional_iterator_tag, 00269 std::bidirectional_iterator_tag){} 00270 inline void I_Has_to_be_at_least( std::bidirectional_iterator_tag, 00271 std::random_access_iterator_tag){} 00272 00273 inline void I_Has_to_be_at_least( std::random_access_iterator_tag, 00274 std::random_access_iterator_tag){} 00275 00276 // The is-at-least assertions. 00277 template <class I> inline 00278 void Assert_is_at_least_input_category( const I& /*i*/) { 00279 typedef typename std::iterator_traits<I>::iterator_category category; 00280 I_Has_to_be_at_least( std::input_iterator_tag(), 00281 category()); 00282 } 00283 template <class I> inline 00284 void Assert_is_at_least_output_category( const I& /*i*/) { 00285 typedef typename std::iterator_traits<I>::iterator_category category; 00286 I_Has_to_be_at_least( std::output_iterator_tag(), 00287 category()); 00288 } 00289 template <class IC> inline 00290 void Assert_is_at_least_forward_category( const IC& /*ic*/) { 00291 typedef typename std::iterator_traits<IC>::iterator_category category; 00292 I_Has_to_be_at_least( std::forward_iterator_tag(), 00293 category()); 00294 } 00295 template <class IC> inline 00296 void Assert_is_at_least_bidirectional_category( const IC& /*ic*/) { 00297 typedef typename std::iterator_traits<IC>::iterator_category category; 00298 I_Has_to_be_at_least( std::bidirectional_iterator_tag(), 00299 category()); 00300 } 00301 template <class IC> inline 00302 void Assert_is_at_least_random_access_category( const IC& /*ic*/) { 00303 typedef typename std::iterator_traits<IC>::iterator_category category; 00304 I_Has_to_be_at_least( std::random_access_iterator_tag(), 00305 category()); 00306 } 00307 00308 template< class C> inline 00309 bool I_is_empty_range( const C& c1, const C&, Circulator_tag){ 00310 return c1 == NULL; 00311 } 00312 00313 template< class I> inline 00314 bool I_is_empty_range( const I& i1, const I& i2, Iterator_tag){ 00315 return i1 == i2; 00316 } 00317 00318 template< class IC> inline 00319 bool is_empty_range( const IC& ic1, const IC& ic2){ 00320 // is `true' if the range [`ic1, ic2') is empty, `false' otherwise. 00321 // Precondition: `T' is either a circulator or an iterator type. The 00322 // range [`ic1, ic2') is valid. 00323 typedef typename Circulator_traits<IC>::category category; 00324 return I_is_empty_range( ic1, ic2, category()); 00325 } 00326 00327 struct Circulator_or_iterator_tag {}; // any circulator or iterator. 00328 00329 inline 00330 Circulator_or_iterator_tag 00331 check_circulator_or_iterator( Circulator_tag ){ 00332 return Circulator_or_iterator_tag(); 00333 } 00334 inline 00335 Circulator_or_iterator_tag 00336 check_circulator_or_iterator( Iterator_tag ){ 00337 return Circulator_or_iterator_tag(); 00338 } 00339 00340 template< class IC> inline 00341 void Assert_circulator_or_iterator( const IC &){ 00342 typedef typename Circulator_traits<IC>::category category; 00343 Assert_compile_time_tag( 00344 Circulator_or_iterator_tag(), 00345 check_circulator_or_iterator( category())); 00346 } 00347 00348 #define CGAL_For_all( ic1, ic2) \ 00349 for ( bool _circ_loop_flag = ! ::CGAL::is_empty_range( ic1, ic2); \ 00350 _circ_loop_flag; \ 00351 _circ_loop_flag = ((++ic1) != (ic2)) ) 00352 00353 #define CGAL_For_all_backwards( ic1, ic2) \ 00354 for ( bool _circ_loop_flag = ! ::CGAL::is_empty_range( ic1, ic2); \ 00355 _circ_loop_flag; \ 00356 _circ_loop_flag = ((ic1) != (--ic2)) ) 00357 00358 00359 00360 template <class C> inline 00361 typename C::size_type 00362 I_min_circulator_size( const C& c) { 00363 Assert_circulator(c); 00364 Assert_random_access_category(c); 00365 typedef typename C::size_type size_type; 00366 size_type n = 0; 00367 if ( c != NULL) { 00368 n = (c-1) - c + 1; 00369 CGAL_assertion(n > 0); 00370 } 00371 return n; 00372 } 00373 00374 template <class C> 00375 typename C::size_type 00376 I_circulator_size( const C& c, Forward_circulator_tag) { 00377 // Simply count. 00378 if ( c == NULL) 00379 return 0; 00380 typedef typename C::size_type size_type; 00381 size_type n = 0; 00382 C d = c; 00383 do { 00384 ++n; 00385 ++d; 00386 } while( c != d); 00387 return n; 00388 } 00389 template <class C> inline 00390 typename C::size_type 00391 I_circulator_size( const C& c, Bidirectional_circulator_tag) { 00392 return I_circulator_size( c, Forward_circulator_tag()); 00393 } 00394 template <class C> inline 00395 typename C::size_type 00396 I_circulator_size( const C& c, Random_access_circulator_tag) { 00397 return I_min_circulator_size( c.min_circulator()); 00398 } 00399 00400 template <class C> inline 00401 typename C::size_type 00402 circulator_size( const C& c) { 00403 typedef typename std::iterator_traits<C>::iterator_category category; 00404 return I_circulator_size( c, 00405 category()); 00406 } 00407 template <class C> 00408 typename C::difference_type 00409 I_circulator_distance( C c, const C& d, Forward_circulator_tag) { 00410 // Simply count. 00411 if ( c == NULL) 00412 return 0; 00413 typedef typename C::difference_type difference_type; 00414 difference_type n = 0; 00415 do { 00416 ++n; 00417 } while( ++c != d); 00418 return n; 00419 } 00420 template <class C> inline 00421 typename C::difference_type 00422 I_circulator_distance( const C& c, const C& d, 00423 Bidirectional_circulator_tag) { 00424 return I_circulator_distance( c, d, Forward_circulator_tag()); 00425 } 00426 template <class C> inline 00427 typename C::difference_type 00428 I_circulator_distance( const C& c, const C& d, 00429 Random_access_circulator_tag) { 00430 typedef typename C::difference_type difference_type; 00431 typedef typename C::size_type size_type; 00432 if ( d - c > 0) 00433 return (d - c); 00434 return difference_type( size_type( I_min_circulator_size( 00435 c.min_circulator()))) - (c-d); 00436 } 00437 00438 template <class C> inline 00439 typename C::difference_type 00440 circulator_distance( const C& c, const C& d) { 00441 typedef typename std::iterator_traits<C>::iterator_category category; 00442 return I_circulator_distance( c, d, 00443 category()); 00444 } 00445 template <class C> inline 00446 typename std::iterator_traits<C>::difference_type 00447 I_iterator_distance(const C& c1, const C& c2, Circulator_tag) { 00448 return circulator_distance( c1, c2); 00449 } 00450 00451 template <class I> inline 00452 typename std::iterator_traits<I>::difference_type 00453 I_iterator_distance(const I& i1, const I& i2, Iterator_tag) { 00454 return std::distance( i1, i2); 00455 } 00456 00457 template <class IC> inline 00458 typename std::iterator_traits<IC>::difference_type 00459 iterator_distance(const IC& ic1, const IC& ic2) { 00460 typedef typename Circulator_traits<IC>::category category; 00461 return I_iterator_distance( ic1, ic2, category()); 00462 } 00463 template <class C> inline 00464 C I_get_min_circulator( C c, Forward_circulator_tag) { 00465 return c; 00466 } 00467 template <class C> inline 00468 C I_get_min_circulator( C c, Bidirectional_circulator_tag) { 00469 return c; 00470 } 00471 template <class C> inline 00472 C I_get_min_circulator( C c, Random_access_circulator_tag) { 00473 return c.min_circulator(); 00474 } 00475 template <class C> inline 00476 C get_min_circulator( C c) { 00477 typedef std::iterator_traits<C> Traits; 00478 typedef typename Traits::iterator_category Category; 00479 return I_get_min_circulator( c, Category()); 00480 } 00481 template<class I, class U> inline 00482 I non_negative_mod(I n, U m) { 00483 CGAL_precondition( m > 0); 00484 #if (-1 % 3) > 0 00485 n = n % m; 00486 #else 00487 if (n < 0) 00488 n = m - 1 - (( - n - 1) % m) ; 00489 else 00490 n = n % m; 00491 #endif 00492 CGAL_postcondition( n >= 0); 00493 return n; 00494 } 00495 00496 template < class C, class Ref, class Ptr> 00497 class Iterator_from_circulator { 00498 private: 00499 // The m_anchor is normalized to be a minimal circulator. 00500 const C* m_anchor; 00501 C current; 00502 int m_winding; 00503 00504 typedef std::iterator_traits<C> I_traits; 00505 typedef typename I_traits::iterator_category I_Iter_cat; 00506 typedef I_Iterator_from_circulator_traits<I_Iter_cat> I__traits; 00507 00508 public: 00509 // 00510 // TYPES 00511 00512 typedef C Circulator; 00513 typedef Iterator_from_circulator<C,Ref,Ptr> Self; 00514 00515 typedef typename I__traits::iterator_category iterator_category; 00516 00517 typedef typename C::value_type value_type; 00518 typedef typename C::difference_type difference_type; 00519 typedef typename C::size_type size_type; 00520 typedef typename C::reference reference; 00521 typedef typename C::pointer pointer; 00522 00523 // 00524 // CREATION 00525 00526 Iterator_from_circulator() : m_anchor(0), m_winding(0) {} 00527 00528 Iterator_from_circulator( const C* circ, int n) 00529 : m_anchor( circ), current( *circ), m_winding(n) {} 00530 00531 // Allow construction from Iterator_from_circulator with 00532 // assignment compatible circulator CC: 00533 template <class CC, class CREF, class CPTR> 00534 Iterator_from_circulator( 00535 const Iterator_from_circulator<CC,CREF,CPTR>& c) 00536 : m_anchor( c.anchor()), current( c.current_circulator()), 00537 m_winding(c.winding()) {} 00538 00539 // 00540 // OPERATIONS 00541 00542 bool operator==( const Self& i) const { 00543 CGAL_assertion( m_anchor == i.m_anchor); // same anchor? 00544 return ( current == i.current) && ( m_winding == i.m_winding); 00545 } 00546 bool operator!=( const Self& i) const { 00547 return !(*this == i); 00548 } 00549 Ref operator*() const { 00550 CGAL_assertion( m_anchor != NULL); 00551 CGAL_assertion( current != NULL); 00552 return Ref(*current); 00553 } 00554 Ptr operator->() const { 00555 CGAL_assertion( m_anchor != NULL); 00556 CGAL_assertion( current != NULL); 00557 return Ptr(current.operator->()); 00558 } 00559 Self& operator++() { 00560 CGAL_assertion( m_anchor != NULL); 00561 CGAL_assertion( current != NULL); 00562 ++current; 00563 if ( current == *m_anchor) 00564 ++m_winding; 00565 return *this; 00566 } 00567 Self operator++(int) { 00568 Self tmp = *this; 00569 ++*this; 00570 return tmp; 00571 } 00572 Self& operator--() { 00573 CGAL_assertion( m_anchor != NULL); 00574 CGAL_assertion( current != NULL); 00575 if ( current == *m_anchor) 00576 --m_winding; 00577 --current; 00578 return *this; 00579 } 00580 Self operator--(int) { 00581 Self tmp = *this; 00582 --*this; 00583 return tmp; 00584 } 00585 Self& operator+=( difference_type n) { 00586 CGAL_assertion( m_anchor != NULL); 00587 CGAL_assertion( current != NULL); 00588 if ( n < 0 && current == *m_anchor) // We are leaving the anchor. 00589 --m_winding; 00590 current += n; 00591 if ( n > 0 && current == *m_anchor) // Back again at the anchor. 00592 ++m_winding; 00593 return *this; 00594 } 00595 Self operator+( difference_type n) const { 00596 Self tmp = *this; 00597 return tmp += n; 00598 } 00599 Self& operator-=( difference_type n) { 00600 return operator+=( -n); 00601 } 00602 Self operator-( difference_type n) const { 00603 Self tmp = *this; 00604 return tmp += -n; 00605 } 00606 difference_type operator-( const Self& i) const { 00607 CGAL_assertion( m_anchor != NULL); 00608 CGAL_assertion( current != NULL); 00609 CGAL_assertion( m_anchor == i.m_anchor); 00610 if ( m_winding != i.m_winding) { 00611 difference_type s = I_min_circulator_size( *m_anchor); 00612 return (current - *m_anchor) - (i.current - *m_anchor) 00613 + s * (m_winding - i.m_winding); 00614 } 00615 return (current - *m_anchor) - (i.current - *m_anchor); 00616 } 00617 00618 Ref operator[](difference_type n) const { 00619 Self tmp = *this; 00620 tmp += n; 00621 return tmp.operator*(); 00622 } 00623 bool operator<( const Self& i) const { 00624 CGAL_assertion( m_anchor != NULL); 00625 CGAL_assertion( current != NULL); 00626 CGAL_assertion( m_anchor == i.m_anchor); 00627 return ( (m_winding < i.m_winding) 00628 || ( (m_winding == i.m_winding) 00629 && (current - *m_anchor) < (i.current - *m_anchor) 00630 ) 00631 ); 00632 } 00633 bool operator> ( const Self& i) const { return i < *this; } 00634 bool operator<=( const Self& i) const { return !(i < *this); } 00635 bool operator>=( const Self& i) const { return !(*this < i); } 00636 00637 const C* anchor() const { return m_anchor;} 00638 int winding() const { return m_winding;} 00639 Circulator current_circulator() const { return current;} 00640 }; 00641 00642 template < class Dist, class C, class Ref, class Ptr> 00643 Iterator_from_circulator<C,Ref,Ptr> 00644 operator+( Dist n, const Iterator_from_circulator<C,Ref,Ptr>& circ) { 00645 Iterator_from_circulator<C,Ref,Ptr> tmp = circ; 00646 return tmp += n; 00647 } 00648 00649 template < class C > 00650 class Container_from_circulator { 00651 private: 00652 C anchor; 00653 public: 00654 // 00655 // CREATION 00656 00657 Container_from_circulator() {} 00658 // the resulting iterators will have a singular value. 00659 00660 Container_from_circulator(const C& c) 00661 // The anchor is normalized to be a minimal circulator. 00662 : anchor(get_min_circulator(c)) {} 00663 // the resulting iterators will have a singular value if the 00664 // circulator `c' is singular. 00665 00666 // 00667 // TYPES 00668 00669 typedef C Circulator; 00670 00671 typedef typename C::value_type value_type; 00672 typedef value_type& reference; 00673 typedef const value_type& const_reference; 00674 typedef value_type* pointer; 00675 typedef const value_type* const_pointer; 00676 typedef typename C::size_type size_type; 00677 typedef typename C::difference_type difference_type; 00678 00679 typedef Iterator_from_circulator< C, reference, pointer> 00680 iterator; 00681 typedef Iterator_from_circulator< C, const_reference, const_pointer> 00682 const_iterator; 00683 // 00684 // OPERATIONS 00685 00686 iterator begin() { 00687 // the start iterator. 00688 return iterator( &anchor, 0); 00689 } 00690 const_iterator begin() const { 00691 // the start const iterator. 00692 return const_iterator( &anchor, 0); 00693 } 00694 iterator end() { 00695 // the past-the-end iterator. 00696 return anchor == NULL ? iterator( &anchor, 0) 00697 : iterator( &anchor, 1); 00698 } 00699 const_iterator end() const { 00700 // the past-the-end const iterator. 00701 return anchor == NULL ? const_iterator( &anchor, 0) 00702 : const_iterator( &anchor, 1); 00703 } 00704 }; 00705 template < class Ctnr> 00706 class Circulator_from_container { 00707 public: 00708 // TYPES 00709 00710 typedef Circulator_from_container<Ctnr> Self; 00711 typedef Ctnr Container; 00712 typedef typename Ctnr::iterator iterator; 00713 typedef typename Ctnr::value_type value_type; 00714 typedef typename Ctnr::reference reference; 00715 typedef value_type* pointer; 00716 typedef typename Ctnr::size_type size_type; 00717 typedef typename Ctnr::difference_type difference_type; 00718 00719 typedef std::iterator_traits<iterator> ITraits; 00720 typedef typename ITraits::iterator_category Icategory; 00721 typedef I_Circulator_from_iterator_traits<Icategory> CTraits; 00722 typedef typename CTraits::iterator_category iterator_category; 00723 00724 private: 00725 Ctnr* ctnr; 00726 iterator i; 00727 00728 public: 00729 // CREATION 00730 00731 Circulator_from_container() : ctnr(NULL) {} 00732 Circulator_from_container( Ctnr* c) : ctnr(c), i(c->begin()) {} 00733 Circulator_from_container( Ctnr* c, iterator j) : ctnr(c), i(j) {} 00734 00735 // Gnu-bug workaround: define operator= explicitly. 00736 Self& operator=( const Self& c) { 00737 ctnr = c.ctnr; 00738 i = c.i; 00739 return *this; 00740 } 00741 00742 // OPERATIONS 00743 00744 bool operator==( Nullptr_t p) const { 00745 CGAL_assertion( p == NULL); 00746 return (ctnr == NULL) || (ctnr->begin() == ctnr->end()); 00747 } 00748 bool operator!=( Nullptr_t p) const { return !(*this == p); } 00749 bool operator==( const Self& c) const { return i == c.i; } 00750 bool operator!=( const Self& c) const { return !(*this == c); } 00751 reference operator*() const { 00752 CGAL_assertion( ctnr != NULL); 00753 CGAL_assertion( i != ctnr->end()); 00754 return *i; 00755 } 00756 pointer operator->() const { 00757 CGAL_assertion( ctnr != NULL); 00758 CGAL_assertion( i != ctnr->end()); 00759 return i.operator->(); 00760 } 00761 Self& operator++() { 00762 CGAL_assertion( ctnr != NULL); 00763 CGAL_assertion( i != ctnr->end()); 00764 ++i; 00765 if ( i == ctnr->end()) 00766 i = ctnr->begin(); 00767 return *this; 00768 } 00769 Self operator++(int) { 00770 Self tmp= *this; 00771 ++*this; 00772 return tmp; 00773 } 00774 Self& operator--() { 00775 CGAL_assertion( ctnr != NULL); 00776 CGAL_assertion( i != ctnr->end()); 00777 if ( i == ctnr->begin()) 00778 i = ctnr->end(); 00779 --i; 00780 return *this; 00781 } 00782 Self operator--(int) { 00783 Self tmp = *this; 00784 --*this; 00785 return tmp; 00786 } 00787 Self& operator+=( difference_type n) { 00788 CGAL_assertion( ctnr != NULL); 00789 CGAL_assertion( i != ctnr->end()); 00790 typename Ctnr::difference_type j = i - ctnr->begin(); 00791 typename Ctnr::difference_type size = ctnr->size(); 00792 CGAL_assertion( j >= 0); 00793 CGAL_assertion( size >= 0); 00794 j = non_negative_mod( j + n, size); 00795 CGAL_assertion( j >= 0); 00796 CGAL_assertion( j < size); 00797 i = ctnr->begin() + j; 00798 return *this; 00799 } 00800 Self operator+( difference_type n) const { 00801 Self tmp = *this; 00802 return tmp += n; 00803 } 00804 Self& operator-=( difference_type n) { return operator+=( -n); } 00805 Self operator-( difference_type n) const { 00806 Self tmp = *this; 00807 return tmp += -n; 00808 } 00809 difference_type operator-( const Self& c) const { 00810 CGAL_assertion( ctnr != NULL); 00811 CGAL_assertion( c.ctnr != NULL); 00812 return i - c.i; 00813 } 00814 reference operator[]( difference_type n) const { 00815 Self tmp = *this; 00816 tmp += n; 00817 return *tmp; 00818 } 00819 iterator current_iterator() const { return i;} 00820 Self min_circulator() const { return Self(ctnr); } 00821 Ctnr* container() const { return ctnr; } 00822 }; 00823 00824 template <class Ctnr> 00825 inline 00826 Circulator_from_container<Ctnr> 00827 operator+( typename Circulator_from_container<Ctnr>::difference_type n, 00828 const Circulator_from_container<Ctnr>& c) { 00829 Circulator_from_container<Ctnr> tmp = c; 00830 return tmp += n; 00831 } 00832 00833 template < class Ctnr> 00834 class Const_circulator_from_container { 00835 public: 00836 // TYPES 00837 00838 typedef Const_circulator_from_container<Ctnr> Self; 00839 typedef Circulator_from_container<Ctnr> Mutable; 00840 typedef Ctnr Container; 00841 typedef typename Ctnr::const_iterator const_iterator; 00842 typedef typename Ctnr::value_type value_type; 00843 typedef typename Ctnr::const_reference reference; 00844 typedef const value_type* pointer; 00845 typedef typename Ctnr::size_type size_type; 00846 typedef typename Ctnr::difference_type difference_type; 00847 00848 typedef std::iterator_traits<const_iterator> ITraits; 00849 typedef typename ITraits::iterator_category Icategory; 00850 typedef I_Circulator_from_iterator_traits<Icategory> CTraits; 00851 typedef typename CTraits::iterator_category iterator_category; 00852 00853 private: 00854 const Ctnr* ctnr; 00855 const_iterator i; 00856 00857 public: 00858 // CREATION 00859 00860 Const_circulator_from_container() : ctnr(NULL) {} 00861 Const_circulator_from_container( const Ctnr* c) 00862 : ctnr(c), i(c->begin()) {} 00863 Const_circulator_from_container( const Ctnr* c, const_iterator j) 00864 : ctnr(c), i(j) {} 00865 Const_circulator_from_container( const Mutable& c) 00866 : ctnr( c.container()), i( c.current_iterator()) {} 00867 00868 // Gnu-bug workaround: define operator= explicitly. 00869 Self& operator=( const Self& c) { 00870 ctnr = c.ctnr; 00871 i = c.i; 00872 return *this; 00873 } 00874 00875 // OPERATIONS 00876 00877 bool operator==( Nullptr_t p) const { 00878 CGAL_assertion( p == NULL); 00879 return (ctnr == NULL) || (ctnr->begin() == ctnr->end()); 00880 } 00881 bool operator!=( Nullptr_t p) const { return !(*this == p); } 00882 bool operator==( const Self& c) const { return i == c.i; } 00883 bool operator!=( const Self& c) const { return !(*this == c); } 00884 reference operator*() const { 00885 CGAL_assertion( ctnr != NULL); 00886 CGAL_assertion( i != ctnr->end()); 00887 return *i; 00888 } 00889 pointer operator->() const { 00890 CGAL_assertion( ctnr != NULL); 00891 CGAL_assertion( i != ctnr->end()); 00892 return i.operator->(); 00893 } 00894 Self& operator++() { 00895 CGAL_assertion( ctnr != NULL); 00896 CGAL_assertion( i != ctnr->end()); 00897 ++i; 00898 if ( i == ctnr->end()) 00899 i = ctnr->begin(); 00900 return *this; 00901 } 00902 Self operator++(int) { 00903 Self tmp= *this; 00904 ++*this; 00905 return tmp; 00906 } 00907 Self& operator--() { 00908 CGAL_assertion( ctnr != NULL); 00909 CGAL_assertion( i != ctnr->end()); 00910 if ( i == ctnr->begin()) 00911 i = ctnr->end(); 00912 --i; 00913 return *this; 00914 } 00915 Self operator--(int) { 00916 Self tmp = *this; 00917 --*this; 00918 return tmp; 00919 } 00920 Self& operator+=( difference_type n) { 00921 CGAL_assertion( ctnr != NULL); 00922 CGAL_assertion( i != ctnr->end()); 00923 typename Ctnr::difference_type j = i - ctnr->begin(); 00924 typename Ctnr::difference_type size = ctnr->size(); 00925 CGAL_assertion( j >= 0); 00926 CGAL_assertion( size >= 0); 00927 j = non_negative_mod( j + n, size); 00928 CGAL_assertion( j >= 0); 00929 CGAL_assertion( j < size); 00930 i = ctnr->begin() + j; 00931 return *this; 00932 } 00933 Self operator+( difference_type n) const { 00934 Self tmp = *this; 00935 return tmp += n; 00936 } 00937 Self& operator-=( difference_type n) { return operator+=( -n); } 00938 Self operator-( difference_type n) const { 00939 Self tmp = *this; 00940 return tmp += -n; 00941 } 00942 difference_type operator-( const Self& c) const { 00943 CGAL_assertion( ctnr != NULL); 00944 CGAL_assertion( c.ctnr != NULL); 00945 return i - c.i; 00946 } 00947 reference operator[]( difference_type n) const { 00948 Self tmp = *this; 00949 tmp += n; 00950 return *tmp; 00951 } 00952 const_iterator current_iterator() const { return i;} 00953 Self min_circulator() const { return Self(ctnr); } 00954 const Ctnr* container() const { return ctnr; } 00955 }; 00956 00957 template <class Ctnr> 00958 inline 00959 Const_circulator_from_container<Ctnr> 00960 operator+( typename Const_circulator_from_container<Ctnr>::difference_type n, 00961 const Const_circulator_from_container<Ctnr>& c) { 00962 Const_circulator_from_container<Ctnr> tmp = c; 00963 return tmp += n; 00964 } 00965 00966 00967 // Note: Tt, Ss, and Dd are here for backwards compatibility, they are 00968 // not used. 00969 template < class I, class Tt = int, class Ss = int, class Dd = int> 00970 class Circulator_from_iterator { 00971 public: 00972 // TYPES 00973 00974 typedef Circulator_from_iterator<I,Tt,Ss,Dd> Self; 00975 typedef I iterator; 00976 typedef std::iterator_traits<iterator> Traits; 00977 00978 typedef typename Traits::value_type value_type; 00979 typedef std::size_t size_type; 00980 typedef typename Traits::difference_type difference_type; 00981 typedef typename Traits::reference reference; 00982 typedef typename Traits::pointer pointer; 00983 00984 typedef typename Traits::iterator_category Icategory; 00985 typedef I_Circulator_from_iterator_traits<Icategory> CTraits; 00986 typedef typename CTraits::iterator_category iterator_category; 00987 00988 private: 00989 I m_begin; 00990 I m_end; 00991 I current; 00992 bool empty; 00993 00994 // The following static iterator is needed so that we have a value 00995 // that can be uniquely compared (the default constructed one can be 00996 // different each time). 00997 //static I null_iterator; 00998 00999 public: 01000 // CREATION 01001 01002 Circulator_from_iterator() : m_begin(), 01003 m_end(), 01004 current(), 01005 empty( true) 01006 {} 01007 01008 Circulator_from_iterator( const I& bgn, const I& end) 01009 : m_begin(bgn), m_end(end), current(bgn), empty(bgn==end) {} 01010 01011 Circulator_from_iterator( const I& bgn, const I& end, const I& cur) 01012 : m_begin(bgn), m_end(end), current(cur), empty(bgn==end) {} 01013 01014 Circulator_from_iterator( const Self& c, const I& cur) 01015 : m_begin( c.m_begin), m_end( c.m_end), current(cur), empty(c.empty) {} 01016 01017 01018 template <class II, class A1, class A2, class A3> 01019 // Allow construction from Circulator_from_iterator with 01020 // assignment compatible iterator II: 01021 Circulator_from_iterator( 01022 const Circulator_from_iterator<II,A1,A2,A3>& ii) 01023 : m_begin( ii.begin()), m_end( ii.end()), 01024 current(ii.current_iterator()), empty(ii.begin()==ii.end()) {} 01025 01026 // 01027 // OPERATIONS 01028 01029 bool operator==( Nullptr_t p) const { 01030 CGAL_assertion( p == NULL); 01031 return empty; 01032 } 01033 bool operator!=( Nullptr_t p) const { return !(*this == p); } 01034 bool operator==( const Self& c) const { return current == c.current;} 01035 bool operator!=( const Self& c) const { return !(*this == c); } 01036 reference operator*() const { 01037 CGAL_assertion( current != m_end); 01038 return *current; 01039 } 01040 pointer operator->() const { 01041 CGAL_assertion( current != m_end); 01042 return &(*current); 01043 } 01044 Self& operator++() { 01045 CGAL_assertion( current != m_end); 01046 ++current; 01047 if ( current == m_end) 01048 current = m_begin; 01049 return *this; 01050 } 01051 Self operator++(int) { 01052 Self tmp= *this; 01053 ++*this; 01054 return tmp; 01055 } 01056 Self& operator--() { 01057 CGAL_assertion( current != m_end); 01058 if ( current == m_begin) 01059 current = m_end; 01060 --current; 01061 return *this; 01062 } 01063 Self operator--(int) { 01064 Self tmp = *this; 01065 --*this; 01066 return tmp; 01067 } 01068 Self& operator+=( difference_type n) { 01069 CGAL_assertion( current != m_end); 01070 difference_type i = current - m_begin; 01071 difference_type size = m_end - m_begin; 01072 CGAL_assertion( i >= 0); 01073 CGAL_assertion( size >= 0); 01074 i = non_negative_mod( i + n, size); 01075 CGAL_assertion( i >= 0); 01076 CGAL_assertion( i < size); 01077 current = m_begin + i; 01078 return *this; 01079 } 01080 Self operator+( difference_type n) const { 01081 Self tmp = *this; 01082 return tmp += n; 01083 } 01084 Self& operator-=( difference_type n) { return operator+=( -n); } 01085 Self operator-( difference_type n) const { 01086 Self tmp = *this; 01087 return tmp += -n; 01088 } 01089 difference_type operator-( const Self& i) const { 01090 CGAL_assertion((m_begin == i.m_begin) && (m_end == i.m_end)); 01091 return current - i.current; 01092 } 01093 reference operator[](difference_type n) const { 01094 Self tmp = *this; 01095 tmp += n; 01096 return tmp.operator*(); 01097 } 01098 iterator begin() const { return m_begin;} 01099 iterator end() const { return m_end;} 01100 iterator current_iterator() const { return current;} 01101 Self min_circulator() const { return Self( m_begin, m_end); } 01102 }; 01103 01104 //template < class I, class T, class Size, class Dist> 01105 //I Circulator_from_iterator< I, T, Size, Dist>::null_iterator = I(); 01106 01107 template < class D, class I, class T, class Size, class Dist> inline 01108 Circulator_from_iterator< I, T, Size, Dist> 01109 operator+( D n, const 01110 Circulator_from_iterator< I, T, Size, Dist>& circ) { 01111 Circulator_from_iterator< I, T, Size, Dist> 01112 tmp = circ; 01113 return tmp += Dist(n); 01114 } 01115 01116 CGAL_END_NAMESPACE 01117 01118 #endif // CGAL_CIRCULATOR_H //