Milena (Olena)  User documentation 2.0a Id
extension_val.hh
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_VAL_HH
00028 # define MLN_CORE_IMAGE_DMORPH_EXTENSION_VAL_HH
00029 
00036 
00037 # include <mln/core/internal/image_identity.hh>
00038 
00039 
00040 
00041 namespace mln
00042 {
00043 
00044   // Forward declaration.
00045   template <typename I> class extension_val;
00046 
00047 
00048   namespace internal
00049   {
00050 
00052     template <typename I>
00053     struct data< extension_val<I> >
00054     {
00055       data(I& ima, const mln_value(I)& val_);
00056 
00057       I ima_;
00058       mln_value(I) val_;
00059     };
00060 
00061   } // end of namespace mln::internal
00062 
00063 
00064   namespace trait
00065   {
00066 
00067     template <typename I>
00068     struct image_< extension_val<I> > : image_< I > // Same as I except...
00069     {
00070       // ...these changes.
00071       typedef trait::image::category::identity_morpher category;
00072       typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
00073       typedef trait::image::value_access::indirect value_access;
00074 
00075       // extended domain
00076       typedef trait::image::ext_domain::infinite ext_domain;
00077       typedef trait::image::ext_value::single    ext_value;
00078       typedef trait::image::ext_io::read_write   ext_io;
00079     };
00080 
00081     template <typename I, typename V>
00082     struct ch_value< extension_val<I>, V >
00083     {
00084       typedef mlc_converts_to(mln_value(I), V) keep_ext;
00085       typedef mln_ch_value(I, V) Iv;
00086       typedef extension_val<Iv>  Iv_ext;
00087       typedef mlc_if(keep_ext, Iv_ext, Iv) ret;
00088     };
00089 
00090   } // end of namespace mln::trait
00091 
00092 
00093 
00097   //
00098   template <typename I>
00099   class extension_val :
00100     public internal::image_identity< I, mln_domain(I), extension_val<I> >
00101   {
00102   public:
00103 
00105     typedef extension_val< tag::image_<I> > skeleton;
00106 
00108     typedef mln_value(I) value;
00109 
00111     typedef mln_value(I) rvalue;
00112 
00113 
00115     extension_val();
00116 
00118     extension_val(I& ima, const mln_value(I)& val);
00119 
00122     void init_(I& ima, const mln_value(I)& val);
00123 
00124 
00126     // Tech note: the 'template' allows for multiple input.
00127     template <typename P>
00128     bool has(const P& p) const;
00129 
00130 
00132     mln_value(I) operator()(const mln_psite(I)& p) const;
00133 
00135     mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
00136 
00137 
00139     const mln_value(I)& extension() const;
00140 
00142     void change_extension(const mln_value(I)& val);
00143   };
00144 
00145 
00146   // init_
00147 
00148   template <typename I, typename J>
00149   void init_(tag::image_t, extension_val<I>& target, const J& model);
00150 
00151   template <typename V, typename I>
00152   void init_(tag::extension_t, V& target, const extension_val<I>& model);
00153 
00154 
00155 
00156 # ifndef MLN_INCLUDE_ONLY
00157 
00158   // internal::data< extension_val<I,S> >
00159 
00160   namespace internal
00161   {
00162 
00163     template <typename I>
00164     inline
00165     data< extension_val<I> >::data(I& ima, const mln_value(I)& val)
00166       : ima_(ima),
00167         val_(val)
00168     {
00169     }
00170 
00171   } // end of namespace mln::internal
00172 
00173   // extension_val<I>
00174 
00175   template <typename I>
00176   inline
00177   extension_val<I>::extension_val()
00178   {
00179   }
00180 
00181   template <typename I>
00182   inline
00183   extension_val<I>::extension_val(I& ima, const mln_value(I)& val)
00184   {
00185     init_(ima, val);
00186   }
00187 
00188   template <typename I>
00189   inline
00190   void
00191   extension_val<I>::init_(I& ima, const mln_value(I)& val)
00192   {
00193     this->data_ = new internal::data< extension_val<I> >(ima, val);
00194   }
00195 
00196   template <typename I>
00197   template <typename P>
00198   inline
00199   bool
00200   extension_val<I>::has(const P&) const
00201   {
00202     return true;
00203   }
00204 
00205   template <typename I>
00206   inline
00207   mln_value(I)
00208   extension_val<I>::operator()(const mln_psite(I)& p) const
00209   {
00210     mln_precondition(this->is_valid());
00211     // if-else is preferred to the ternary op to allow conversions.
00212     if (this->data_->ima_.domain().has(p))
00213       return this->data_->ima_(p);
00214     else
00215       return this->data_->val_;
00216   }
00217 
00218   template <typename I>
00219   inline
00220   mln_morpher_lvalue(I)
00221   extension_val<I>::operator()(const mln_psite(I)& p)
00222   {
00223     static mln_value(I) cpy;
00224     mln_precondition(this->is_valid());
00225     // See the above comment about if-else v. ternary.
00226     if (this->data_->ima_.domain().has(p))
00227       return this->data_->ima_(p);
00228     else
00229       {
00230         // This hack makes the extension value non-modifiable.
00231         cpy = this->data_->val_;
00232         return cpy;
00233       }
00234   }
00235 
00236   template <typename I>
00237   inline
00238   const mln_value(I)&
00239   extension_val<I>::extension() const
00240   {
00241     mln_precondition(this->is_valid());
00242     return this->data_->val_;
00243   }
00244 
00245   template <typename I>
00246   inline
00247   void
00248   extension_val<I>::change_extension(const mln_value(I)& val)
00249   {
00250     mln_precondition(this->is_valid());
00251     this->data_->val_ = val;
00252   }
00253 
00254 
00255   // init_
00256 
00257   template <typename I, typename J>
00258   void init_(tag::image_t, extension_val<I>& target, const J& model)
00259   {
00260     I ima;
00261     init_(tag::image, ima, model);
00262     mln_value(I) val;
00263     init_(tag::extension, val, model);
00264     target.init_(ima, val);
00265   }
00266 
00267   template <typename V, typename I>
00268   void init_(tag::extension_t, V& target, const extension_val<I>& model)
00269   {
00270     mlc_converts_to(mln_value(I), V)::check();
00271     target = static_cast<V>(model.extension());
00272   }
00273 
00274 # endif // ! MLN_INCLUDE_ONLY
00275 
00276 } // end of namespace mln
00277 
00278 
00279 #endif // ! MLN_CORE_IMAGE_DMORPH_EXTENSION_VAL_HH
 All Classes Namespaces Functions Variables Typedefs Enumerator