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
00027
00028 #ifndef OLENA_CORE_ABSTRACT_NEIGHBORHOOD_HH
00029 # define OLENA_CORE_ABSTRACT_NEIGHBORHOOD_HH
00030
00031 # include <mlc/type.hh>
00032 # include <oln/core/abstract/dpoint.hh>
00033 # include <oln/core/abstract/struct_elt.hh>
00034
00035 namespace oln {
00036
00037 namespace abstract {
00038 template<class Exact>
00039 struct neighborhood;
00040 }
00041
00045 template<class Exact>
00046 struct struct_elt_traits<abstract::neighborhood<Exact> >
00047 {
00048 typedef abstract::neighborhood<Exact> abstract_type;
00049 };
00050
00051 namespace abstract
00052 {
00053
00064 template<class Exact>
00065 struct neighborhood : public mlc_hierarchy::any<Exact>
00066 {
00067 typedef Exact exact_type;
00068 typedef neighborhood<Exact> self_type;
00069
00075 typedef typename struct_elt_traits<Exact>::iter_type iter_type;
00076
00077 typedef typename struct_elt_traits<Exact>::neighb_type neighb_type;
00079 typedef typename struct_elt_traits<Exact>::win_type win_type;
00081
00087 typedef typename struct_elt_traits<Exact>::dpoint_type dpoint_type;
00088
00089 typedef typename struct_elt_traits<Exact>::abstract_type abstract_type;
00091
00092 enum { dim = struct_elt_traits<Exact>::dim };
00094
00096 static std::string
00097 name()
00098 {
00099 return std::string("neighborhood<") + Exact::name() + ">";
00100 }
00101
00107 bool
00108 has(const abstract::dpoint<dpoint_type>& dp) const
00109 {
00110 return this->exact().has_(dp.exact());
00111 }
00112
00117 unsigned
00118 card() const
00119 {
00120 return this->exact().card_();
00121 }
00122
00130 bool
00131 is_centered() const
00132 {
00133 return this->exact().is_centered_();
00134 }
00135
00141 const dpoint_type
00142 dp(unsigned i) const
00143 {
00144 return this->exact()[i];
00145 }
00146
00152 bool
00153 operator==(const self_type& win) const
00154 {
00155 return this->exact().is_equal(win.exact());
00156 }
00157
00164 coord
00165 delta() const
00166 {
00167 return this->exact().get_delta();
00168 }
00169
00175 const dpoint_type
00176 operator[](unsigned i) const
00177 {
00178 return this->exact().at(i);
00179 }
00180
00187 exact_type&
00188 add(const abstract::dpoint<dpoint_type>& dp)
00189 {
00190 this->exact().add_(dp.exact());
00191 return this->exact().add_(-dp.exact());
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 protected:
00203
00210 void
00211 sym()
00212 {
00213 this->exact().sym_();
00214 }
00215
00219 neighborhood()
00220 {}
00221 };
00222
00223 }
00224
00228 template<class E>
00229 inline E
00230 inter(const abstract::neighborhood<E> &lhs,
00231 const abstract::neighborhood<E> &rhs)
00232 {
00233 E neighb;
00234 for (unsigned j = 0; j < rhs.card(); ++j)
00235 if (lhs.has(rhs.dp(j)) && ! neighb.has(rhs.dp(j)))
00236 neighb.add(rhs.dp(j));
00237 return neighb;
00238 }
00239
00243 template<class E>
00244 inline E
00245 uni(const abstract::neighborhood<E> &lhs,
00246 const abstract::neighborhood<E> &rhs)
00247 {
00248 E neighb;
00249 for (unsigned j = 0; j < rhs.card(); ++j)
00250 if (! neighb.has(rhs.dp(j)))
00251 neighb.add(rhs.dp(j));
00252 for (unsigned j = 0; j < lhs.card(); ++j)
00253 if (! neighb.has(lhs.dp(j)))
00254 neighb.add(lhs.dp(j));
00255 return neighb;
00256 }
00257
00261 template<class E>
00262 inline typename struct_elt_traits<E>::win_type
00263 mk_win_from_neighb(const abstract::neighborhood<E>& n)
00264 {
00265 typename struct_elt_traits<E>::win_type win(n.card());
00266 for (unsigned i = 0; i < n.card(); ++i)
00267 win.add(n.dp(i));
00268 return win;
00269 }
00270
00271 # define oln_neighb_type(Neighbable) \
00272 typename Neighbable::neighb_type
00273
00274
00275 }
00276
00277
00278 #endif // OLENA_CORE_ABSTRACT_NEIGHBORHOOD_HH