00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00026 #ifndef MLN_TOPO_FACE_ITER_HH 00027 # define MLN_TOPO_FACE_ITER_HH 00028 00033 00034 # include <mln/topo/internal/complex_set_iterator_base.hh> 00035 # include <mln/topo/face.hh> 00036 # include <mln/topo/face_iter.hh> 00037 00038 // FIXME: Factor a bit more? (Using complex_set_iterator_base.) 00039 00040 00041 namespace mln 00042 { 00043 00044 namespace topo 00045 { 00046 00047 // Forward declarations. 00048 template <unsigned D> class complex; 00049 00050 namespace internal 00051 { 00052 00053 template <typename F, typename E> 00054 class complex_set_iterator_base; 00055 00056 } // end of namespace mln::topo::internal 00057 00058 00059 /*-------------------------. 00060 | topo::face_fwd_iter<D>. | 00061 `-------------------------*/ 00062 00067 // 00068 template <unsigned D> 00069 class face_fwd_iter 00070 : public internal::complex_set_iterator_base< topo::face<D>, face_fwd_iter<D> > 00071 { 00072 // Tech note: we use topo::face to help g++-2.95. 00073 private: 00074 typedef face_fwd_iter<D> self_; 00075 typedef internal::complex_set_iterator_base< topo::face<D>, self_ > super_; 00076 00077 public: 00078 using super_::is_valid; 00079 using super_::invalidate; 00080 00081 public: 00084 face_fwd_iter(); 00085 // FIXME: See comment in internal::complex_set_iterator_base's 00086 // default ctor. 00087 face_fwd_iter(complex<D>& c); 00089 00093 void start(); 00095 void next_(); 00097 00098 private: 00099 using super_::f_; 00100 }; 00101 00102 00103 /*-------------------------. 00104 | topo::face_bkd_iter<D>. | 00105 `-------------------------*/ 00106 00110 // 00111 template <unsigned D> 00112 class face_bkd_iter 00113 : public internal::complex_set_iterator_base< topo::face<D>, face_bkd_iter<D> > 00114 { 00115 // Tech note: we use topo::face to help g++-2.95. 00116 private: 00117 typedef face_bkd_iter<D> self_; 00118 typedef internal::complex_set_iterator_base< topo::face<D>, self_ > super_; 00119 00120 public: 00121 using super_::is_valid; 00122 using super_::invalidate; 00123 00124 public: 00127 face_bkd_iter(); 00128 // FIXME: See comment in internal::complex_set_iterator_base's 00129 // default ctor. 00130 face_bkd_iter(complex<D>& c); 00132 00136 void start(); 00138 void next_(); 00140 00141 private: 00142 using super_::f_; 00143 }; 00144 00145 00146 00147 # ifndef MLN_INCLUDE_ONLY 00148 00149 /*-------------------------. 00150 | topo::face_fwd_iter<D>. | 00151 `-------------------------*/ 00152 00153 template <unsigned D> 00154 inline 00155 face_fwd_iter<D>::face_fwd_iter() 00156 : super_() 00157 { 00158 } 00159 00160 template <unsigned D> 00161 inline 00162 face_fwd_iter<D>::face_fwd_iter(complex<D>& c) 00163 : super_(c) 00164 { 00165 set_cplx(c); 00166 mln_postcondition(!is_valid()); 00167 } 00168 00169 template <unsigned D> 00170 inline 00171 void 00172 face_fwd_iter<D>::start() 00173 { 00174 f_.set_n(0u); 00175 f_.set_face_id(0u); 00176 } 00177 00178 template <unsigned D> 00179 inline 00180 void 00181 face_fwd_iter<D>::next_() 00182 { 00183 if (is_valid()) 00184 { 00185 if (f_.face_id() + 1 < f_.cplx().nfaces_of_dim(f_.n())) 00186 f_.inc_face_id(); 00187 else 00188 // Start to iterate on the faces of the next dimension if 00189 // possible. 00190 if (f_.n() <= D) 00191 { 00192 f_.inc_n(); 00193 f_.set_face_id(0u); 00194 } 00195 else 00196 invalidate(); 00197 } 00198 } 00199 00200 00201 /*-------------------------. 00202 | topo::face_bkd_iter<D>. | 00203 `-------------------------*/ 00204 00205 template <unsigned D> 00206 inline 00207 face_bkd_iter<D>::face_bkd_iter() 00208 : super_() 00209 { 00210 } 00211 00212 template <unsigned D> 00213 inline 00214 face_bkd_iter<D>::face_bkd_iter(complex<D>& c) 00215 : super_(c) 00216 { 00217 set_cplx(c); 00218 mln_postcondition(!is_valid()); 00219 } 00220 00221 template <unsigned D> 00222 inline 00223 void 00224 face_bkd_iter<D>::start() 00225 { 00226 f_.set_n(D); 00227 f_.set_face_id(f_.cplx().template nfaces_of_static_dim<D>() - 1); 00228 } 00229 00230 template <unsigned D> 00231 inline 00232 void 00233 face_bkd_iter<D>::next_() 00234 { 00235 if (is_valid()) 00236 { 00237 if (f_.face_id() > 0) 00238 f_.dec_face_id(); 00239 else 00240 // Start to iterate on the faces of the previous dimension 00241 // if it exists. 00242 if (f_.n() > 0) 00243 { 00244 f_.dec_n(); 00245 f_.set_face_id(f_.cplx().nfaces_of_dim(f_.n()) - 1); 00246 } 00247 else 00248 invalidate(); 00249 } 00250 } 00251 00252 # endif // ! MLN_INCLUDE_ONLY 00253 00254 } // end of namespace mln::topo 00255 00256 } // end of namespace mln 00257 00258 #endif // ! MLN_TOPO_FACE_ITER_HH