|
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/HalfedgeDS/include/CGAL/HalfedgeDS_iterator_adaptor.h $ 00019 // $Id: HalfedgeDS_iterator_adaptor.h 35787 2007-01-24 17:16:05Z spion $ 00020 // 00021 // 00022 // Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de> 00023 00024 #ifndef CGAL_HALFEDGEDS_ITERATOR_ADAPTOR_H 00025 #define CGAL_HALFEDGEDS_ITERATOR_ADAPTOR_H 1 00026 00027 #include <iterator> 00028 00029 CGAL_BEGIN_NAMESPACE 00030 00031 // The iterator identity adaptor will be used for the HDS implementations 00032 // that are based on STL (or other) container classes which do not 00033 // guarantee that the default construction of its iterator gives always 00034 // the same singular value (i.e. something like NULL). This adaptor 00035 // assumes that iterator traits are fully supported. It works for all 00036 // kinds of iterators, from input iterators to random access iterators. 00037 // It does no longer require that these iterators have a constructor 00038 // accepting zero as an argument (e.g. a pointer). This approach has 00039 // failed with the KCC compiler (Kai's C++). 00040 00041 // Instead, we rely now on a static local variable. Static variables are 00042 // first of all zero-initialized (Section 3.6.2), which guarantees that 00043 // pointers and such are set to zero even if the construtor does not 00044 // initialize them (Section 8.5). With static variables, the order of 00045 // initialization could be critical, if the initialization of one 00046 // requires another one to be initialized already (I have not seen such a 00047 // design for iterator yet, but who knows, maybe if reference counting 00048 // come into play). If global static variables are in different 00049 // compilation units, there order of initialization is unspecified. 00050 // However, if the static variable is a local variable, the 00051 // initialization happens before the surrounding function is called if 00052 // the type is a POD, otherwise the initialization happens when the 00053 // control flow passes through the declaration of the static variable the 00054 // first time (Section 6.7), which costs performance but makes it safe 00055 // for weird static initialization situations. Usually the std::vector 00056 // class uses a plain C-pointer as iterator, which would be a POD and 00057 // thus efficient. However, the std::list iterators might not be POD's if 00058 // they define their own copy contructor. This is the case for 00059 // std::list::iterator of the current SGI STL, but not for the 00060 // std::list::const_iterator, which is a funny side-effect of having 00061 // only a single class for both and a constructor that allows iterator to 00062 // const_iterator conversions. The bottom line is, std::vector is fine, 00063 // std::list could cost a bit performance and In_place_list might be 00064 // preferable. 00065 00066 00067 template < class I> 00068 class HalfedgeDS_iterator_adaptor { 00069 private: 00070 I nt; // The internal iterator. 00071 00072 // keep the local static variable for the null iterator 00073 // in a small inline function, optimizers might like that 00074 // better than a static function. 00075 const I& null_iterator() const { 00076 static I it = I(); // zero-initialized and a default constructor 00077 return it; 00078 } 00079 public: 00080 typedef I Iterator; 00081 typedef HalfedgeDS_iterator_adaptor<I> Self; 00082 typedef std::iterator_traits<I> Traits; 00083 typedef typename Traits::reference reference; 00084 typedef typename Traits::pointer pointer; 00085 typedef typename Traits::value_type value_type; 00086 typedef typename Traits::difference_type difference_type; 00087 typedef typename Traits::iterator_category iterator_category; 00088 00089 // CREATION 00090 // -------- 00091 // explicitly set to 0 00092 HalfedgeDS_iterator_adaptor() : nt( null_iterator()) {} 00093 HalfedgeDS_iterator_adaptor( Iterator j) : nt(j) {} // down cast 00094 00095 template < class J> 00096 HalfedgeDS_iterator_adaptor( const HalfedgeDS_iterator_adaptor<J>& j) 00097 : nt(j.iterator()) {} 00098 00099 // OPERATIONS Forward Category 00100 // --------------------------- 00101 00102 Iterator iterator() const { return nt;} 00103 00104 bool operator==( const Self& i) const { return ( nt == i.nt); } 00105 bool operator!=( const Self& i) const { return !(*this == i); } 00106 reference operator*() const { return *nt; } 00107 pointer operator->() const { return &*nt; } 00108 Self& operator++() { 00109 ++nt; 00110 return *this; 00111 } 00112 Self operator++(int) { 00113 Self tmp = *this; 00114 ++*this; 00115 return tmp; 00116 } 00117 00118 // OPERATIONS Bidirectional Category 00119 // --------------------------------- 00120 00121 Self& operator--() { 00122 --nt; 00123 return *this; 00124 } 00125 Self operator--(int) { 00126 Self tmp = *this; 00127 --*this; 00128 return tmp; 00129 } 00130 00131 // OPERATIONS Random Access Category 00132 // --------------------------------- 00133 00134 Self& operator+=( difference_type n) { 00135 nt += n; 00136 return *this; 00137 } 00138 Self operator+( difference_type n) const { 00139 Self tmp = *this; 00140 return tmp += n; 00141 } 00142 Self& operator-=( difference_type n) { return operator+=( -n); } 00143 Self operator-( difference_type n) const { 00144 Self tmp = *this; 00145 return tmp += -n; 00146 } 00147 difference_type operator-( const Self& i) const { return nt - i.nt; } 00148 reference operator[]( difference_type n) const { 00149 Self tmp = *this; 00150 tmp += n; 00151 return tmp.operator*(); 00152 } 00153 bool operator< ( const Self& i) const { return ( nt < i.nt); } 00154 bool operator> ( const Self& i) const { return i < *this; } 00155 bool operator<=( const Self& i) const { return !(i < *this); } 00156 bool operator>=( const Self& i) const { return !(*this < i); } 00157 }; 00158 00159 CGAL_END_NAMESPACE 00160 00161 // we don't need Koenig lookup here 00162 template < class D, class I> 00163 inline 00164 CGAL::HalfedgeDS_iterator_adaptor<I> 00165 operator+( D n, CGAL::HalfedgeDS_iterator_adaptor<I> i) { 00166 return i += Dist(n); 00167 } 00168 #endif // CGAL_HALFEDGEDS_ITERATOR_ADAPTOR_H // 00169 // EOF //
1.7.6.1