Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #ifndef MLN_CORE_IMAGE_DMORPH_EXTENSION_IMA_HH 00028 # define MLN_CORE_IMAGE_DMORPH_EXTENSION_IMA_HH 00029 00034 00035 # include <mln/core/internal/image_identity.hh> 00036 00037 00038 00039 namespace mln 00040 { 00041 00042 // Forward declaration. 00043 template <typename I, typename J> class extension_ima; 00044 00045 00046 namespace internal 00047 { 00048 00050 template <typename I, typename J> 00051 struct data< extension_ima<I, J> > 00052 { 00053 data(I& ima, const J& ext); 00054 00055 I ima_; 00056 J ext_; 00057 }; 00058 00059 } // end of namespace mln::internal 00060 00061 00062 namespace trait 00063 { 00064 00065 template <typename I, typename J> 00066 struct image_< extension_ima<I, J> > : image_< I > // Same as I except... 00067 { 00068 // ...these changes. 00069 typedef trait::image::category::identity_morpher category; 00070 typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest. 00071 typedef trait::image::value_access::indirect value_access; 00072 00073 // extended domain 00074 typedef trait::image::ext_domain::extendable ext_domain; 00075 typedef trait::image::ext_value::multiple ext_value; 00076 typedef trait::image::ext_io::read_only ext_io; 00077 }; 00078 00079 template <typename I, typename J, typename V> 00080 struct ch_value< extension_ima<I, J>, V > 00081 { 00082 typedef mlc_converts_to(mln_value(J), V) keep_ext; 00083 typedef mln_ch_value(I, V) Iv; 00084 typedef extension_ima<Iv, J> Iv_ext; 00085 typedef mlc_if(keep_ext, Iv_ext, Iv) ret; 00086 }; 00087 00088 } // end of namespace mln::trait 00089 00090 00091 00095 // 00096 template <typename I, typename J> 00097 class extension_ima 00098 00099 : public internal::image_identity< I, mln_domain(I), extension_ima<I, J> >, 00100 private mlc_converts_to(mln_value(J), mln_value(I))::check_t 00101 { 00102 public: 00103 00105 typedef extension_ima< tag::image_<I>, tag::ext_<J> > skeleton; 00106 00108 typedef mln_value(I) value; 00109 00111 typedef mln_value(I) rvalue; 00112 00114 extension_ima(); 00115 00117 extension_ima(I& ima, const J& ext); 00118 00121 void init_(I& ima, const J& ext); 00122 00123 00125 // Tech note: the 'template' allows for multiple input. 00126 template <typename P> 00127 bool has(const P& p) const; 00128 00129 00131 mln_value(I) operator()(const mln_psite(I)& p) const; 00132 00134 mln_morpher_lvalue(I) operator()(const mln_psite(I)& p); 00135 00136 00138 const J& extension() const; 00139 }; 00140 00141 00142 // init_ 00143 00144 template <typename I, typename J, typename M> 00145 void init_(tag::image_t, extension_ima<I,J>& target, const M& model); 00146 00147 template <typename J, typename I> 00148 void init_(tag::extension_t, J& target, const extension_ima<I,J>& model); 00149 00150 00151 00152 # ifndef MLN_INCLUDE_ONLY 00153 00154 // internal::data< extension_ima<I,S> > 00155 00156 namespace internal 00157 { 00158 00159 template <typename I, typename J> 00160 inline 00161 data< extension_ima<I, J> >::data(I& ima, const J& ext) 00162 : ima_(ima), 00163 ext_(const_cast<J&>(ext)) 00164 { 00165 } 00166 00167 } // end of namespace mln::internal 00168 00169 // extension_ima<I, J> 00170 00171 template <typename I, typename J> 00172 inline 00173 extension_ima<I, J>::extension_ima() 00174 { 00175 } 00176 00177 template <typename I, typename J> 00178 inline 00179 extension_ima<I, J>::extension_ima(I& ima, const J& ext) 00180 { 00181 init_(ima, ext); 00182 } 00183 00184 template <typename I, typename J> 00185 inline 00186 void 00187 extension_ima<I, J>::init_(I& ima, const J& ext) 00188 { 00189 this->data_ = new internal::data< extension_ima<I, J> >(ima, ext); 00190 } 00191 00192 template <typename I, typename J> 00193 template <typename P> 00194 inline 00195 bool 00196 extension_ima<I, J>::has(const P& p) const 00197 { 00198 mln_precondition(this->is_valid()); 00199 mln_precondition(this->data_->ext_.is_valid()); 00200 return 00201 this->data_->ima_.domain().has(p) 00202 || this->data_->ext_.has(p); 00203 } 00204 00205 template <typename I, typename J> 00206 inline 00207 mln_value(I) 00208 extension_ima<I, J>::operator()(const mln_psite(I)& p) const 00209 { 00210 mln_precondition(this->is_valid()); 00211 mln_precondition(has(p)); 00212 // if-else is preferred to the ternary op to allow for the 00213 // function result to convert towards the expected return type. 00214 if (this->data_->ima_.domain().has(p)) 00215 return this->data_->ima_(p); 00216 else 00217 return this->data_->ext_(p); 00218 } 00219 00220 template <typename I, typename J> 00221 inline 00222 mln_morpher_lvalue(I) 00223 extension_ima<I, J>::operator()(const mln_psite(I)& p) 00224 { 00225 static mln_value(I) cpy; 00226 mln_precondition(this->is_valid()); 00227 mln_precondition(has(p)); 00228 // See the above comment about if-else v. ternary. 00229 if (this->data_->ima_.domain().has(p)) 00230 return this->data_->ima_(p); 00231 else 00232 { 00233 // This hack makes this signature valid both in the image 00234 // domain and in its extension. It works even if 00235 // mln_morpher_lvalue(I) is a mutable reference. 00236 cpy = this->data_->ext_(p); 00237 return cpy; 00238 } 00239 } 00240 00241 template <typename I, typename J> 00242 inline 00243 const J& 00244 extension_ima<I, J>::extension() const 00245 { 00246 mln_precondition(this->is_valid()); 00247 return this->data_->ext_; 00248 } 00249 00250 // init_ 00251 00252 template <typename I, typename J, typename M> 00253 inline 00254 void init_(tag::image_t, extension_ima<I,J>& target, const M& model) 00255 { 00256 I ima; 00257 init_(tag::image, ima, model); 00258 J ext; 00259 init_(tag::extension, ext, model); 00260 target.init_(ima, ext); 00261 } 00262 00263 template <typename J, typename I> 00264 inline 00265 void init_(tag::extension_t, J& target, const extension_ima<I,J>& model) 00266 { 00267 typedef mlc_unconst(J) J_; 00268 J_& ext_ = const_cast<J_&>(model.extension()); 00269 J_& target_ = const_cast<J_&>(target); 00270 target_ = ext_; 00271 } 00272 00273 # endif // ! MLN_INCLUDE_ONLY 00274 00275 } // end of namespace mln 00276 00277 00278 #endif // ! MLN_CORE_IMAGE_DMORPH_EXTENSION_IMA_HH