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

complex_image.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_COMPLEX_IMAGE_HH
00027 # define MLN_CORE_IMAGE_COMPLEX_IMAGE_HH
00028 
00032 
00033 # include <vector>
00034 
00035 # include <mln/trait/images.hh>
00036 
00037 # include <mln/core/internal/image_primary.hh>
00038 # include <mln/metal/vec.hh>
00039 # include <mln/core/site_set/p_complex.hh>
00040 # include <mln/core/site_set/complex_psite.hh>
00041 # include <mln/value/set.hh>
00042 
00043 
00044 /* FIXME: In the current implementation, the type of values on faces
00045    of different dimensions is necessarily the same (V).  We should
00046    allow different data types for vertices and edges.  */
00047 
00048 
00049 namespace mln
00050 {
00051 
00052   // Forward declaration.
00053   template <unsigned D, typename G, typename V> class complex_image;
00054 
00055   namespace internal
00056   {
00057 
00059     template <unsigned D, typename G, typename V>
00060     struct data< complex_image<D, G, V> >
00061     {
00062       data(const p_complex<D, G>& pc,
00063            const metal::vec< D + 1, std::vector<V> >& values);
00064 
00065       metal::vec< D + 1, std::vector<V> > values_;
00066       const p_complex<D, G> pc_;
00067     };
00068 
00069   } // end of namespace mln::internal
00070 
00071 
00072   namespace trait
00073   {
00074 
00075     template <unsigned D, typename G, typename V>
00076     struct image_< complex_image<D, G, V> >
00077       : default_image_< V, complex_image<D, G, V> >
00078     {
00079       typedef trait::image::category::primary category;
00080 
00081       // FIXME: Is that right?
00082       typedef trait::image::speed::fast       speed;
00083       typedef trait::image::size::regular     size;
00084 
00085       // Value.
00086       typedef trait::image::value_access::direct           value_access;
00087       // FIXME: This image is value wise read_write, and provides
00088       // an access to its values throught a multi-set,
00089       // but we need to add the corresponding interface in the class.
00090       typedef trait::image::vw_io::none                    vw_io;
00091       typedef trait::image::vw_set::none                   vw_set;
00092       typedef trait::image::value_storage::disrupted       value_storage;
00093       typedef trait::image::value_browsing::site_wise_only value_browsing;
00094       typedef trait::image::value_alignment::irrelevant    value_alignment;
00095       typedef trait::image::value_io::read_write           value_io;
00096 
00097       // Site / domain.
00098       typedef trait::image::pw_io::read_write              pw_io;
00099       typedef trait::image::localization::space            localization;
00100       /* FIXME: Depends on G.  We could use
00101          `trait::image::space_from_point<mln_site(G)>::ret' in most
00102          cases (i.e., when G's site is a Point), but would not be
00103          generic.  */
00104       typedef typename trait::image::dimension::none    dimension;
00105 
00106       // Extended domain.
00107       typedef trait::image::ext_domain::none      ext_domain;
00108       typedef trait::image::ext_value::irrelevant ext_value;
00109       typedef trait::image::ext_io::irrelevant    ext_io;
00110     };
00111 
00112   } // end of namespace mln::trait
00113 
00114 
00124   template <unsigned D, typename G, typename V>
00125   class complex_image
00126     : public internal::image_primary< V, p_complex<D, G>,
00127                                       complex_image<D, G, V> >
00128   {
00129   public:
00131     static const unsigned dim = D;
00133     typedef G geom;
00135     typedef V value;
00136 
00143     typedef typename std::vector<V>::reference lvalue;
00144 
00146     typedef typename std::vector<V>::const_reference rvalue;
00147 
00149     typedef complex_image< D, tag::psite_<G>, tag::value_<V> > skeleton;
00150 
00151   public:
00154     complex_image();
00155     complex_image(const p_complex<D, G>& pc);
00156     complex_image(const p_complex<D, G>& pc,
00157                   const metal::vec< D + 1, std::vector<V> >& values);
00159 
00161     void init_(const p_complex<D, G>& pc,
00162                const metal::vec< D + 1, std::vector<V> >& values);
00163 
00165     rvalue operator()(const complex_psite<D, G>& p) const;
00167     lvalue operator()(const complex_psite<D, G>& p);
00168 
00172     const p_complex<D, G>& domain() const;
00173 
00175     const metal::vec<D + 1, std::vector<V> >& values() const;
00177   };
00178 
00179   // Fwd decl.
00180   template <unsigned D, typename G, typename V, typename W>
00181   void init_(tag::image_t,
00182              complex_image<D, G, V>& target,
00183              const complex_image<D, G, W>& model);
00184 
00185 
00186 # ifndef MLN_INCLUDE_ONLY
00187 
00188   /*-----------------.
00189   | Initialization.  |
00190   `-----------------*/
00191 
00192   template <unsigned D, typename G, typename V, typename W>
00193   inline
00194   void init_(tag::image_t,
00195              complex_image<D, G, V>& target,
00196              const complex_image<D, G, W>& model)
00197   {
00198     metal::vec<D + 1, std::vector<V> > values;
00199     for (unsigned i = 0; i <= D; ++i)
00200       values[i].resize(model.values()[i].size());
00201     target.init_(model.domain(), values);
00202   }
00203 
00204   /*-------.
00205   | Data.  |
00206   `-------*/
00207 
00208   namespace internal
00209   {
00210     template <unsigned D, typename G, typename V>
00211     inline
00212     data< complex_image<D, G, V> >::data(const p_complex<D, G>& pc,
00213                                          const metal::vec< D + 1, std::vector<V> >& values)
00214       : values_(values),
00215         pc_(pc)
00216     {
00217       // Ensure the complex is consistent with the values.
00218       /* FIXME: We need additional macros in mln/core/contract.hh for
00219          big blocks of preconditions like this one.  */
00220 # ifndef NDEBUG
00221       for (unsigned i = 0; i < D; ++i)
00222         mln_precondition(pc.cplx().nfaces_of_dim(i) == values[i].size());
00223 # endif // !NDEBUG
00224     }
00225 
00226   } // end of namespace mln::internal
00227 
00228   /*---------------.
00229   | Construction.  |
00230   `---------------*/
00231 
00232   template <unsigned D, typename G, typename V>
00233   inline
00234   complex_image<D, G, V>::complex_image()
00235   {
00236   }
00237 
00238   template <unsigned D, typename G, typename V>
00239   inline
00240   complex_image<D, G, V>::complex_image(const p_complex<D, G>& pc)
00241   {
00242     metal::vec<D + 1, std::vector<V> > values;
00243     for (unsigned i = 0; i <= D; ++i)
00244       values[i].resize(pc.cplx().nfaces_of_dim(i));
00245     init_(pc, values);
00246   }
00247 
00248   template <unsigned D, typename G, typename V>
00249   inline
00250   complex_image<D, G, V>::complex_image(const p_complex<D, G>& pc,
00251                                         const metal::vec< D + 1,
00252                                                           std::vector<V> >& values)
00253   {
00254     init_(pc, values);
00255   }
00256 
00257   template <unsigned D, typename G, typename V>
00258   inline
00259   void
00260   complex_image<D, G, V>::init_(const p_complex<D, G>& pc,
00261                                 const metal::vec< D + 1, std::vector<V> >& values)
00262   {
00263     mln_precondition(! this->is_valid());
00264     this->data_ =
00265       new internal::data< complex_image<D, G, V> >(pc, values);
00266   }
00267 
00268   /*---------------.
00269   | Manipulation.  |
00270   `---------------*/
00271 
00272   template <unsigned D, typename G, typename V>
00273   inline
00274   typename complex_image<D, G, V>::rvalue
00275   complex_image<D, G, V>::operator()(const complex_psite<D, G>& p) const
00276   {
00277     mln_precondition(this->data_->pc_.has(p));
00278     return this->data_->values_[p.n()][p.face_id()];
00279   }
00280 
00281   template <unsigned D, typename G, typename V>
00282   inline
00283   typename complex_image<D, G, V>::lvalue
00284   complex_image<D, G, V>::operator()(const complex_psite<D, G>& p)
00285   {
00286     mln_precondition(this->data_->pc_.has(p));
00287     return this->data_->values_[p.n()][p.face_id()];
00288   }
00289 
00290   template <unsigned D, typename G, typename V>
00291   inline
00292   const metal::vec< D + 1, std::vector<V> >&
00293   complex_image<D, G, V>::values() const
00294   {
00295     return this->data_->values_;
00296   }
00297 
00298   template <unsigned D, typename G, typename V>
00299   inline
00300   const p_complex<D, G>&
00301   complex_image<D, G, V>::domain() const
00302   {
00303     mln_precondition(this->is_valid());
00304     return this->data_->pc_;
00305   }
00306 
00307 # endif // ! MLN_INCLUDE_ONLY
00308 
00309 } // end of namespace mln
00310 
00311 
00312 #endif // ! MLN_CORE_IMAGE_COMPLEX_IMAGE_HH

Generated on Thu Sep 8 2011 18:31:41 for Milena (Olena) by  doxygen 1.7.1