Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 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_MORPHO_TREE_PROPAGATE_IF_HH 00027 # define MLN_MORPHO_TREE_PROPAGATE_IF_HH 00028 00032 00033 00034 # include <mln/morpho/tree/data.hh> 00035 # include <mln/morpho/tree/propagate_node.hh> 00036 00037 # include <mln/data/fill.hh> 00038 # include <mln/pw/all.hh> 00039 00040 namespace mln 00041 { 00042 00043 namespace morpho 00044 { 00045 00046 namespace tree 00047 { 00048 00049 template <typename W> 00050 struct way_of_propagation : Object< W > { protected: way_of_propagation() {}; }; 00051 struct desc_propagation : way_of_propagation <desc_propagation> {}; 00052 struct asc_propagation : way_of_propagation <asc_propagation> {}; 00053 00065 template <typename T, typename A, typename P, typename W> 00066 inline 00067 void 00068 propagate_if(const T& tree, 00069 Image<A>& a_, 00070 const way_of_propagation<W>& prop_, 00071 const Function_v2b<P>& pred_, 00072 const mln_value(A)& v); 00073 00075 template <typename T, typename A, typename P> 00076 inline 00077 void 00078 propagate_if(const T& tree, 00079 Image<A>& a_, 00080 const desc_propagation& prop_, 00081 const Function_v2b<P>& pred_); 00082 00094 template <typename T, typename A, typename W> 00095 inline 00096 void 00097 propagate_if_value(const T& tree, 00098 Image<A>& a_, 00099 const way_of_propagation<W>& prop_, 00100 const mln_value(A)& v, 00101 const mln_value(A)& v_prop); 00102 00104 template <typename T, typename A, typename W> 00105 inline 00106 void 00107 propagate_if_value(const T& tree, 00108 Image<A>& a_, 00109 const way_of_propagation<W>& prop, 00110 const mln_value(A)& v); 00111 00112 00113 00114 00115 # ifndef MLN_INCLUDE_ONLY 00116 00117 namespace internal 00118 { 00119 template <typename T, typename A, typename P> 00120 bool check_propagate_if(const T& t, 00121 const A& a, 00122 const asc_propagation& prop, 00123 const P& pred, 00124 const mln_value(A)& v) 00125 { 00126 (void) prop; 00127 mln_node_piter(T) n(t); 00128 for_all(n) 00129 if (pred(n) && a(t.parent(n)) != v) 00130 return false; 00131 return true; 00132 } 00133 00134 template <typename T, typename A, typename P> 00135 bool check_propagate_if(const T& t, 00136 const A& a, 00137 const desc_propagation& prop, 00138 const P& pred, 00139 const mln_value(A)& v) 00140 { 00141 (void) prop; 00142 mln_node_piter(T) n(t); 00143 for_all(n) 00144 if (a(n) != v && pred(t.parent(n))) 00145 return false; 00146 return true; 00147 } 00148 00149 template <typename T, typename A, typename P> 00150 bool check_propagate_if(const T& t, 00151 const A& a, 00152 const desc_propagation& prop, 00153 const P& pred) 00154 { 00155 (void) prop; 00156 mln_node_piter(T) n(t); 00157 for_all(n) 00158 if (a(n) != a(t.parent(n)) && pred(t.parent(n))) 00159 return false; 00160 return true; 00161 } 00162 00163 template <typename T, typename A, typename P> 00164 inline 00165 void 00166 propagate_if(const T& tree, 00167 A& a, 00168 const desc_propagation& prop, 00169 const P& pred, 00170 const mln_value(A)& v) 00171 { 00172 (void) prop; 00173 00174 mln_precondition(a.is_valid()); 00175 mln_precondition(tree.f().domain() == a.domain()); 00176 00177 mln_ch_value(typename T::function, bool) mark; 00178 initialize(mark, tree.f()); 00179 mln::data::fill(mark, false); 00180 00181 mln_dn_node_piter(T) n(tree); 00182 for_all(n) 00183 if (mark(tree.parent(n))) 00184 { 00185 a(n) = v; 00186 mark(n) = true; 00187 } 00188 else if (pred(n)) 00189 mark(n) = true; 00190 mln_postcondition(check_propagate_if(tree, a, prop, pred, v)); 00191 } 00192 00193 template <typename T, typename A, typename P> 00194 inline 00195 void 00196 propagate_if(const T& tree, 00197 A& a, 00198 const desc_propagation& prop, 00199 const P& pred) 00200 { 00201 (void) prop; 00202 00203 mln_precondition(a.is_valid()); 00204 mln_precondition(tree.f().domain() == a.domain()); 00205 00206 mln_ch_value(typename T::function, bool) mark; 00207 initialize(mark, tree.f()); 00208 mln::data::fill(mark, false); 00209 00210 mln_dn_node_piter(T) n(tree); 00211 for_all(n) 00212 if (mark(tree.parent(n))) 00213 { 00214 a(n) = a(tree.parent(n)); 00215 mark(n) = true; 00216 } 00217 else if (pred(n)) 00218 mark(n) = true; 00219 mln_postcondition(check_propagate_if(tree, a, prop, pred)); 00220 } 00221 00222 00223 template <typename T, typename A, typename P> 00224 inline 00225 void 00226 propagate_if(const T& tree, 00227 A& a, 00228 const asc_propagation& prop, 00229 const P& pred, 00230 const mln_value(A)& v) 00231 { 00232 (void) prop; 00233 00234 mln_precondition(a.is_valid()); 00235 mln_precondition(tree.f().domain() == a.domain()); 00236 00237 mln_ch_value(typename T::function, bool) mark; 00238 initialize(mark, tree.f()); 00239 mln::data::fill(mark, false); 00240 00241 mln_up_node_piter(T) n(tree); 00242 for_all(n) 00243 if (mark(n)) 00244 { 00245 a(n) = v; 00246 mark(tree.parent(n)) = true; 00247 } 00248 else if (pred(n)) 00249 mark(tree.parent(n)) = true; 00250 00251 mln_postcondition(check_propagate_if(tree, a, prop, pred, v)); 00252 } 00253 00254 } // end of namespace mln::morpho::tree::internal 00255 00256 00257 // Facades 00258 00259 template <typename T, typename A, typename W> 00260 inline 00261 void 00262 propagate_if_value(const T& tree, 00263 Image<A>& a_, 00264 const way_of_propagation<W>& prop_, 00265 const mln_value(A)& v, 00266 const mln_value(A)& v_prop) 00267 { 00268 A& a = exact(a_); 00269 const W& prop = exact(prop_); 00270 00271 internal::propagate_if(tree, a, prop, pw::value(a) == pw::cst(v), v_prop); 00272 } 00273 00274 00275 template <typename T, typename A, typename W> 00276 inline 00277 void 00278 propagate_if_value(const T& tree, 00279 Image<A>& a_, 00280 const way_of_propagation<W>& prop_, 00281 const mln_value(A)& v) 00282 { 00283 A& a = exact(a_); 00284 const W& prop = exact(prop_); 00285 00286 internal::propagate_if(tree, a, prop, pw::value(a) == pw::cst(v), v); 00287 } 00288 00289 00290 template <typename T, typename A, typename P, typename W> 00291 inline 00292 void 00293 propagate_if(const T& tree, 00294 Image<A>& a_, 00295 const way_of_propagation<W>& prop_, 00296 const Function_v2b<P>& pred_, 00297 const mln_value(A)& v) 00298 { 00299 A& a = exact(a_); 00300 const W& prop = exact(prop_); 00301 const P& pred = exact(pred_); 00302 00303 internal::propagate_if(tree, a, prop, pred, v); 00304 } 00305 00306 00307 template <typename T, typename A, typename P> 00308 inline 00309 void 00310 propagate_if(const T& tree, 00311 Image<A>& a_, 00312 const desc_propagation& prop, 00313 const Function_v2b<P>& pred_) 00314 { 00315 A& a = exact(a_); 00316 const P& pred = exact(pred_); 00317 00318 internal::propagate_if(tree, a, prop, pred); 00319 } 00320 00321 #endif // ! MLN_INCLUDE_ONLY 00322 00323 00324 } // end of namespace mln::morpho::tree 00325 00326 } // end of namespace mln::morpho 00327 00328 } // end of namespace mln 00329 00330 #endif // ! MLN_MORPHO_TREE_PROPAGATE_IF_HH