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

from_to.hh

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

Generated on Thu Sep 8 2011 18:31:51 for Milena (Olena) by  doxygen 1.7.1