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