00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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
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
00200
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 }
00241
00242 }
00243
00244 }
00245
00246 #endif // ! MLN_TOPO_INTERNAL_COMPLEX_RELATIVE_ITERATOR_SEQUENCE_HH