$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
extension_fun.hh
1 // Copyright (C) 2008, 2009, 2011, 2012, 2013 EPITA Research and
2 // Development 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_DMORPH_EXTENSION_FUN_HH
28 # define MLN_CORE_IMAGE_DMORPH_EXTENSION_FUN_HH
29 
37 
38 # include <mln/core/internal/image_identity.hh>
39 
40 
41 
42 namespace mln
43 {
44 
45  // Forward declaration.
46  template <typename I, typename F> class extension_fun;
47 
48 
49  namespace internal
50  {
51 
55  template <typename I, typename F>
56  struct data< extension_fun<I, F> >
57  {
58  data(I& ima, const F& fun);
59 
60  I ima_;
61  const F fun_;
62  };
63 
64  } // end of namespace mln::internal
65 
66 
67  namespace trait
68  {
69 
70  template <typename I, typename F>
71  struct image_< extension_fun<I, F> > : image_< I > // Same as I except...
72  {
73  // ...these changes.
74  typedef trait::image::category::identity_morpher category;
75  typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
76  typedef trait::image::value_access::indirect value_access;
77 
78  // extended domain
79  typedef trait::image::ext_domain::infinite ext_domain;
80  typedef trait::image::ext_value::multiple ext_value;
81  typedef trait::image::ext_io::read_only ext_io;
82  };
83 
84  template <typename I, typename F, typename V>
85  struct ch_value< extension_fun<I, F>, V >
86  {
87  typedef mlc_converts_to(mln_result(F), V) keep_ext;
88  typedef mln_ch_value(I, V) Iv;
89  typedef extension_fun<Iv, F> Iv_ext;
90  typedef mlc_if(keep_ext, Iv_ext, Iv) ret;
91  };
92 
93  } // end of namespace mln::trait
94 
95 
96 
100  //
101  template <typename I, typename F>
103  : public internal::image_identity< I, mln_domain(I), extension_fun<I, F> >,
104  private mlc_converts_to(mln_result(F), mln_value(I))::check_t
105  {
106  public:
107 
109  typedef extension_fun< tag::image_<I>, tag::function_<F> > skeleton;
110 
112  typedef mln_value(I) value;
113 
115  typedef mln_value(I) rvalue;
116 
117 
119  extension_fun();
120 
122  extension_fun(I& ima, const F& fun);
123 
127  void init_(I& ima, const F& fun);
129 
130 
133  // Tech note: the 'template' allows for multiple input.
134  template <typename P>
135  bool has(const P& p) const;
136 
137 
139  mln_value(I) operator()(const mln_psite(I)& p) const;
140 
142  mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
143 
144 
146  const F& extension() const;
147  };
148 
149 
151 
152  // init_
153 
154  template <typename I, typename F, typename J>
155  void init_(tag::image_t, extension_fun<I,F>& target, const J& model);
156 
157  template <typename F, typename I>
158  void init_(tag::extension_t, F& target, const extension_fun<I,F>& model);
159 
161 
162 
163 # ifndef MLN_INCLUDE_ONLY
164 
165  // internal::data< extension_fun<I,S> >
166 
167  namespace internal
168  {
169 
170  template <typename I, typename F>
171  inline
172  data< extension_fun<I, F> >::data(I& ima, const F& fun)
173  : ima_(ima),
174  fun_(fun)
175  {
176  }
177 
178  } // end of namespace mln::internal
179 
180 
181  // extension_fun<I, F>
182 
183  template <typename I, typename F>
184  inline
186  {
187  }
188 
189  template <typename I, typename F>
190  inline
191  extension_fun<I, F>::extension_fun(I& ima, const F& fun)
192  {
193  init_(ima, fun);
194  }
195 
196  template <typename I, typename F>
197  inline
198  void
199  extension_fun<I, F>::init_(I& ima, const F& fun)
200  {
201  this->data_ = new internal::data< extension_fun<I, F> >(ima, fun);
202  }
203 
204  template <typename I, typename F>
205  template <typename P>
206  inline
207  bool
208  extension_fun<I, F>::has(const P&) const
209  {
210  return true;
211  }
212 
213  template <typename I, typename F>
214  inline
215  mln_value(I)
216  extension_fun<I, F>::operator()(const mln_psite(I)& p) const
217  {
218  mln_precondition(this->is_valid());
219  // if-else is preferred to the ternary op to allow for the
220  // function result to convert towards the expected return type.
221  if (this->data_->ima_.domain().has(p))
222  return this->data_->ima_(p);
223  else
224  return this->data_->fun_(p);
225  }
226 
227  template <typename I, typename F>
228  inline
229  mln_morpher_lvalue(I)
230  extension_fun<I, F>::operator()(const mln_psite(I)& p)
231  {
232  static mln_value(I) cpy;
233  mln_precondition(this->is_valid());
234  // See the above comment about if-else v. ternary.
235  if (this->data_->ima_.domain().has(p))
236  return this->data_->ima_(p);
237  else
238  {
239  // This hack makes this signature valid both in the image
240  // domain and in its extension. It works even if
241  // mln_morpher_lvalue(I) is a mutable reference.
242  cpy = this->data_->fun_(p);
243  return cpy;
244  }
245  }
246 
247  template <typename I, typename F>
248  inline
249  const F&
250  extension_fun<I, F>::extension() const
251  {
252  mln_precondition(this->is_valid());
253  return this->data_->fun_;
254  }
255 
256 
257  // init_
258 
259  template <typename I, typename F, typename J>
260  void init_(tag::image_t, extension_fun<I,F>& target, const J& model)
261  {
262  I ima;
263  init_(tag::image, ima, model);
264  F fun;
265  init_(tag::extension, fun, model);
266  target.init_(ima, fun);
267  }
268 
269  template <typename F, typename I>
270  void init_(tag::extension_t, F& target, const extension_fun<I,F>& model)
271  {
272  target = model.extension();
273  }
274 
275 # endif // ! MLN_INCLUDE_ONLY
276 
277 } // end of namespace mln
278 
279 
280 #endif // ! MLN_CORE_IMAGE_DMORPH_EXTENSION_FUN_HH