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_ALGEBRAIC_FACE_HH
00027 # define MLN_TOPO_ALGEBRAIC_FACE_HH
00028
00032
00033 #include <mln/topo/face.hh>
00034 #include <mln/topo/algebraic_n_face.hh>
00035
00036
00037 namespace mln
00038 {
00039
00040 namespace topo
00041 {
00042
00043
00044 template <unsigned D> class complex;
00045 template <unsigned N, unsigned D> class n_face;
00046 template <unsigned N, unsigned D> class face_data;
00047
00048
00049
00050
00051
00052
00058 template <unsigned D>
00059 struct algebraic_face : public face<D>
00060 {
00061 typedef face<D> super_;
00062
00063 public:
00064
00065 typedef complex<D> complex_type;
00066
00068 algebraic_face();
00070 algebraic_face(complex<D>& complex, unsigned n, unsigned face_id,
00071 bool sign);
00073 algebraic_face(const face<D>& f, bool sign);
00074
00076 template <unsigned N>
00077 algebraic_face(const algebraic_n_face<N, D>& f);
00078
00082 bool sign() const;
00084 void set_sign(bool sign);
00086
00087 private:
00089 bool sign_;
00090 };
00091
00092
00094 template <unsigned D>
00095 algebraic_face<D>
00096 make_algebraic_face(const face<D>& f, bool sign);
00097
00098
00101 template <unsigned D>
00102 algebraic_face<D>
00103 operator-(const face<D>& f);
00104
00105 template <unsigned D>
00106 algebraic_face<D>
00107 operator-(const algebraic_face<D>& f);
00109
00110
00113
00118 template <unsigned D>
00119 bool operator==(const algebraic_face<D>& lhs,
00120 const algebraic_face<D>& rhs);
00121
00126 template <unsigned D>
00127 bool operator!=(const algebraic_face<D>& lhs,
00128 const algebraic_face<D>& rhs);
00129
00138 template <unsigned D>
00139 bool operator< (const algebraic_face<D>& lhs,
00140 const algebraic_face<D>& rhs);
00141
00143
00144
00146 template <unsigned D>
00147 std::ostream&
00148 operator<<(std::ostream& ostr, const algebraic_face<D>& f);
00149
00150
00151
00152 # ifndef MLN_INCLUDE_ONLY
00153
00154 template <unsigned D>
00155 inline
00156 algebraic_face<D>::algebraic_face()
00157 : super_(), sign_(true)
00158 {
00159 }
00160
00161 template <unsigned D>
00162 inline
00163 algebraic_face<D>::algebraic_face(complex<D>& c, unsigned n,
00164 unsigned face_id, bool sign)
00165 : super_(c, n, face_id), sign_(sign)
00166 {
00167
00168 mln_precondition(n <= D);
00169 }
00170
00171 template <unsigned D>
00172 inline
00173 algebraic_face<D>::algebraic_face(const face<D>& f, bool sign)
00174 : super_(f), sign_(sign)
00175 {
00176
00177 mln_precondition(f.n() <= D);
00178 }
00179
00180 template <unsigned D>
00181 template <unsigned N>
00182 inline
00183 algebraic_face<D>::algebraic_face(const algebraic_n_face<N, D>& f)
00184 : super_(f), sign_(f.sign())
00185 {
00186
00187 metal::bool_< N <= D >::check();
00188 }
00189
00190
00191 template <unsigned D>
00192 inline
00193 bool
00194 algebraic_face<D>::sign() const
00195 {
00196 return sign_;
00197 }
00198
00199 template <unsigned D>
00200 inline
00201 void
00202 algebraic_face<D>::set_sign(bool sign)
00203 {
00204 sign_ = sign;
00205 }
00206
00207
00208 template <unsigned D>
00209 algebraic_face<D>
00210 make_algebraic_face(const face<D>& f, bool sign)
00211 {
00212 return algebraic_face<D>(f, sign);
00213 }
00214
00215
00216 template <unsigned D>
00217 algebraic_face<D>
00218 operator-(const face<D>& f)
00219 {
00220 return algebraic_face<D>(f, false);
00221 }
00222
00223 template <unsigned D>
00224 algebraic_face<D>
00225 operator-(const algebraic_face<D>& f)
00226 {
00227 algebraic_face<D> f2(f);
00228 f2.set_sign(!f.sign());
00229 return f2;
00230 }
00231
00232
00233 template <unsigned D>
00234 inline
00235 bool
00236 operator==(const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
00237 {
00238
00239 mln_precondition(lhs.cplx() == rhs.cplx());
00240 return
00241 lhs.n() == rhs.n() &&
00242 lhs.face_id() == rhs.face_id() &&
00243 lhs.sign() == rhs.sign();
00244 }
00245
00246 template <unsigned D>
00247 inline
00248 bool
00249 operator!=(const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
00250 {
00251
00252 mln_precondition(lhs.cplx() == rhs.cplx());
00253 return !(lhs == rhs);
00254 }
00255
00256 template <unsigned D>
00257 inline
00258 bool
00259 operator< (const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
00260 {
00261
00262 mln_precondition(lhs.cplx() == rhs.cplx());
00263
00264 mln_precondition(lhs.n() == rhs.n());
00265 return lhs.face_id() < rhs.face_id();
00266 }
00267
00268
00269 template <unsigned D>
00270 inline
00271 std::ostream&
00272 operator<<(std::ostream& ostr, const algebraic_face<D>& f)
00273 {
00274 return
00275 ostr << "(cplx = " << f.cplx().addr() << ", dim = " << f.n()
00276 << ", id = " << f.face_id() << ", sign = " << f.sign()<< ')';
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 namespace internal
00290 {
00291
00292 template <unsigned N, unsigned D>
00293 std::vector< algebraic_face<D> >
00294 lower_dim_adj_faces_if_dim_matches_<N, D>::operator()(const face<D>& face)
00295 {
00296 metal::bool_< (N <= D) >::check();
00297 metal::bool_< (N > 1) >::check();
00298
00299 if (face.n() == N)
00300 {
00301 face_data<N, D>& data = face.template data<N>();
00302 std::vector< algebraic_n_face<N - 1, D> > lower_dim_faces =
00303 data.lower_dim_faces_;
00304 std::vector< topo::algebraic_face<D> > result;
00305 for (typename std::vector< algebraic_n_face<N - 1, D> >::const_iterator f =
00306 lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f)
00307 result.push_back(*f);
00308 return result;
00309 }
00310 else
00311 return internal::lower_dim_adj_faces_if_dim_matches_<N - 1, D>()(face);
00312 }
00313
00314 template <unsigned D>
00315 std::vector< algebraic_face<D> >
00316 lower_dim_adj_faces_if_dim_matches_<1, D>::operator()(const face<D>& face)
00317 {
00320 mln_precondition(face.n() == 1);
00321 face_data<1, D>& data = face.template data<1>();
00322 std::vector< algebraic_n_face<0, D> > lower_dim_faces =
00323 data.lower_dim_faces_;
00324 std::vector< topo::algebraic_face<D> > result;
00325 for (typename std::vector< algebraic_n_face<0, D> >::const_iterator f =
00326 lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f)
00327 result.push_back(*f);
00328 return result;
00329 }
00330
00331 template <unsigned N, unsigned D>
00332 std::vector< algebraic_face<D> >
00333 higher_dim_adj_faces_if_dim_matches_<N, D>::operator()(const face<D>& face)
00334 {
00335 metal::bool_< (N < D) >::check();
00336
00337 if (face.n() == N)
00338 {
00339 face_data<N, D>& data = face.template data<N>();
00340 std::vector< algebraic_n_face<N + 1, D> > higher_dim_faces =
00341 data.higher_dim_faces_;
00342 std::vector< topo::algebraic_face<D> > result;
00343 for (typename std::vector< algebraic_n_face<N + 1, D> >::const_iterator f =
00344 higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f)
00345 result.push_back(*f);
00346 return result;
00347 }
00348 else
00349 return
00350 internal::higher_dim_adj_faces_if_dim_matches_<N - 1, D>()(face);
00351 }
00352
00353 template <unsigned D>
00354 std::vector< algebraic_face<D> >
00355 higher_dim_adj_faces_if_dim_matches_<0, D>::operator()(const face<D>& face)
00356 {
00359 mln_precondition(face.n() == 0);
00360 face_data<0, D>& data = face.template data<0>();
00361 std::vector< algebraic_n_face<1, D> > higher_dim_faces =
00362 data.higher_dim_faces_;
00363 std::vector< topo::algebraic_face<D> > result;
00364 for (typename std::vector< algebraic_n_face<1, D> >::const_iterator f =
00365 higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f)
00366 result.push_back(*f);
00367 return result;
00368 }
00369
00370 }
00371
00372
00373 # endif // ! MLN_INCLUDE_ONLY
00374
00375 }
00376
00377 }
00378
00379 #endif // ! MLN_TOPO_ALGEBRAIC_FACE_HH