$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
extension_val.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_VAL_HH
28 # define MLN_CORE_IMAGE_DMORPH_EXTENSION_VAL_HH
29 
36 
37 # include <mln/core/internal/image_identity.hh>
38 
39 
40 
41 namespace mln
42 {
43 
44  // Forward declaration.
45  template <typename I> class extension_val;
46 
47 
48  namespace internal
49  {
50 
55  template <typename I>
56  struct data< extension_val<I> >
57  {
58  data(I& ima, const mln_value(I)& val_);
59 
60  I ima_;
61  mln_value(I) val_;
62  };
63 
64  } // end of namespace mln::internal
65 
66 
67  namespace trait
68  {
69 
70  template <typename I>
71  struct image_< extension_val<I> > : 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::single ext_value;
81  typedef trait::image::ext_io::read_write ext_io;
82  };
83 
84  template <typename I, typename V>
85  struct ch_value< extension_val<I>, V >
86  {
87  typedef mlc_converts_to(mln_value(I), V) keep_ext;
88  typedef mln_ch_value(I, V) Iv;
89  typedef extension_val<Iv> 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>
103  public internal::image_identity< I, mln_domain(I), extension_val<I> >
104  {
105  public:
106 
109 
111  typedef mln_value(I) value;
112 
114  typedef mln_value(I) rvalue;
115 
116 
118  extension_val();
119 
121  extension_val(I& ima, const mln_value(I)& val);
122 
126  void init_(I& ima, const mln_value(I)& val);
128 
129 
131  // Tech note: the 'template' allows for multiple input.
132  template <typename P>
133  bool has(const P& p) const;
134 
135 
137  mln_value(I) operator()(const mln_psite(I)& p) const;
138 
140  mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
141 
142 
144  const mln_value(I)& extension() const;
145 
147  void change_extension(const mln_value(I)& val);
148  };
149 
150 
152 
153  // init_
154 
155  template <typename I, typename J>
156  void init_(tag::image_t, extension_val<I>& target, const J& model);
157 
158  template <typename V, typename I>
159  void init_(tag::extension_t, V& target, const extension_val<I>& model);
160 
162 
163 
164 # ifndef MLN_INCLUDE_ONLY
165 
166  // internal::data< extension_val<I,S> >
167 
168  namespace internal
169  {
170 
171  template <typename I>
172  inline
173  data< extension_val<I> >::data(I& ima, const mln_value(I)& val)
174  : ima_(ima),
175  val_(val)
176  {
177  }
178 
179  } // end of namespace mln::internal
180 
181  // extension_val<I>
182 
183  template <typename I>
184  inline
186  {
187  }
188 
189  template <typename I>
190  inline
191  extension_val<I>::extension_val(I& ima, const mln_value(I)& val)
192  {
193  init_(ima, val);
194  }
195 
196  template <typename I>
197  inline
198  void
199  extension_val<I>::init_(I& ima, const mln_value(I)& val)
200  {
201  this->data_ = new internal::data< extension_val<I> >(ima, val);
202  }
203 
204  template <typename I>
205  template <typename P>
206  inline
207  bool
208  extension_val<I>::has(const P&) const
209  {
210  return true;
211  }
212 
213  template <typename I>
214  inline
215  mln_value(I)
216  extension_val<I>::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 conversions.
220  if (this->data_->ima_.domain().has(p))
221  return this->data_->ima_(p);
222  else
223  return this->data_->val_;
224  }
225 
226  template <typename I>
227  inline
228  mln_morpher_lvalue(I)
229  extension_val<I>::operator()(const mln_psite(I)& p)
230  {
231  static mln_value(I) cpy;
232  mln_precondition(this->is_valid());
233  // See the above comment about if-else v. ternary.
234  if (this->data_->ima_.domain().has(p))
235  return this->data_->ima_(p);
236  else
237  {
238  // This hack makes the extension value non-modifiable.
239  cpy = this->data_->val_;
240  return cpy;
241  }
242  }
243 
244  template <typename I>
245  inline
246  const mln_value(I)&
247  extension_val<I>::extension() const
248  {
249  mln_precondition(this->is_valid());
250  return this->data_->val_;
251  }
252 
253  template <typename I>
254  inline
255  void
256  extension_val<I>::change_extension(const mln_value(I)& val)
257  {
258  mln_precondition(this->is_valid());
259  this->data_->val_ = val;
260  }
261 
262 
263  // init_
264 
265  template <typename I, typename J>
266  void init_(tag::image_t, extension_val<I>& target, const J& model)
267  {
268  I ima;
269  init_(tag::image, ima, model);
270  mln_value(I) val;
271  init_(tag::extension, val, model);
272  target.init_(ima, val);
273  }
274 
275  template <typename V, typename I>
276  void init_(tag::extension_t, V& target, const extension_val<I>& model)
277  {
278  mlc_converts_to(mln_value(I), V)::check();
279  target = static_cast<V>(model.extension());
280  }
281 
282 # endif // ! MLN_INCLUDE_ONLY
283 
284 } // end of namespace mln
285 
286 
287 #endif // ! MLN_CORE_IMAGE_DMORPH_EXTENSION_VAL_HH