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