BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Nested_iterator.h
Go to the documentation of this file.
00001 // Copyright (c) 2003  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/STL_Extension/include/CGAL/Nested_iterator.h $
00019 // $Id: Nested_iterator.h 50431 2009-07-07 15:56:20Z afabri $
00020 // 
00021 //
00022 // Author(s)     : Menelaos Karavelas <mkaravel@cse.nd.edu>
00023 
00024 
00025 #ifndef CGAL_NESTED_ITERATOR_H
00026 #define CGAL_NESTED_ITERATOR_H
00027 
00028 #include <CGAL/iterator.h>
00029 #include <iterator>
00030 
00031 #if defined(BOOST_MSVC)
00032 #  pragma warning(push)
00033 #  pragma warning(disable:4396)
00034 #endif
00035 
00036 CGAL_BEGIN_NAMESPACE
00037 
00038 template<class It>
00039 struct Nested_iterator_traits
00040 {
00041   typedef It                                 Base_iterator;
00042   typedef typename std::iterator_traits<It>::value_type::iterator  Iterator;
00043 
00044   Iterator begin(It it) const { return it->begin(); }
00045   Iterator end(It it) const { return it->end(); }
00046 };
00047 
00048 namespace CGALi {
00049 
00050   template<class Tr>
00051   struct Emptyness_predicate : public Tr
00052   {
00053     typedef Tr            Traits;
00054 
00055     bool operator()(typename Traits::Base_iterator base_it) const
00056     {
00057       return this->begin(base_it) == this->end(base_it);
00058     }
00059 
00060     
00061   };
00062 
00063   template<class F_iterator>
00064   class FI_w_begin_end : public F_iterator
00065   {
00066   private:
00067     typedef typename F_iterator::Predicate               Predicate;
00068     typedef typename Predicate::Traits::Iterator         Iterator;
00069     typedef typename Predicate::Traits::Base_iterator    Base_iterator;
00070 
00071   public:    
00072     FI_w_begin_end() : F_iterator() {}
00073 
00074     FI_w_begin_end(Base_iterator it2,
00075                    Base_iterator it3)
00076       : F_iterator(it2, Predicate(), it3) {}
00077 
00078     Iterator begin(Base_iterator it)
00079     {
00080       return this->predicate().begin(it);
00081     }
00082 
00083     Iterator end(Base_iterator it)
00084     {
00085       return this->predicate().end(it);
00086     }
00087 
00088   };
00089 
00090 }
00091 
00092 template<class Base_it, class Tr> class Nested_iterator;
00093 
00094 template<class Base_it, class Tr>
00095 bool operator==(const Nested_iterator<Base_it,Tr>&,
00096                 const Nested_iterator<Base_it,Tr>&);
00097 
00098 template <typename Base_it,
00099           typename Tr = Nested_iterator_traits<Base_it> >
00100 class Nested_iterator
00101   : private CGALi::FI_w_begin_end<
00102   Filter_iterator<Base_it, CGALi::Emptyness_predicate<Tr> > >
00103 {
00104   typedef Nested_iterator<Base_it,Tr>           Self;
00105 public:
00106   typedef Base_it                               Base_iterator;
00107   typedef Tr                                    Traits;
00108   typedef typename Tr::Iterator                 Iterator;
00109 
00110 protected:
00111   typedef CGALi::
00112   FI_w_begin_end< Filter_iterator<Base_iterator,
00113                                   CGALi::Emptyness_predicate<Tr> > >
00114   Filter_base_iterator;
00115 
00116 private:
00117   typedef std::iterator_traits<Iterator>        ItTraits;
00118 
00119 public:
00120   typedef typename ItTraits::reference          reference;
00121   typedef typename ItTraits::pointer            pointer;
00122   typedef typename ItTraits::value_type         value_type;
00123   typedef typename ItTraits::difference_type    difference_type;
00124   typedef typename ItTraits::iterator_category  iterator_category;
00125 
00126 public:
00127   Nested_iterator() : Filter_base_iterator(), nested_it_() {}
00128   Nested_iterator(Base_iterator base_it_end,
00129                   Base_iterator base_it_cur)
00130     : Filter_base_iterator(base_it_end, base_it_cur), nested_it_()
00131   {
00132     if ( !this->is_end() ) {
00133       nested_it_ = this->begin( this->base() );
00134     }
00135   }
00136 
00137   Nested_iterator(const Self& other)
00138     : Filter_base_iterator(other)
00139   {
00140     if ( !other.is_end() )
00141       nested_it_ = other.nested_it_;
00142   }
00143 
00144   Self& operator=(const Self& other)
00145   {
00146     copy_from(other);
00147     return *this;
00148   }
00149 
00150   Self& operator++()
00151   {
00152     if ( nested_it_ != end( this->base() ) ) {
00153       ++nested_it_;
00154       if ( nested_it_ == end( this->base() ) ) {
00155         Filter_base_iterator::operator++();
00156         if ( !this->is_end() ) {
00157           nested_it_ = begin( this->base() );
00158         }
00159       }
00160     } 
00161     return *this;
00162   }
00163 
00164   Self operator++(int)
00165   {
00166     Self tmp = *this;
00167     ++(*this);
00168     return tmp;
00169   }
00170 
00171   Self& operator--()
00172   {
00173     if ( this->is_end() ) {
00174       Filter_base_iterator::operator--();
00175       nested_it_ = this->end(this->base());
00176       --nested_it_;
00177     } else {
00178       if ( nested_it_ != begin( this->base() ) ) {
00179         --nested_it_;
00180       } else {
00181         Filter_base_iterator::operator--();
00182         nested_it_ = this->end( this->base() );
00183         --nested_it_;
00184       }
00185     }
00186     return *this;
00187   }
00188 
00189   Self operator--(int)
00190   {
00191     
00192     Self tmp = *this;
00193     --(*this);
00194     return tmp;
00195   }
00196 
00197   
00198   reference  operator*()  const
00199   {
00200     return *nested_it_;
00201   }
00202 
00203   pointer    operator->() const
00204   {
00205     return nested_it_.operator->();
00206   }
00207 
00208   friend bool operator==<>(const Self&, const Self&);
00209 
00210 protected:
00211   void copy_from(const Self& other)
00212   {
00213     Filter_base_iterator::operator=(other);
00214     if ( !other.is_end() ) {
00215       nested_it_ = other.nested_it_;
00216     }
00217   }
00218 
00219 protected:
00220   Iterator       nested_it_;
00221 };
00222 
00223 
00224 
00225 
00226 
00227 template<class Base_it, class Traits>
00228 inline
00229 bool operator==(const Nested_iterator<Base_it,Traits>& it1,
00230                 const Nested_iterator<Base_it,Traits>& it2)
00231 {
00232   //  CGAL_precondition( it1.b_ == it2.b_ && it1.e_ == it2.e_ );
00233 
00234   if ( it1.base() != it2.base() ) { return false; }
00235   return it1.is_end() || ( it1.nested_it_ == it2.nested_it_ );
00236 }
00237 
00238 template<class Base_it, class Traits>
00239 inline
00240 bool operator!=(const Nested_iterator<Base_it,Traits>& it1,
00241                 const Nested_iterator<Base_it,Traits>& it2)
00242 {
00243   return !(it1 == it2);
00244 }
00245 
00246 
00247 CGAL_END_NAMESPACE
00248 
00249 #if defined(BOOST_MSVC)
00250 #  pragma warning(pop)
00251 #endif
00252 
00253 #endif // CGAL_NESTED_ITERATOR_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines