BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/HalfedgeDS_iterator_adaptor.h
Go to the documentation of this file.
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 //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines