• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

extension_ima.hh

00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
00002 // (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> struct 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

Generated on Tue Oct 4 2011 15:23:45 for Milena (Olena) by  doxygen 1.7.1