Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
thru_image.hh
1 // Copyright (C) 2007, 2008, 2009, 2011 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_VMORPH_THRU_IMAGE_HH
28 # define MLN_CORE_IMAGE_VMORPH_THRU_IMAGE_HH
29 
35 
36 # include <mln/core/internal/image_value_morpher.hh>
37 # include <mln/core/concept/meta_function.hh>
38 # include <mln/metal/bexpr.hh>
39 # include <mln/trait/functions.hh>
40 
41 
42 namespace mln
43 {
44 
45  // Forward declaration.
46  template <typename I, typename F> class thru_image;
47 
48  namespace internal
49  {
50  template <typename I, typename F> class thru_image_write;
51  template <typename I, typename F> class thru_image_read;
52 
54  template <typename I, typename F>
55  struct thru_find_impl
56  {
57  typedef thru_image_write<I, F> write;
58  typedef thru_image_read<I, F> read;
59  typedef mlc_if(mlc_and(mln_trait_fun_is_assignable(F),
60  mlc_and(mlc_not(mlc_is_const(I)),
61  mlc_equal(mln_trait_image_pw_io(I),
62  trait::image::pw_io::read_write))),
63  write, read) ret;
64  };
65 
67  template <typename I, typename F>
68  struct data< thru_image<I, F> >
69  {
70  data(I& ima, const F& f);
71 
72  I ima_;
73  F f_;
74  };
75 
76  } // end of namespace mln::internal
77 
78 
79  namespace trait
80  {
81 
82  template <typename I, typename F>
83  struct image_< thru_image<I, F> > : image_< typename mln::internal::thru_find_impl<I, F>::ret > // Same as I except...
84  {
85  // ...these changes.
86  typedef trait::image::category::value_morpher category;
87  typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
88  typedef trait::image::value_access::computed value_access;
89  };
90 
91  template <typename I, typename F>
92  struct image_< mln::internal::thru_image_write<I, F> > : image_< I > // Same as I except...
93  {
94  typedef trait::image::vw_io::read_write vw_io;
95  };
96 
97  template <typename I, typename F>
98  struct image_< mln::internal::thru_image_read<I, F> > : image_< I > // Same as I except...
99  {
100  typedef trait::image::vw_io::read vw_io;
101  };
102 
103  } // end of namespace mln::trait
104 
105 
106 
107  // FIXME: Doc!
108 
109  namespace internal
110  {
111 
112  template <typename I, typename F>
113  class thru_image_read : public internal::image_value_morpher< I, typename F::result, thru_image<I,F> >
114  {
115  public:
116 
118  typedef thru_image<tag::image_<I>, F> skeleton;
119 
121  typedef mln_psite(I) psite;
122 
124  typedef mln_result(F) value;
125 
127  typedef value rvalue;
128  typedef value lvalue; // Workaround for write operator()
129 
130  rvalue operator()(const mln_psite(I)& p) const;
131  rvalue operator()(const mln_psite(I)& p);
132 
133  };
134 
135  // Inheritance from read ?!
136  template <typename I, typename F>
137  class thru_image_write : public thru_image_read<I,F>
138  {
139  public:
140 
142 // typedef typename F::template lresult<typename F::argument>::ret lvalue;
143  typedef typename F::lresult lvalue;
144 
145  using thru_image_read<I,F>::operator();
146  lvalue operator()(const mln_psite(I)& p);
147 
148  };
149  }
150 
154  //
155  template <typename I, typename F>
156  class thru_image : public internal::thru_find_impl<I, F>::ret
157  {
158  public:
159 
160  thru_image();
161  thru_image(I& ima);
162  thru_image(I& ima, const F& f);
163 
164  void init_(I& ima, const F& f);
165 
167  operator thru_image<const I, F>() const;
168  };
169 
170  template <typename I, typename F>
171  thru_image<I, F> thru(const mln::Function<F>& f,
172  Image<I>& ima);
173 
174  template <typename I, typename F>
175  const thru_image<const I, F> thru(const mln::Function<F>& f,
176  const Image<I>& ima);
177 
178  template <typename I, typename M>
180  thru(const mln::Meta_Function<M>& f, Image<I>& ima);
181 
182  template <typename I, typename M>
184  thru(const mln::Meta_Function<M>& f, const Image<I>& ima);
185 
186 # ifndef MLN_INCLUDE_ONLY
187 
188  // internal::data< thru_image<I,S> >
189 
190  namespace internal
191  {
192 
193  template <typename I, typename F>
194  inline
195  data< thru_image<I, F> >::data(I& ima, const F& f)
196  : ima_(ima),
197  f_(f)
198  {
199  }
200 
201  } // end of namespace mln::internal
202 
203  // thru_image<I>
204 
205  template <typename I, typename F>
206  inline
207  thru_image<I, F>::thru_image()
208  {
209  }
210 
211  template <typename I, typename F>
212  inline
213  thru_image<I, F>::thru_image(I& ima, const F& f)
214  {
215  mln_precondition(ima.is_valid());
216  init_(ima, f);
217  }
218 
219  template <typename I, typename F>
220  inline
221  thru_image<I, F>::thru_image(I& ima)
222  {
223  mln_precondition(ima.is_valid());
224  init_(ima, F());
225  }
226 
227  template <typename I, typename F>
228  inline
229  void
230  thru_image<I, F>::init_(I& ima, const F& f)
231  {
232  mln_precondition(! this->is_valid());
233  mln_precondition(ima.is_valid());
234  this->data_ = new internal::data< thru_image<I, F> >(ima, f);
235  }
236 
237  template <typename I, typename F>
238  inline
240  {
241  thru_image<const I, F> tmp(this->data_->ima_, this->data_->f_);
242  return tmp;
243  }
244 
245  namespace internal
246  {
247 
248  template <typename I, typename F>
249  inline
250  typename thru_image_read<I, F>::rvalue
251  thru_image_read<I, F>::operator()(const mln_psite(I)& p) const
252  {
253  mln_precondition(this->is_valid());
254  return this->data_->f_(this->data_->ima_(p));
255  }
256 
257  template <typename I, typename F>
258  inline
259  typename thru_image_read<I, F>::rvalue
260  thru_image_read<I, F>::operator()(const mln_psite(I)& p)
261  {
262  mln_precondition(this->is_valid());
263  return this->data_->f_(this->data_->ima_(p));
264  }
265 
266  template <typename I, typename F>
267  inline
268  typename thru_image_write<I, F>::lvalue
269  thru_image_write<I, F>::operator()(const mln_psite(I)& p)
270  {
271  mln_precondition(this->is_valid());
272  return this->data_->f_(this->data_->ima_(p));
273  }
274 
275  }
276 
277  // thru
278  template <typename I, typename F>
279  thru_image<I, F> thru(const mln::Function<F>& f,
280  Image<I>& ima)
281  {
282  thru_image<I, F> tmp(exact(ima), exact(f));
283  return tmp;
284  }
285 
286  template <typename I, typename F>
287  thru_image<const I, F> thru(const mln::Function<F>& f,
288  const Image<I>& ima)
289  {
290  thru_image<const I, F> tmp(exact(ima), exact(f));
291  return tmp;
292  }
293 
294  template <typename I, typename M>
295  thru_image<I, mln_fun_with(M, mln_value(I))>
296  thru(const mln::Meta_Function<M>& f, Image<I>& ima)
297  {
298  typedef mln_fun_with(M, mln_value(I)) F;
299  thru_image<I, F> tmp(exact(ima), F(exact(f).state()));
300 
301  return tmp;
302  }
303 
304  template <typename I, typename M>
305  thru_image<const I, mln_fun_with(M, mln_value(I))>
306  thru(const mln::Meta_Function<M>& f, const Image<I>& ima)
307  {
308  typedef mln_fun_with(M, mln_value(I)) F;
309  thru_image<const I, F> tmp(exact(ima), F(exact(f).state()));
310 
311  return tmp;
312  }
313 
314 # endif // ! MLN_INCLUDE_ONLY
315 
316 } // end of namespace mln
317 
318 
319 #endif // ! MLN_CORE_IMAGE_VMORPH_THRU_IMAGE_HH