• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

from_to.hh

00001 // Copyright (C) 2008, 2009, 2010 EPITA Research and Development
00002 // Laboratory (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
00026 
00027 #ifndef MLN_CONVERT_FROM_TO_HH
00028 # define MLN_CONVERT_FROM_TO_HH
00029 
00039 
00040 # include <mln/convert/impl/all.hh>
00041 # include <mln/convert/from_to.hxx>
00042 
00043 # include <mln/metal/abort.hh>
00044 # include <mln/metal/converts_to.hh>
00045 # include <mln/metal/is.hh>
00046 # include <mln/metal/is_a.hh>
00047 
00048 # include <mln/value/cast.hh>
00049 
00050 namespace mln
00051 {
00052 
00053   // Forward declarations.
00054   template <typename E> struct Object;
00055   template <typename E> struct Value;
00056   template <typename E> struct Site_Set;
00057   template <typename E> struct Image;
00058 
00059   namespace convert
00060   {
00061 
00062     template <typename F, typename T>
00063     void
00064     from_to(const F& from, T& to);
00065 
00066 
00067 # ifndef MLN_INCLUDE_ONLY
00068 
00069     namespace internal
00070     {
00071 
00072       // Dispatch to specific implementation.
00073 
00074       // Image -> Site_Set.
00075       template <typename I, typename S>
00076       inline
00077       void
00078       from_to_dispatch(const Image<I>& from, Site_Set<S>& to)
00079       {
00080         mlc_is(mln_trait_site_set_contents(S),
00081             mln::trait::site_set::contents::dynamic)::check();
00082         mln_precondition(exact(from).is_valid());
00083         mln::convert::impl::from_image_to_site_set(from, to);
00084       }
00085 
00086 
00087       // Site_Set -> Image.
00088       template <typename S, typename I>
00089       inline
00090       void
00091       from_to_dispatch(const Site_Set<S>& from, Image<I>& to)
00092       {
00093         mlc_converts_to(mln_site(S), mln_site(I))::check(); // FIXME: Is it too restrictive?
00094         mln_precondition(exact(from).is_valid());
00095         mln::convert::impl::from_site_set_to_image(from, to);
00096       }
00097 
00098 
00099       // Value -> Value
00100       template <typename F, typename T>
00101       inline
00102       void
00103       from_to_dispatch(const Value<F>& from, Value<T>& to)
00104       {
00105         mln::convert::impl::from_value_to_value(from, to);
00106       }
00107 
00108 
00109 
00110       // Dispatch related to convertible objects.
00111 
00112       // F -> T
00113       // if F convertible to T.
00114       template <typename F, typename T>
00115       inline
00116       void
00117       from_to_dispatch(metal::true_,
00118                        const Object<F>& from, Object<T>& to)
00119       {
00120         exact(to) = exact(from);
00121       }
00122 
00123 
00124       // F is NOT convertible to T.
00125       template <typename F, typename T>
00126       inline
00127       void
00128       from_to_dispatch(metal::false_,
00129                        const Object<F>& from, Object<T>& to)
00130       {
00131         over_load::from_to_(exact(from), exact(to));
00132       }
00133 
00134 
00135 
00136       // Default dispatch if the two arguments are objects.
00137 
00138       // Object -> Object
00139       template <typename F, typename T>
00140       inline
00141       void
00142       from_to_dispatch(const Object<F>& from, Object<T>& to)
00143       {
00144         typedef mlc_converts_to(F, T) F_converts_to_T; // FIXME: HERE we've got a problem with g++-2.95.
00145         internal::from_to_dispatch(F_converts_to_T(),
00146                                    exact(from), exact(to));
00147       }
00148 
00149 
00150 
00151       // Dispatch entry points.
00152       // Check whether arguments are an object or not.
00153 
00154       // Builtin -> Builtin
00155       template <typename F, typename T>
00156       inline
00157       void
00158       from_to_dispatch(metal::false_,  const F& from,
00159                        metal::false_,  T&       to)
00160       {
00161         over_load::from_to_(from, to);
00162       }
00163 
00164 
00165       // Object -> Builtin
00166       template <typename F, typename T>
00167       inline
00168       void
00169       from_to_dispatch(metal::true_,  const F& from,
00170                        metal::false_, T&       to)
00171       {
00172         over_load::from_to_(exact(from), to);
00173       }
00174 
00175 
00176       // Builtin -> Object
00177       template <typename F, typename T>
00178       inline
00179       void
00180       from_to_dispatch(metal::false_, const F& from,
00181                        metal::true_,  T&       to)
00182       {
00183         over_load::from_to_(from, exact(to));
00184       }
00185 
00186       // Object -> Object
00187       template <typename F, typename T>
00188       inline
00189       void
00190       from_to_dispatch(metal::true_,  const F& from,
00191                        metal::true_,  T&       to)
00192       {
00193         internal::from_to_dispatch(exact(from), exact(to));
00194       }
00195 
00196 
00197     } // end of namespace mln::convert::internal
00198 
00199 
00200     namespace over_load
00201     {
00202 
00203 
00204       // Object -> Object (F not convertible towards T)
00205       // No conversion exists!
00206       template <typename F, typename T>
00207       void
00208       from_to_(const Object<F>&, Object<T>&)
00209       {
00210         // This particular from-to is not defined!
00211         //
00212         // Either this conversion is meaningless or an overload is
00213         // missing.
00214         mlc_abort(F)::check();
00215       }
00216 
00217 
00218       // Object -> Object
00219       template <typename T>
00220       inline
00221       void
00222       from_to_(const Object<T>& from, Object<T>& to)
00223       {
00224         exact(to) = exact(from);
00225       }
00226 
00227 
00228       // Exact same type.
00229       template <typename T>
00230       inline
00231       void
00232       from_to_(const T& from, T& to)
00233       {
00234         to = from;
00235       }
00236 
00237 
00238       // Default conversion.
00239       template <typename F, typename T>
00240       inline
00241       void
00242       from_to_(const F& from, T& to)
00243       {
00244         to = mln::value::cast<T>(from);
00245       }
00246 
00247 
00248     } // end of namespace mln::convert::over_load
00249 
00250 
00251 
00252     // Facade
00253 
00254     template <typename F, typename T>
00255     inline
00256     void
00257     from_to(const F& from, T& to)
00258     {
00259       typedef mlc_is_a(F, Object) F_is_object;
00260       typedef mlc_is_a(T, Object) T_is_object;
00261       internal::from_to_dispatch(F_is_object(), from,
00262                                  T_is_object(), to);
00263     }
00264 
00265 
00266 # endif // ! MLN_INCLUDE_ONLY
00267 
00268   } // end of namespace mln::convert
00269 
00270 } // end of namespace mln
00271 
00272 
00273 #endif // ! MLN_CONVERT_FROM_TO_HH

Generated on Tue Oct 4 2011 15:23:47 for Milena (Olena) by  doxygen 1.7.1