BWAPI
|
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