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

extension_fun.hh

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_DMORPH_EXTENSION_FUN_HH
00027 # define MLN_CORE_IMAGE_DMORPH_EXTENSION_FUN_HH
00028 
00036 
00037 # include <mln/core/internal/image_identity.hh>
00038 
00039 
00040 
00041 namespace mln
00042 {
00043 
00044   // Forward declaration.
00045   template <typename I, typename F> struct extension_fun;
00046 
00047 
00048   namespace internal
00049   {
00050 
00052     template <typename I, typename F>
00053     struct data< extension_fun<I, F> >
00054     {
00055       data(I& ima, const F& fun);
00056 
00057       I ima_;
00058       const F fun_;
00059     };
00060 
00061   } // end of namespace mln::internal
00062 
00063 
00064   namespace trait
00065   {
00066 
00067     template <typename I, typename F>
00068     struct image_< extension_fun<I, F> > : 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::multiple  ext_value;
00078       typedef trait::image::ext_io::read_only    ext_io;
00079     };
00080 
00081     template <typename I, typename F, typename V>
00082     struct ch_value< extension_fun<I, F>, V >
00083     {
00084       typedef mlc_converts_to(mln_result(F), V) keep_ext;
00085       typedef mln_ch_value(I, V)   Iv;
00086       typedef extension_fun<Iv, F> 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, typename F>
00099   class extension_fun
00100   : public internal::image_identity< I, mln_domain(I), extension_fun<I, F> >,
00101     private mlc_converts_to(mln_result(F), mln_value(I))::check_t
00102   {
00103   public:
00104 
00106     typedef extension_fun< tag::image_<I>, tag::function_<F> > skeleton;
00107 
00109     typedef mln_value(I) value;
00110 
00112     typedef mln_value(I) rvalue;
00113 
00114 
00116     extension_fun();
00117 
00119     extension_fun(I& ima, const F& fun);
00120 
00123     void init_(I& ima, const F& fun);
00124 
00125 
00128     // Tech note: the 'template' allows for multiple input.
00129     template <typename P>
00130     bool has(const P& p) const;
00131 
00132 
00134     mln_value(I) operator()(const mln_psite(I)& p) const;
00135 
00137     mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
00138 
00139 
00141     const F& extension() const;
00142   };
00143 
00144 
00145   // init_
00146 
00147   template <typename I, typename F, typename J>
00148   void init_(tag::image_t, extension_fun<I,F>& target, const J& model);
00149 
00150   template <typename F, typename I>
00151   void init_(tag::extension_t, F& target, const extension_fun<I,F>& model);
00152 
00153 
00154 
00155 
00156 # ifndef MLN_INCLUDE_ONLY
00157 
00158   // internal::data< extension_fun<I,S> >
00159 
00160   namespace internal
00161   {
00162 
00163     template <typename I, typename F>
00164     inline
00165     data< extension_fun<I, F> >::data(I& ima, const F& fun)
00166       : ima_(ima),
00167         fun_(fun)
00168     {
00169     }
00170 
00171   } // end of namespace mln::internal
00172 
00173 
00174   // extension_fun<I, F>
00175 
00176   template <typename I, typename F>
00177   inline
00178   extension_fun<I, F>::extension_fun()
00179   {
00180   }
00181 
00182   template <typename I, typename F>
00183   inline
00184   extension_fun<I, F>::extension_fun(I& ima, const F& fun)
00185   {
00186     init_(ima, fun);
00187   }
00188 
00189   template <typename I, typename F>
00190   inline
00191   void
00192   extension_fun<I, F>::init_(I& ima, const F& fun)
00193   {
00194     this->data_ = new internal::data< extension_fun<I, F> >(ima, fun);
00195   }
00196 
00197   template <typename I, typename F>
00198   template <typename P>
00199   inline
00200   bool
00201   extension_fun<I, F>::has(const P&) const
00202   {
00203     return true;
00204   }
00205 
00206   template <typename I, typename F>
00207   inline
00208   mln_value(I)
00209   extension_fun<I, F>::operator()(const mln_psite(I)& p) const
00210   {
00211     mln_precondition(this->is_valid());
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_->fun_(p);
00218   }
00219 
00220   template <typename I, typename F>
00221   inline
00222   mln_morpher_lvalue(I)
00223   extension_fun<I, F>::operator()(const mln_psite(I)& p)
00224   {
00225     static mln_value(I) cpy;
00226     mln_precondition(this->is_valid());
00227     // See the above comment about if-else v. ternary.
00228     if (this->data_->ima_.domain().has(p))
00229       return this->data_->ima_(p);
00230     else
00231       {
00232         // This hack makes this signature valid both in the image
00233         // domain and in its extension.  It works even if
00234         // mln_morpher_lvalue(I) is a mutable reference.
00235         cpy = this->data_->fun_(p);
00236         return cpy;
00237       }
00238   }
00239 
00240   template <typename I, typename F>
00241   inline
00242   const F&
00243   extension_fun<I, F>::extension() const
00244   {
00245     mln_precondition(this->is_valid());
00246     return this->data_->fun_;
00247   }
00248 
00249 
00250   // init_
00251 
00252   template <typename I, typename F, typename J>
00253   void init_(tag::image_t, extension_fun<I,F>& target, const J& model)
00254   {
00255     I ima;
00256     init_(tag::image, ima, model);
00257     F fun;
00258     init_(tag::extension, fun, model);
00259     target.init_(ima, fun);
00260   }
00261 
00262   template <typename F, typename I>
00263   void init_(tag::extension_t, F& target, const extension_fun<I,F>& model)
00264   {
00265     target = model.extension();
00266   }
00267 
00268 # endif // ! MLN_INCLUDE_ONLY
00269 
00270 } // end of namespace mln
00271 
00272 
00273 #endif // ! MLN_CORE_IMAGE_DMORPH_EXTENSION_FUN_HH

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