Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
lazy_image.hh
1 // Copyright (C) 2007, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_CORE_IMAGE_IMORPH_LAZY_IMAGE_HH
27 # define MLN_CORE_IMAGE_IMORPH_LAZY_IMAGE_HH
28 
32 
33 
34 # include <cmath>
35 
36 # include <mln/core/internal/image_identity.hh>
37 # include <mln/core/alias/box2d.hh>
38 
39 
40 namespace mln
41 {
42 
43  // Forward declaration.
44  template <typename I, typename F, typename B> struct lazy_image;
45 
46  namespace internal
47  {
48 
50  template <typename I, typename F, typename B>
51  struct data< lazy_image<I,F,B> >
52  {
53  data(const F& fun_, const B& box);
54 
55  mutable mln_ch_value(I,mln_result(F)) ima_;
56  mutable mln_ch_value(I,bool) is_known;
57  const F& fun;
58  const B& bb_;
59  };
60 
61  } // end of namespace mln::internal
62 
63 
64 
65  namespace trait
66  {
67 
68  template <typename I, typename F, typename B>
69  struct image_< lazy_image<I,F,B> > : default_image_morpher< I, mln_value(I),
70  lazy_image<I,F,B> >
71  {
72  typedef trait::image::category::domain_morpher category;
73  typedef trait::image::value_io::read_only value_io;
74  };
75 
76  } // end of namespace mln::trait
77 
78 
79 
91  template <typename I, typename F, typename B>
92  struct lazy_image :
93  public mln::internal::image_identity< mln_ch_value(I, mln_result(F)),
94  mln_domain(I), lazy_image<I, F,B> >
95  {
96  typedef mln::internal::image_identity< mln_ch_value(I, mln_result(F)),
97  mln_domain(I),
98  lazy_image<I, F,B> > super_;
99 
101  typedef mln_result(F) rvalue;
102 
104  typedef mln_result(F) lvalue;
105 
107  typedef lazy_image< tag::image_<I>, F, B > skeleton;
108 
110  using super_::is_valid;
111 
113  lazy_image();
114 
116  lazy_image(const F& fun, const B& box);
117 
119  void init_(const F& fun, const B& box);
120 
122  const box<mln_psite(I)>& domain() const;
123 
125  bool has(const mln_psite(I)&) const;
126 
128  mln_result(F) operator()(const typename F::input& x) const;
129 
131  mln_result(F) operator()(const typename F::input& x);
132 
134  rvalue operator()(const mln_psite(I)& p) const;
135 
137  lvalue operator()(const mln_psite(I)& p);
138 
139  };
140 
141 
142 
143 # ifndef MLN_INCLUDE_ONLY
144 
145  namespace internal
146  {
147 
148  // internal::data< lazy_image<I,S> >
149 
150  template <typename I, typename F, typename B>
151  inline
152  data< lazy_image<I,F,B> >::data(const F& fun, const B& box)
153  : ima_(box), is_known(box), fun(fun), bb_(box)
154  {
155  }
156 
157  } // end of namespace mln::internal
158 
159  template <typename I, typename F, typename B>
160  inline
161  lazy_image<I,F,B>::lazy_image(const F& fun, const B& box)
162  {
163  this->data_ = new internal::data< lazy_image<I,F,B> >(fun, box);
164  }
165 
166  template <typename I, typename F, typename B>
167  inline
168  void lazy_image<I,F,B>::init_(const F& fun, const B& box)
169  {
170  this->data_ = new internal::data< lazy_image<I,F,B> >(fun, box);
171  }
172 
173  template <typename I, typename F, typename B>
174  inline
175  bool lazy_image<I,F,B>::has(const mln_psite(I)& p) const
176  {
177  return this->data_->ima_.has(p);
178  }
179 
180  template <typename I, typename F, typename B>
181  inline
182  mln_result(F)
183  lazy_image<I,F,B>::operator()(const typename F::input& p) const
184  {
185  mln_assertion(this->has(p));
186  if (this->data_->is_known(p))
187  return this->data_->ima_(p);
188  this->data_->ima_(p) = this->data_->fun(p);
189  this->data_->is_known(p) = true;
190  return this->data_->ima_(p);
191  }
192 
193 
194  template <typename I, typename F, typename B>
195  inline
196  mln_result(F)
197  lazy_image<I,F,B>::operator()(const typename F::input& p)
198  {
199  mln_assertion(this->has(p));
200  if (this->data_->is_known(p))
201  return this->data_->ima_(p);
202  this->data_->ima_(p) = this->data_->fun(p);
203  this->data_->is_known(p) = true;
204  return this->data_->ima_(p);
205  }
206 
207  template <typename I, typename F, typename B>
208  inline
210  lazy_image<I,F,B>::operator()(const mln_psite(I)& p) const
211  {
212  return (*this).operator()(convert::to< typename F::input >(p));
213  }
214 
215  template <typename I, typename F, typename B>
216  inline
218  lazy_image<I,F,B>::operator()(const mln_psite(I)& p)
219  {
220  return (*this).operator()(convert::to< typename F::input >(p));
221  }
222 
223  template <typename I, typename F, typename B>
224  inline
225  const box<mln_psite(I)>&
227  {
228  return this->data_->bb_;
229  }
230 
231 # endif // ! MLN_INCLUDE_ONLY
232 
233 } // end of namespace mln
234 
235 
236 #endif // ! MLN_CORE_IMAGE_IMORPH_LAZY_IMAGE_HH