Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
extension_val.hh
1 // Copyright (C) 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_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 
52  template <typename I>
53  struct data< extension_val<I> >
54  {
55  data(I& ima, const mln_value(I)& val_);
56 
57  I ima_;
58  mln_value(I) val_;
59  };
60 
61  } // end of namespace mln::internal
62 
63 
64  namespace trait
65  {
66 
67  template <typename I>
68  struct image_< extension_val<I> > : image_< I > // Same as I except...
69  {
70  // ...these changes.
71  typedef trait::image::category::identity_morpher category;
72  typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
73  typedef trait::image::value_access::indirect value_access;
74 
75  // extended domain
76  typedef trait::image::ext_domain::infinite ext_domain;
77  typedef trait::image::ext_value::single ext_value;
78  typedef trait::image::ext_io::read_write ext_io;
79  };
80 
81  template <typename I, typename V>
82  struct ch_value< extension_val<I>, V >
83  {
84  typedef mlc_converts_to(mln_value(I), V) keep_ext;
85  typedef mln_ch_value(I, V) Iv;
86  typedef extension_val<Iv> Iv_ext;
87  typedef mlc_if(keep_ext, Iv_ext, Iv) ret;
88  };
89 
90  } // end of namespace mln::trait
91 
92 
93 
97  //
98  template <typename I>
99  class extension_val :
100  public internal::image_identity< I, mln_domain(I), extension_val<I> >
101  {
102  public:
103 
106 
108  typedef mln_value(I) value;
109 
111  typedef mln_value(I) rvalue;
112 
113 
115  extension_val();
116 
118  extension_val(I& ima, const mln_value(I)& val);
119 
122  void init_(I& ima, const mln_value(I)& val);
123 
124 
126  // Tech note: the 'template' allows for multiple input.
127  template <typename P>
128  bool has(const P& p) const;
129 
130 
132  mln_value(I) operator()(const mln_psite(I)& p) const;
133 
135  mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
136 
137 
139  const mln_value(I)& extension() const;
140 
142  void change_extension(const mln_value(I)& val);
143  };
144 
145 
146  // init_
147 
148  template <typename I, typename J>
149  void init_(tag::image_t, extension_val<I>& target, const J& model);
150 
151  template <typename V, typename I>
152  void init_(tag::extension_t, V& target, const extension_val<I>& model);
153 
154 
155 
156 # ifndef MLN_INCLUDE_ONLY
157 
158  // internal::data< extension_val<I,S> >
159 
160  namespace internal
161  {
162 
163  template <typename I>
164  inline
165  data< extension_val<I> >::data(I& ima, const mln_value(I)& val)
166  : ima_(ima),
167  val_(val)
168  {
169  }
170 
171  } // end of namespace mln::internal
172 
173  // extension_val<I>
174 
175  template <typename I>
176  inline
178  {
179  }
180 
181  template <typename I>
182  inline
183  extension_val<I>::extension_val(I& ima, const mln_value(I)& val)
184  {
185  init_(ima, val);
186  }
187 
188  template <typename I>
189  inline
190  void
191  extension_val<I>::init_(I& ima, const mln_value(I)& val)
192  {
193  this->data_ = new internal::data< extension_val<I> >(ima, val);
194  }
195 
196  template <typename I>
197  template <typename P>
198  inline
199  bool
200  extension_val<I>::has(const P&) const
201  {
202  return true;
203  }
204 
205  template <typename I>
206  inline
207  mln_value(I)
208  extension_val<I>::operator()(const mln_psite(I)& p) const
209  {
210  mln_precondition(this->is_valid());
211  // if-else is preferred to the ternary op to allow conversions.
212  if (this->data_->ima_.domain().has(p))
213  return this->data_->ima_(p);
214  else
215  return this->data_->val_;
216  }
217 
218  template <typename I>
219  inline
220  mln_morpher_lvalue(I)
221  extension_val<I>::operator()(const mln_psite(I)& p)
222  {
223  static mln_value(I) cpy;
224  mln_precondition(this->is_valid());
225  // See the above comment about if-else v. ternary.
226  if (this->data_->ima_.domain().has(p))
227  return this->data_->ima_(p);
228  else
229  {
230  // This hack makes the extension value non-modifiable.
231  cpy = this->data_->val_;
232  return cpy;
233  }
234  }
235 
236  template <typename I>
237  inline
238  const mln_value(I)&
240  {
241  mln_precondition(this->is_valid());
242  return this->data_->val_;
243  }
244 
245  template <typename I>
246  inline
247  void
248  extension_val<I>::change_extension(const mln_value(I)& val)
249  {
250  mln_precondition(this->is_valid());
251  this->data_->val_ = val;
252  }
253 
254 
255  // init_
256 
257  template <typename I, typename J>
258  void init_(tag::image_t, extension_val<I>& target, const J& model)
259  {
260  I ima;
261  init_(tag::image, ima, model);
262  mln_value(I) val;
263  init_(tag::extension, val, model);
264  target.init_(ima, val);
265  }
266 
267  template <typename V, typename I>
268  void init_(tag::extension_t, V& target, const extension_val<I>& model)
269  {
270  mlc_converts_to(mln_value(I), V)::check();
271  target = static_cast<V>(model.extension());
272  }
273 
274 # endif // ! MLN_INCLUDE_ONLY
275 
276 } // end of namespace mln
277 
278 
279 #endif // ! MLN_CORE_IMAGE_DMORPH_EXTENSION_VAL_HH