Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 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_CORE_CONCEPT_SITE_SET_HH 00027 # define MLN_CORE_CONCEPT_SITE_SET_HH 00028 00034 00035 # include <set> 00036 00037 # include <mln/core/concept/site_iterator.hh> 00038 # include <mln/trait/site_sets.hh> 00039 # include <mln/metal/not_equal.hh> 00040 # include <mln/metal/is_a.hh> 00041 # include <mln/metal/is_unqualif.hh> 00042 # include <mln/util/ord.hh> 00043 00044 00045 namespace mln 00046 { 00047 00048 // Forward declaration. 00049 template <typename E> struct Site_Set; 00050 00051 00053 template <> 00054 struct Site_Set<void> 00055 { 00056 typedef Object<void> super; 00057 }; 00058 00059 00064 template <typename E> 00065 struct Site_Set : public Object<E> 00066 { 00067 typedef Site_Set<void> category; 00068 00069 /* 00070 typedef element; 00071 00072 typedef site; 00073 typedef psite; 00074 00075 typedef fwd_piter; 00076 typedef bkd_piter; 00077 00078 bool has(const psite& p) const; 00079 bool is_valid() const; 00080 00081 std::size_t memory_size() const; 00082 */ 00083 00084 protected: 00085 Site_Set(); 00086 }; 00087 00088 00089 00090 namespace convert 00091 { 00092 00093 namespace over_load 00094 { 00095 00096 template <typename S, typename P, typename C_> 00097 void 00098 from_to_(const Site_Set<S>& from, std::set<P,C_>& to); 00099 00100 template <typename P, typename C_, typename S> 00101 void 00102 from_to_(const std::set<P,C_>& from, Site_Set<S>& to); 00103 00104 } // end of namespace mln::convert::over_load 00105 00106 } // end of namespace mln::convert 00107 00108 00109 00110 namespace trait 00111 { 00112 00113 template <typename S> 00114 struct set_unary_< op::ord, Site_Set, S > 00115 { 00116 // No definition here. 00117 00118 // That prevents from calling the inclusion operator ("op<") 00119 // which is clearly not the expected ordering... 00120 00121 // Consequently site sets have to define the way they are 00122 // ordered. 00123 }; 00124 00125 } // end of namespace mln::trait 00126 00127 00128 00129 # ifndef MLN_INCLUDE_ONLY 00130 00131 00132 namespace convert 00133 { 00134 00135 namespace over_load 00136 { 00137 00138 template <typename S, typename P, typename C_> 00139 inline 00140 void 00141 from_to_(const Site_Set<S>& from_, std::set<P,C_>& to) 00142 { 00143 mlc_converts_to(mln_psite(S), P)::check(); 00144 const S& from = exact(from_); 00145 to.clear(); 00146 mln_piter(S) p(from); 00147 for_all(p) 00148 to.insert(p); 00149 } 00150 00151 00152 template <typename P, typename C_, typename S> 00153 inline 00154 void 00155 from_to_(const std::set<P,C_>& from, Site_Set<S>& to_) 00156 { 00157 mlc_converts_to(P, mln_i_element(S))::check(); 00158 S& to = exact(to_); 00159 to.clear(); 00160 for (typename std::set<P>::const_iterator i = from.begin(); 00161 i != from.end(); 00162 ++i) 00163 to.insert(*i); 00164 } 00165 00166 } // end of namespace mln::convert::over_load 00167 00168 } // end of namespace mln::convert 00169 00170 00171 namespace internal 00172 { 00173 00174 // nsites: known or unknown. 00175 00176 template <typename trait_nsites, typename E> 00177 struct site_set_nsites_check 00178 { 00179 static void run() { /* No requirement. */ } 00180 }; 00181 00182 template <typename E> 00183 struct site_set_nsites_check< mln::trait::site_set::nsites::known, E > 00184 { 00185 static void run() 00186 { 00187 unsigned (E::*m)() const = & E::nsites; 00188 m = 0; 00189 } 00190 }; 00191 00192 // bbox: unknown, lazy, or straight. 00193 00194 template <typename trait_bbox, typename E> 00195 struct site_set_bbox_check 00196 { 00197 static void run() 00198 { 00199 typedef typename E::q_box q_box; 00200 q_box (E::*m)() const = & E::bbox; 00201 m = 0; 00202 } 00203 }; 00204 00205 template <typename E> 00206 struct site_set_bbox_check< mln::trait::site_set::bbox::unknown, E > 00207 { 00208 static void run() { /* No requirement. */ } 00209 }; 00210 00211 // contents: fixed, growing, or free. 00212 00213 template <typename trait_contents, typename E> 00214 struct site_set_contents_check; 00215 00216 template <typename E> 00217 struct site_set_contents_check< mln::trait::site_set::contents::fixed, E > 00218 { 00219 static void run() { /* No requirement. */ } 00220 }; 00221 00222 template <typename E> 00223 struct site_set_contents_check< mln::trait::site_set::contents::growing, E > 00224 { 00225 static void run() 00226 { 00227 typedef typename E::i_element i_element; 00228 mlc_equal(mlc_unqualif(i_element), i_element)::check(); 00229 void (E::*m1)(const i_element&) = & E::insert; 00230 m1 = 0; 00231 void (E::*m2)() = & E::clear; 00232 m2 = 0; 00233 } 00234 }; 00235 00236 template <typename E> 00237 struct site_set_contents_check< mln::trait::site_set::contents::free, E > 00238 { 00239 static void run() 00240 { 00241 typedef typename E::i_element i_element; 00242 mlc_equal(mlc_unqualif(i_element), i_element)::check(); 00243 void (E::*m1)(const i_element&) = & E::insert; 00244 m1 = 0; 00245 typedef typename E::r_element r_element; 00246 mlc_equal(mlc_unqualif(r_element), r_element)::check(); 00247 void (E::*m2)(const r_element&) = & E::remove; 00248 m2 = 0; 00249 void (E::*m3)() = & E::clear; 00250 m3 = 0; 00251 } 00252 }; 00253 00254 } // end of namespace mln::internal 00255 00256 00257 // fwd decl 00258 template <typename P> struct box_; 00259 00260 template <typename E> 00261 inline 00262 Site_Set<E>::Site_Set() 00263 { 00264 // Check properties. 00265 mlc_not_equal( mln_trait_site_set_nsites(E), mln::trait::undef )::check(); 00266 mlc_not_equal( mln_trait_site_set_bbox(E), mln::trait::undef )::check(); 00267 mlc_not_equal( mln_trait_site_set_contents(E), mln::trait::undef )::check(); 00268 mlc_not_equal( mln_trait_site_set_arity(E), mln::trait::undef )::check(); 00269 // FIXME: also test something like 00270 // mlc_is_a( mln_trait_site_set_nsites(E), mln::trait::site_set::nsites::any )::check(); 00271 00272 // Check associated types. 00273 typedef mln_element(E) element; 00274 mlc_is_unqualif(element)::check(); 00275 typedef mln_site(E) site; 00276 typedef mln_psite(E) psite; 00277 typedef mln_piter(E) piter; 00278 typedef mln_fwd_piter(E) fwd_piter; 00279 typedef mln_bkd_piter(E) bkd_piter; 00280 00281 // Check methods. 00282 bool (E::*m1)(const psite& p) const = & E::has; 00283 m1 = 0; 00284 bool (E::*m2)() const = & E::is_valid; 00285 m2 = 0; 00286 std::size_t (E::*m3)() const = & E::memory_size; 00287 m3 = 0; 00288 00289 // Check methods depending upon properties. 00290 internal::site_set_nsites_check < mln_trait_site_set_nsites(E), E >::run(); 00291 internal::site_set_bbox_check < mln_trait_site_set_bbox(E), E >::run(); 00292 internal::site_set_contents_check< mln_trait_site_set_contents(E), E >::run(); 00293 } 00294 00295 # endif // ! MLN_INCLUDE_ONLY 00296 00297 } // end of namespace mln 00298 00299 00300 # include <mln/core/site_set/operators.hh> 00301 # include <mln/core/routine/ops.hh> 00302 00303 00304 #endif // ! MLN_CORE_CONCEPT_SITE_SET_HH