• 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 // FIXME: Move this elsewhere.
00044 // Working around std::vector<bool>'s (forced) specialization.
00045 
00046 # define mlc_unbool(V)                          \
00047    typename mln::internal::unbool<V>::ret
00048 
00049 namespace mln
00050 {
00051 
00052   namespace internal
00053   {
00054 
00056     struct bool_proxy
00057     {
00058     public:
00059       bool_proxy() {}
00060       bool_proxy(bool b) : b_(b) {}
00061       bool& operator=(bool b) { b_ = b; return *this; }
00062 
00063       operator bool&() { return b_; }
00064       operator const bool&() const { return b_; }
00065 
00066       bool operator==(const bool_proxy& rhs) { return b_ == rhs.b_; }
00067       bool operator< (const bool_proxy& rhs) { return b_ <  rhs.b_; }
00068 
00069     private:
00071       bool b_;
00072     };
00073 
00074     template <typename V> struct unbool       { typedef V          ret; };
00075     template <>           struct unbool<bool> { typedef bool_proxy ret; };
00076 
00077   } // end of namespace mln::internal
00078 
00079 }
00080 
00081 
00082 
00083 /* FIXME: In the current implementation, the type of values on faces
00084    of different dimensions is necessarily the same (V).  We should
00085    allow different data types for vertices and edges.  */
00086 
00087 
00088 namespace mln
00089 {
00090 
00091   // Forward declaration.
00092   template <unsigned D, typename G, typename V> class complex_image;
00093 
00094   namespace internal
00095   {
00096 
00098     template <unsigned D, typename G, typename V>
00099     struct data< complex_image<D, G, V> >
00100     {
00101       data(const p_complex<D, G>& pc,
00102            const metal::vec< D + 1, std::vector<V> >& values);
00103 
00104       metal::vec< D + 1, std::vector< mlc_unbool(V) > > values_;
00105       const p_complex<D, G> pc_;
00106     };
00107 
00108   } // end of namespace mln::internal
00109 
00110 
00111   namespace trait
00112   {
00113 
00114     template <unsigned D, typename G, typename V>
00115     struct image_< complex_image<D, G, V> >
00116       : default_image_< V, complex_image<D, G, V> >
00117     {
00118       typedef trait::image::category::primary category;
00119 
00120       // FIXME: Is that right?
00121       typedef trait::image::speed::fast       speed;
00122       typedef trait::image::size::regular     size;
00123 
00124       // Value.
00125       typedef trait::image::value_access::direct           value_access;
00126       // FIXME: This image is value wise read_write, and provides
00127       // an access to its values throught a multi-set,
00128       // but we need to add the corresponding interface in the class.
00129       typedef trait::image::vw_io::none                    vw_io;
00130       typedef trait::image::vw_set::none                   vw_set;
00131       typedef trait::image::value_storage::disrupted       value_storage;
00132       typedef trait::image::value_browsing::site_wise_only value_browsing;
00133       typedef trait::image::value_alignment::irrelevant    value_alignment;
00134       typedef trait::image::value_io::read_write           value_io;
00135 
00136       // Site / domain.
00137       typedef trait::image::pw_io::read_write              pw_io;
00138       typedef trait::image::localization::space            localization;
00139       /* FIXME: Depends on G.  We could use
00140          `trait::image::space_from_point<mln_site(G)>::ret' in most
00141          cases (i.e., when G's site is a Point), but would not be
00142          generic.  */
00143       typedef typename trait::image::dimension::none    dimension;
00144 
00145       // Extended domain.
00146       typedef trait::image::ext_domain::none      ext_domain;
00147       typedef trait::image::ext_value::irrelevant ext_value;
00148       typedef trait::image::ext_io::irrelevant    ext_io;
00149     };
00150 
00151   } // end of namespace mln::trait
00152 
00153 
00163   template <unsigned D, typename G, typename V>
00164   class complex_image
00165     : public internal::image_primary< V, p_complex<D, G>,
00166                                       complex_image<D, G, V> >
00167   {
00168   public:
00170     static const unsigned dim = D;
00172     typedef G geom;
00174     typedef V value;
00175 
00177     typedef V& lvalue;
00178 
00180     typedef const V& rvalue;
00181 
00183     typedef complex_image< D, tag::psite_<G>, tag::value_<V> > skeleton;
00184 
00185   public:
00188     complex_image();
00189     complex_image(const p_complex<D, G>& pc);
00190     complex_image(const p_complex<D, G>& pc,
00191                   const metal::vec< D + 1, std::vector<V> >& values);
00193 
00195     void init_(const p_complex<D, G>& pc,
00196                const metal::vec< D + 1, std::vector<V> >& values);
00197 
00199     rvalue operator()(const complex_psite<D, G>& p) const;
00201     lvalue operator()(const complex_psite<D, G>& p);
00202 
00206     const p_complex<D, G>& domain() const;
00207 
00209     const metal::vec<D + 1, std::vector< mlc_unbool(V) > >& values() const;
00211   };
00212 
00213   // Fwd decl.
00214   template <unsigned D, typename G, typename V, typename W>
00215   void init_(tag::image_t,
00216              complex_image<D, G, V>& target,
00217              const complex_image<D, G, W>& model);
00218 
00219 
00220 # ifndef MLN_INCLUDE_ONLY
00221 
00222   /*-----------------.
00223   | Initialization.  |
00224   `-----------------*/
00225 
00226   template <unsigned D, typename G, typename V, typename W>
00227   inline
00228   void init_(tag::image_t,
00229              complex_image<D, G, V>& target,
00230              const complex_image<D, G, W>& model)
00231   {
00232     metal::vec<D + 1, std::vector<V> > values;
00233     for (unsigned i = 0; i <= D; ++i)
00234       values[i].resize(model.domain().nfaces_of_dim(i));
00235     target.init_(model.domain(), values);
00236   }
00237 
00238   /*-------.
00239   | Data.  |
00240   `-------*/
00241 
00242   namespace internal
00243   {
00244     template <unsigned D, typename G, typename V>
00245     inline
00246     data< complex_image<D, G, V> >::data(const p_complex<D, G>& pc,
00247                                          const metal::vec< D + 1, std::vector<V> >& values)
00248       : pc_(pc)
00249     {
00250       // We cannot use the initialization list for values_ (it
00251       // would not work when V = bool).
00252       for (unsigned i = 0; i <= D; ++i)
00253         {
00254           values_[i].reserve(values[i].size());
00255           values_[i].insert(values_[i].begin(),
00256                             values[i].begin(), values[i].end());
00257         }
00258 
00259       // Ensure the complex is consistent with the values.
00260       /* FIXME: We need additional macros in mln/core/contract.hh for
00261          big blocks of preconditions like this one.  */
00262 # ifndef NDEBUG
00263       for (unsigned i = 0; i < D; ++i)
00264         mln_precondition(pc.nfaces_of_dim(i) == values[i].size());
00265 # endif // !NDEBUG
00266     }
00267 
00268   } // end of namespace mln::internal
00269 
00270   /*---------------.
00271   | Construction.  |
00272   `---------------*/
00273 
00274   template <unsigned D, typename G, typename V>
00275   inline
00276   complex_image<D, G, V>::complex_image()
00277   {
00278   }
00279 
00280   template <unsigned D, typename G, typename V>
00281   inline
00282   complex_image<D, G, V>::complex_image(const p_complex<D, G>& pc)
00283   {
00284     metal::vec<D + 1, std::vector<V> > values;
00285     for (unsigned i = 0; i <= D; ++i)
00286       values[i].resize(pc.nfaces_of_dim(i));
00287     init_(pc, values);
00288   }
00289 
00290   template <unsigned D, typename G, typename V>
00291   inline
00292   complex_image<D, G, V>::complex_image(const p_complex<D, G>& pc,
00293                                         const metal::vec< D + 1,
00294                                                           std::vector<V> >& values)
00295   {
00296     init_(pc, values);
00297   }
00298 
00299   template <unsigned D, typename G, typename V>
00300   inline
00301   void
00302   complex_image<D, G, V>::init_(const p_complex<D, G>& pc,
00303                                 const metal::vec< D + 1, std::vector<V> >& values)
00304   {
00305     mln_precondition(! this->is_valid());
00306     this->data_ =
00307       new internal::data< complex_image<D, G, V> >(pc, values);
00308   }
00309 
00310   /*---------------.
00311   | Manipulation.  |
00312   `---------------*/
00313 
00314   template <unsigned D, typename G, typename V>
00315   inline
00316   typename complex_image<D, G, V>::rvalue
00317   complex_image<D, G, V>::operator()(const complex_psite<D, G>& p) const
00318   {
00319     mln_precondition(this->data_->pc_.has(p));
00320     return this->data_->values_[p.n()][p.face_id()];
00321   }
00322 
00323   template <unsigned D, typename G, typename V>
00324   inline
00325   typename complex_image<D, G, V>::lvalue
00326   complex_image<D, G, V>::operator()(const complex_psite<D, G>& p)
00327   {
00328     mln_precondition(this->data_->pc_.has(p));
00329     return this->data_->values_[p.n()][p.face_id()];
00330   }
00331 
00332   template <unsigned D, typename G, typename V>
00333   inline
00334   const metal::vec< D + 1, std::vector< mlc_unbool(V) > >&
00335   complex_image<D, G, V>::values() const
00336   {
00337     return this->data_->values_;
00338   }
00339 
00340   template <unsigned D, typename G, typename V>
00341   inline
00342   const p_complex<D, G>&
00343   complex_image<D, G, V>::domain() const
00344   {
00345     mln_precondition(this->is_valid());
00346     return this->data_->pc_;
00347   }
00348 
00349 # endif // ! MLN_INCLUDE_ONLY
00350 
00351 } // end of namespace mln
00352 
00353 # undef mlc_unbool
00354 
00355 #endif // ! MLN_CORE_IMAGE_COMPLEX_IMAGE_HH

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