$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
from_to.hh
1 // Copyright (C) 2008, 2009, 2010, 2012 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_CONVERT_FROM_TO_HH
28 # define MLN_CONVERT_FROM_TO_HH
29 
39 
40 # include <mln/convert/impl/all.hh>
41 
42 # include <mln/metal/abort.hh>
43 # include <mln/metal/converts_to.hh>
44 # include <mln/metal/is.hh>
45 # include <mln/metal/is_a.hh>
46 
47 # include <mln/value/cast.hh>
48 
49 namespace mln
50 {
51 
52  // Forward declarations.
53  template <typename E> struct Object;
54  template <typename E> struct Value;
55  template <typename E> struct Site_Set;
56  template <typename E> struct Image;
57 
58  namespace convert
59  {
60 
61  template <typename F, typename T>
62  void
63  from_to(const F& from, T& to);
64 
65 
66  } // end of namespace mln::convert
67 
68 } // end of namespace mln
69 
70 
71 # ifndef MLN_INCLUDE_ONLY
72 
73 // Exact same type.
74 template <typename T>
75 inline
76 void
77 from_to_(const T& from, T& to)
78 {
79  to = from;
80 }
81 
82 
83 // Default conversion.
84 template <typename F, typename T>
85 inline
86 void
87 from_to_(const F& from, T& to)
88 {
89  to = mln::value::cast<T>(from);
90 }
91 
92 
93 namespace mln
94 {
95 
96  // Exact same type.
97  template <typename T>
98  inline
99  void
100  from_to_(const T& from, T& to)
101  {
102  to = from;
103  }
104 
105 
106  // Object -> Object (F not convertible towards T)
107  // No conversion exists!
108  template <typename F, typename T>
109  void
110  from_to_(const Object<F>&, Object<T>&)
111  {
112  // This particular from-to is not defined!
113  //
114  // Either this conversion is meaningless or an overload is
115  // missing.
116  mlc_abort(F)::check();
117  }
118 
119 
120  namespace convert
121  {
122 
123  namespace internal
124  {
125 
126  // Dispatch to specific implementation.
127 
128  // Image -> Site_Set.
129  template <typename I, typename S>
130  inline
131  void
132  from_to_dispatch(const Image<I>& from, Site_Set<S>& to)
133  {
134  mlc_is(mln_trait_site_set_contents(S),
135  mln::trait::site_set::contents::dynamic)::check();
136  mln_precondition(exact(from).is_valid());
138  }
139 
140 
141  // Site_Set -> Image.
142  template <typename S, typename I>
143  inline
144  void
145  from_to_dispatch(const Site_Set<S>& from, Image<I>& to)
146  {
147  mlc_converts_to(mln_site(S), mln_site(I))::check(); // FIXME: Is it too restrictive?
148  mln_precondition(exact(from).is_valid());
150  }
151 
152 
153  // Value -> Value
154  template <typename F, typename T>
155  inline
156  void
157  from_to_dispatch(const Value<F>& from, Value<T>& to)
158  {
160  }
161 
162 
163 
164  // Dispatch related to convertible objects.
165 
166  // F -> T
167  // if F convertible to T.
168  template <typename F, typename T>
169  inline
170  void
171  from_to_dispatch(metal::true_,
172  const Object<F>& from, Object<T>& to)
173  {
174  exact(to) = exact(from);
175  }
176 
177 
178  // F is NOT convertible to T.
179  template <typename F, typename T>
180  inline
181  void
182  from_to_dispatch(metal::false_,
183  const Object<F>& from, Object<T>& to)
184  {
185  from_to_(exact(from), exact(to));
186  }
187 
188 
189 
190  // Default dispatch if the two arguments are objects.
191 
192  // Object -> Object
193  template <typename F, typename T>
194  inline
195  void
196  from_to_dispatch(const Object<F>& from, Object<T>& to)
197  {
198  typedef mlc_converts_to(F, T) F_converts_to_T; // FIXME: HERE we've got a problem with g++-2.95.
199  internal::from_to_dispatch(F_converts_to_T(),
200  exact(from), exact(to));
201  }
202 
203  // Object -> Object
204  template <typename T>
205  inline
206  void
207  from_to_dispatch(const Object<T>& from, Object<T>& to)
208  {
209  // // Here we would like to call from_to_ overloads in order
210  // to let the user specify its own conversion
211  // function. However, doing so may lead to ambiguous
212  // prototypes between from_to_(Object<>, Object<>) and
213  // from_to_(T, T).
214  // from_to_(exact(from), exact(to));
215  exact(to) = exact(from);
216  }
217 
218 
219 
220  // Dispatch entry points.
221  // Check whether arguments are an object or not.
222 
223  // Builtin -> Builtin
224  template <typename F, typename T>
225  inline
226  void
227  from_to_dispatch(metal::false_, const F& from,
228  metal::false_, T& to)
229  {
230  from_to_(from, to);
231  }
232 
233 
234  // Object -> Builtin
235  template <typename F, typename T>
236  inline
237  void
238  from_to_dispatch(metal::true_, const F& from,
239  metal::false_, T& to)
240  {
241  from_to_(exact(from), to);
242  }
243 
244 
245  // Builtin -> Object
246  template <typename F, typename T>
247  inline
248  void
249  from_to_dispatch(metal::false_, const F& from,
250  metal::true_, T& to)
251  {
252  from_to_(from, exact(to));
253  }
254 
255  // Object -> Object
256  template <typename F, typename T>
257  inline
258  void
259  from_to_dispatch(metal::true_, const F& from,
260  metal::true_, T& to)
261  {
262  internal::from_to_dispatch(exact(from), exact(to));
263  }
264 
265 
266  } // end of namespace mln::convert::internal
267 
268 
269  // Facade
270 
271  template <typename F, typename T>
272  inline
273  void
274  from_to(const F& from, T& to)
275  {
276  typedef mlc_is_a(F, Object) F_is_object;
277  typedef mlc_is_a(T, Object) T_is_object;
278  internal::from_to_dispatch(F_is_object(), from,
279  T_is_object(), to);
280  }
281 
282 
283  } // end of namespace mln::convert
284 
285 } // end of namespace mln
286 
287 # endif // ! MLN_INCLUDE_ONLY
288 
289 
290 #endif // ! MLN_CONVERT_FROM_TO_HH