Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 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_IMAGE_COMPLEX_IMAGE_HH 00027 # define MLN_CORE_IMAGE_COMPLEX_IMAGE_HH 00028 00032 00033 # include <vector> 00034 00035 # include <mln/trait/images.hh> 00036 00037 # include <mln/core/internal/image_primary.hh> 00038 # include <mln/metal/vec.hh> 00039 # include <mln/core/site_set/p_complex.hh> 00040 # include <mln/core/site_set/complex_psite.hh> 00041 # include <mln/value/set.hh> 00042 00043 // FIXME: Move this elsewhere. 00044 // Working around std::vector<bool>'s (forced) specialization. 00045 00046 # define mlc_unbool(V) \ 00047 typename mln::internal::unbool<V>::ret 00048 00049 namespace mln 00050 { 00051 00052 namespace internal 00053 { 00054 00056 struct bool_proxy 00057 { 00058 public: 00059 bool_proxy() {} 00060 bool_proxy(bool b) : b_(b) {} 00061 bool& operator=(bool b) { b_ = b; return *this; } 00062 00063 operator bool&() { return b_; } 00064 operator const bool&() const { return b_; } 00065 00066 bool operator==(const bool_proxy& rhs) { return b_ == rhs.b_; } 00067 bool operator< (const bool_proxy& rhs) { return b_ < rhs.b_; } 00068 00069 private: 00071 bool b_; 00072 }; 00073 00074 template <typename V> struct unbool { typedef V ret; }; 00075 template <> struct unbool<bool> { typedef bool_proxy ret; }; 00076 00077 } // end of namespace mln::internal 00078 00079 } 00080 00081 00082 00083 /* FIXME: In the current implementation, the type of values on faces 00084 of different dimensions is necessarily the same (V). We should 00085 allow different data types for vertices and edges. */ 00086 00087 00088 namespace mln 00089 { 00090 00091 // Forward declaration. 00092 template <unsigned D, typename G, typename V> class complex_image; 00093 00094 namespace internal 00095 { 00096 00098 template <unsigned D, typename G, typename V> 00099 struct data< complex_image<D, G, V> > 00100 { 00101 data(const p_complex<D, G>& pc, 00102 const metal::vec< D + 1, std::vector<V> >& values); 00103 00104 metal::vec< D + 1, std::vector< mlc_unbool(V) > > values_; 00105 const p_complex<D, G> pc_; 00106 }; 00107 00108 } // end of namespace mln::internal 00109 00110 00111 namespace trait 00112 { 00113 00114 template <unsigned D, typename G, typename V> 00115 struct image_< complex_image<D, G, V> > 00116 : default_image_< V, complex_image<D, G, V> > 00117 { 00118 typedef trait::image::category::primary category; 00119 00120 // FIXME: Is that right? 00121 typedef trait::image::speed::fast speed; 00122 typedef trait::image::size::regular size; 00123 00124 // Value. 00125 typedef trait::image::value_access::direct value_access; 00126 // FIXME: This image is value wise read_write, and provides 00127 // an access to its values throught a multi-set, 00128 // but we need to add the corresponding interface in the class. 00129 typedef trait::image::vw_io::none vw_io; 00130 typedef trait::image::vw_set::none vw_set; 00131 typedef trait::image::value_storage::disrupted value_storage; 00132 typedef trait::image::value_browsing::site_wise_only value_browsing; 00133 typedef trait::image::value_alignment::irrelevant value_alignment; 00134 typedef trait::image::value_io::read_write value_io; 00135 00136 // Site / domain. 00137 typedef trait::image::pw_io::read_write pw_io; 00138 typedef trait::image::localization::space localization; 00139 /* FIXME: Depends on G. We could use 00140 `trait::image::space_from_point<mln_site(G)>::ret' in most 00141 cases (i.e., when G's site is a Point), but would not be 00142 generic. */ 00143 typedef typename trait::image::dimension::none dimension; 00144 00145 // Extended domain. 00146 typedef trait::image::ext_domain::none ext_domain; 00147 typedef trait::image::ext_value::irrelevant ext_value; 00148 typedef trait::image::ext_io::irrelevant ext_io; 00149 }; 00150 00151 } // end of namespace mln::trait 00152 00153 00163 template <unsigned D, typename G, typename V> 00164 class complex_image 00165 : public internal::image_primary< V, p_complex<D, G>, 00166 complex_image<D, G, V> > 00167 { 00168 public: 00170 static const unsigned dim = D; 00172 typedef G geom; 00174 typedef V value; 00175 00177 typedef V& lvalue; 00178 00180 typedef const V& rvalue; 00181 00183 typedef complex_image< D, tag::psite_<G>, tag::value_<V> > skeleton; 00184 00185 public: 00188 complex_image(); 00189 complex_image(const p_complex<D, G>& pc); 00190 complex_image(const p_complex<D, G>& pc, 00191 const metal::vec< D + 1, std::vector<V> >& values); 00193 00195 void init_(const p_complex<D, G>& pc, 00196 const metal::vec< D + 1, std::vector<V> >& values); 00197 00199 rvalue operator()(const complex_psite<D, G>& p) const; 00201 lvalue operator()(const complex_psite<D, G>& p); 00202 00206 const p_complex<D, G>& domain() const; 00207 00209 const metal::vec<D + 1, std::vector< mlc_unbool(V) > >& values() const; 00211 }; 00212 00213 // Fwd decl. 00214 template <unsigned D, typename G, typename V, typename W> 00215 void init_(tag::image_t, 00216 complex_image<D, G, V>& target, 00217 const complex_image<D, G, W>& model); 00218 00219 00220 # ifndef MLN_INCLUDE_ONLY 00221 00222 /*-----------------. 00223 | Initialization. | 00224 `-----------------*/ 00225 00226 template <unsigned D, typename G, typename V, typename W> 00227 inline 00228 void init_(tag::image_t, 00229 complex_image<D, G, V>& target, 00230 const complex_image<D, G, W>& model) 00231 { 00232 metal::vec<D + 1, std::vector<V> > values; 00233 for (unsigned i = 0; i <= D; ++i) 00234 values[i].resize(model.domain().nfaces_of_dim(i)); 00235 target.init_(model.domain(), values); 00236 } 00237 00238 /*-------. 00239 | Data. | 00240 `-------*/ 00241 00242 namespace internal 00243 { 00244 template <unsigned D, typename G, typename V> 00245 inline 00246 data< complex_image<D, G, V> >::data(const p_complex<D, G>& pc, 00247 const metal::vec< D + 1, std::vector<V> >& values) 00248 : pc_(pc) 00249 { 00250 // We cannot use the initialization list for values_ (it 00251 // would not work when V = bool). 00252 for (unsigned i = 0; i <= D; ++i) 00253 { 00254 values_[i].reserve(values[i].size()); 00255 values_[i].insert(values_[i].begin(), 00256 values[i].begin(), values[i].end()); 00257 } 00258 00259 // Ensure the complex is consistent with the values. 00260 /* FIXME: We need additional macros in mln/core/contract.hh for 00261 big blocks of preconditions like this one. */ 00262 # ifndef NDEBUG 00263 for (unsigned i = 0; i < D; ++i) 00264 mln_precondition(pc.nfaces_of_dim(i) == values[i].size()); 00265 # endif // !NDEBUG 00266 } 00267 00268 } // end of namespace mln::internal 00269 00270 /*---------------. 00271 | Construction. | 00272 `---------------*/ 00273 00274 template <unsigned D, typename G, typename V> 00275 inline 00276 complex_image<D, G, V>::complex_image() 00277 { 00278 } 00279 00280 template <unsigned D, typename G, typename V> 00281 inline 00282 complex_image<D, G, V>::complex_image(const p_complex<D, G>& pc) 00283 { 00284 metal::vec<D + 1, std::vector<V> > values; 00285 for (unsigned i = 0; i <= D; ++i) 00286 values[i].resize(pc.nfaces_of_dim(i)); 00287 init_(pc, values); 00288 } 00289 00290 template <unsigned D, typename G, typename V> 00291 inline 00292 complex_image<D, G, V>::complex_image(const p_complex<D, G>& pc, 00293 const metal::vec< D + 1, 00294 std::vector<V> >& values) 00295 { 00296 init_(pc, values); 00297 } 00298 00299 template <unsigned D, typename G, typename V> 00300 inline 00301 void 00302 complex_image<D, G, V>::init_(const p_complex<D, G>& pc, 00303 const metal::vec< D + 1, std::vector<V> >& values) 00304 { 00305 mln_precondition(! this->is_valid()); 00306 this->data_ = 00307 new internal::data< complex_image<D, G, V> >(pc, values); 00308 } 00309 00310 /*---------------. 00311 | Manipulation. | 00312 `---------------*/ 00313 00314 template <unsigned D, typename G, typename V> 00315 inline 00316 typename complex_image<D, G, V>::rvalue 00317 complex_image<D, G, V>::operator()(const complex_psite<D, G>& p) const 00318 { 00319 mln_precondition(this->data_->pc_.has(p)); 00320 return this->data_->values_[p.n()][p.face_id()]; 00321 } 00322 00323 template <unsigned D, typename G, typename V> 00324 inline 00325 typename complex_image<D, G, V>::lvalue 00326 complex_image<D, G, V>::operator()(const complex_psite<D, G>& p) 00327 { 00328 mln_precondition(this->data_->pc_.has(p)); 00329 return this->data_->values_[p.n()][p.face_id()]; 00330 } 00331 00332 template <unsigned D, typename G, typename V> 00333 inline 00334 const metal::vec< D + 1, std::vector< mlc_unbool(V) > >& 00335 complex_image<D, G, V>::values() const 00336 { 00337 return this->data_->values_; 00338 } 00339 00340 template <unsigned D, typename G, typename V> 00341 inline 00342 const p_complex<D, G>& 00343 complex_image<D, G, V>::domain() const 00344 { 00345 mln_precondition(this->is_valid()); 00346 return this->data_->pc_; 00347 } 00348 00349 # endif // ! MLN_INCLUDE_ONLY 00350 00351 } // end of namespace mln 00352 00353 # undef mlc_unbool 00354 00355 #endif // ! MLN_CORE_IMAGE_COMPLEX_IMAGE_HH