Milena (Olena)
User documentation 2.0a Id
|
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_INTERNAL_COMPLEX_RELATIVE_ITERATOR_SEQUENCE_HH 00027 # define MLN_TOPO_INTERNAL_COMPLEX_RELATIVE_ITERATOR_SEQUENCE_HH 00028 00033 00034 # include <iosfwd> 00035 00036 # include <mln/metal/equal.hh> 00037 00038 # include <mln/core/concept/iterator.hh> 00039 # include <mln/topo/complex.hh> 00040 00041 00042 namespace mln 00043 { 00044 00045 namespace topo 00046 { 00047 00048 namespace internal 00049 { 00050 00051 template <typename I1> 00052 struct const_face_type_ 00053 { 00054 typedef typename I1::face_type F_; 00055 typedef const F_& ret; 00056 }; 00057 00058 00068 template <typename I1, typename I2, typename E> 00069 class complex_relative_iterator_sequence : public Iterator<E> 00070 { 00071 typedef complex_relative_iterator_sequence<I1, I2, E> self_; 00072 00073 public: 00075 typedef typename I1::center_type center_type; 00077 typedef typename I1::face_type face_type; 00078 00081 complex_relative_iterator_sequence(); 00082 template <typename Fref> 00083 complex_relative_iterator_sequence(const Fref& f_ref); 00085 00089 void center_at(const center_type& c); 00090 00092 bool is_valid() const; 00094 void invalidate(); 00095 00097 void start(); 00099 void next_(); 00101 00105 operator typename const_face_type_<I1>::ret () const; 00106 // that is: const face_type& 00108 00109 protected: 00111 void update_(); 00112 00113 protected: 00115 I1 iter1_; 00117 I2 iter2_; 00118 00120 face_type f_; 00121 }; 00122 00123 00125 template <typename I1, typename I2, typename E> 00126 inline 00127 std::ostream& 00128 operator<<(std::ostream& ostr, 00129 const complex_relative_iterator_sequence<I1, I2, E>& p); 00130 00131 00132 00133 # ifndef MLN_INCLUDE_ONLY 00134 00135 template <typename I1, typename I2, typename E> 00136 inline 00137 complex_relative_iterator_sequence<I1, I2, E>::complex_relative_iterator_sequence() 00138 { 00139 // Ensure I1 and I2 are compatible. 00140 mlc_equal(typename I1::face_type, typename I2::face_type)::check(); 00141 00142 invalidate(); 00143 } 00144 00145 template <typename I1, typename I2, typename E> 00146 template <typename Fref> 00147 inline 00148 complex_relative_iterator_sequence<I1, I2, E>::complex_relative_iterator_sequence(const Fref& f_ref) 00149 { 00150 // Ensure I1 and I2 are compatible. 00151 mlc_equal(typename I1::face_type, typename I2::face_type)::check(); 00152 00153 center_at(f_ref); 00154 } 00155 00156 template <typename I1, typename I2, typename E> 00157 inline 00158 void 00159 complex_relative_iterator_sequence<I1, I2, E>::center_at(const center_type& c) 00160 { 00161 iter1_.center_at(c); 00162 iter2_.center_at(c); 00163 invalidate(); 00164 } 00165 00166 template <typename I1, typename I2, typename E> 00167 inline 00168 bool 00169 complex_relative_iterator_sequence<I1, I2, E>::is_valid() const 00170 { 00171 return iter1_.is_valid() || iter2_.is_valid(); 00172 } 00173 00174 template <typename I1, typename I2, typename E> 00175 inline 00176 void 00177 complex_relative_iterator_sequence<I1, I2, E>::invalidate() 00178 { 00179 iter1_.invalidate(); 00180 iter2_.invalidate(); 00181 } 00182 00183 template <typename I1, typename I2, typename E> 00184 inline 00185 void 00186 complex_relative_iterator_sequence<I1, I2, E>::start() 00187 { 00188 iter1_.start(); 00189 iter2_.start(); 00190 if (is_valid()) 00191 update_(); 00192 } 00193 00194 template <typename I1, typename I2, typename E> 00195 inline 00196 void 00197 complex_relative_iterator_sequence<I1, I2, E>::next_() 00198 { 00199 /* Iterator<E>::next() ensures that either iter1_ or iter2_ 00200 (or both) are valid before executing this method. */ 00201 if (iter1_.is_valid()) 00202 iter1_.next(); 00203 else 00204 iter2_.next(); 00205 if (is_valid()) 00206 update_(); 00207 } 00208 00209 template <typename I1, typename I2, typename E> 00210 inline 00211 void 00212 complex_relative_iterator_sequence<I1, I2, E>::update_() 00213 { 00214 mln_precondition(is_valid()); 00215 if (iter1_.is_valid()) 00216 f_ = iter1_; 00217 else 00218 f_ = iter2_; 00219 } 00220 00221 template <typename I1, typename I2, typename E> 00222 inline 00223 complex_relative_iterator_sequence<I1, I2, E>::operator typename const_face_type_<I1>::ret () const 00224 { 00225 return f_; 00226 } 00227 00228 00229 template <typename I1, typename I2, typename E> 00230 inline 00231 std::ostream& 00232 operator<<(std::ostream& ostr, 00233 const complex_relative_iterator_sequence<I1, I2, E>& p) 00234 { 00235 return ostr << typename I1::face_type(p); 00236 } 00237 00238 # endif // ! MLN_INCLUDE_ONLY 00239 00240 } // end of namespace mln::topo::internal 00241 00242 } // end of namespace mln::topo 00243 00244 } // end of namespace mln 00245 00246 #endif // ! MLN_TOPO_INTERNAL_COMPLEX_RELATIVE_ITERATOR_SEQUENCE_HH