Milena (Olena)  User documentation 2.0a Id
safe.hh
00001 // Copyright (C) 2007, 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_IMORPH_SAFE_HH
00028 # define MLN_CORE_IMAGE_IMORPH_SAFE_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 safe_image;
00046 
00047 
00048   namespace internal
00049   {
00050 
00052     template <typename I>
00053     struct data< safe_image<I> >
00054     {
00055       data(I& ima, const mln_value(I)& default_value);
00056 
00057       I ima_;
00058       mln_value(I) default_value_;
00059     };
00060 
00061   } // end of namespace mln::internal
00062 
00063 
00064   namespace trait
00065   {
00066 
00067     template <typename I>
00068     struct image_< safe_image<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     };
00074 
00075   } // end of namespace mln::trait
00076 
00077 
00078 
00082   //
00083   template <typename I>
00084   class safe_image : public internal::image_identity< I, mln_domain(I), safe_image<I> >
00085   {
00086   public:
00087 
00089     typedef safe_image< tag::image_<I> > skeleton;
00090 
00091     safe_image();
00092     safe_image(I& ima);
00093     safe_image(I& ima, const mln_value(I)& default_value);
00094 
00095     // Initialize an empty image.
00096     void init_(I& ima, const mln_value(I)& default_value);
00097 
00098     mln_rvalue(I) operator()(const mln_psite(I)& p) const;
00099 
00100     mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
00101 
00103     operator safe_image<const I>() const;
00104   };
00105 
00106 
00107 
00108   template <typename I>
00109   safe_image<I> safe(Image<I>& ima,
00110                      mln_value(I) default_value = mln_value(I)());
00111 
00112   template <typename I>
00113   safe_image<const I> safe(const Image<I>& ima,
00114                            mln_value(I) default_value = mln_value(I)());
00115 
00116 
00117 
00118 # ifndef MLN_INCLUDE_ONLY
00119 
00120   // internal::data< safe_image<I,S> >
00121 
00122   namespace internal
00123   {
00124 
00125     template <typename I>
00126     inline
00127     data< safe_image<I> >::data(I& ima, const mln_value(I)& default_value)
00128       : ima_(ima),
00129         default_value_(default_value)
00130     {
00131     }
00132 
00133   } // end of namespace mln::internal
00134 
00135   // safe_image<I>
00136 
00137   template <typename I>
00138   inline
00139   safe_image<I>::safe_image()
00140   {
00141   }
00142 
00143   template <typename I>
00144   inline
00145   safe_image<I>::safe_image(I& ima, const mln_value(I)& default_value)
00146   {
00147     mln_precondition(ima.is_valid());
00148     init_(ima, default_value);
00149   }
00150 
00151   template <typename I>
00152   inline
00153   safe_image<I>::safe_image(I& ima)
00154   {
00155     mln_precondition(ima.is_valid());
00156     init_(ima, mln_value(I)());
00157   }
00158 
00159   template <typename I>
00160   inline
00161   void
00162   safe_image<I>::init_(I& ima, const mln_value(I)& default_value)
00163   {
00164     mln_precondition(! this->is_valid());
00165     mln_precondition(ima.is_valid());
00166     this->data_ = new internal::data< safe_image<I> >(ima, default_value);
00167   }
00168 
00169   template <typename I>
00170   inline
00171   mln_rvalue(I)
00172   safe_image<I>::operator()(const mln_psite(I)& p) const
00173   {
00174     mln_precondition(this->is_valid());
00175     if (! this->has(p))
00176       return this->data_->default_value_;
00177     return this->data_->ima_(p);
00178   }
00179 
00180   template <typename I>
00181   inline
00182   mln_morpher_lvalue(I)
00183   safe_image<I>::operator()(const mln_psite(I)& p)
00184   {
00185     mln_precondition(this->is_valid());
00186     static mln_value(I) forget_it_;
00187     if (this->has(p))
00188       return this->data_->ima_(p);
00189     else
00190       // A copy of data_->default_value_ is returned.
00191       return forget_it_ = this->data_->default_value_;
00192   }
00193 
00194   template <typename I>
00195   inline
00196   safe_image<I>::operator safe_image<const I>() const
00197   {
00198     safe_image<const I> tmp(this->data_->ima_, this->data_->default_value_);
00199     return tmp;
00200   }
00201 
00202   // safe
00203 
00204   template <typename I>
00205   inline
00206   safe_image<I> safe(Image<I>& ima,
00207                      mln_value(I) default_value)
00208   {
00209     safe_image<I> tmp(exact(ima), default_value);
00210     return tmp;
00211   }
00212 
00213   template <typename I>
00214   inline
00215   safe_image<const I> safe(const Image<I>& ima,
00216                            mln_value(I) default_value)
00217   {
00218     safe_image<const I> tmp(exact(ima), default_value);
00219     return tmp;
00220   }
00221 
00222 # endif // ! MLN_INCLUDE_ONLY
00223 
00224 } // end of namespace mln
00225 
00226 
00227 #endif // ! MLN_CORE_IMAGE_IMORPH_SAFE_HH
 All Classes Namespaces Functions Variables Typedefs Enumerator