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

composition.hh

00001 // Copyright (C) 2007, 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_FUN_COMPOSITION_HH
00027 # define MLN_FUN_COMPOSITION_HH
00028 
00029 # include <mln/fun/unary.hh>
00030 # include <mln/fun/binary.hh>
00031 # include <mln/fun/param.hh>
00032 
00033 namespace mln
00034 {
00035   // Composition
00036   namespace fun
00037   {
00038 
00039     namespace internal
00040     {
00041 
00042       // Compositions may take this has initialization parameter
00043       template <typename F, typename G>
00044       struct composition_param
00045       {
00046         composition_param(const F& f, const G& g) : f_(f), g_(g) {}
00047         composition_param() {}
00048 
00049         F f_;
00050         G g_;
00051       };
00052 
00053       // Composition types...
00054       template <template <class> class CatF,  typename F,
00055                 template <class> class CatG, typename G>
00056       struct composition;
00057 
00058     } // end of namespace mln::fun::internal
00059 
00060     template <template <class> class CatF,  typename F,
00061               template <class> class CatG, typename G>
00062     struct parameter< internal::composition<CatF, F, CatG, G> >
00063     {
00064       typedef internal::composition_param<F, G> param;
00065     };
00066 
00067     namespace internal
00068     {
00069 
00070       // Meta
00071       template <typename F, typename G>
00072       struct composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>
00073       : mln::fun::unary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G> >
00074       {
00075         typedef mln::fun::unary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G> > super;
00076 
00077         composition() {};
00078         composition(const composition_param<F, G>& p) : super(p) {};
00079 
00080         typedef composition exact_type;
00081       };
00082 
00083       template <typename F, typename G>
00084       struct composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>
00085       : mln::fun::binary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G> >
00086       {
00087         typedef mln::fun::binary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G> > super;
00088 
00089         composition() {};
00090         composition(const composition_param<F, G>& p) : super(p) {};
00091 
00092         typedef composition exact_type;
00093       };
00094 
00095       // Concrete
00096       template <typename F, typename G>
00097       struct composition<mln::Meta_Function_v2v, F, mln::Function_v2v, G>
00098       {
00099         typedef mln::fun::spe::unary< composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>, typename G::argument> exact_type;
00100       };
00101 
00102       template <typename F, typename G>
00103       struct composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>
00104       {
00105         typedef mln::fun::spe::binary< composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>,
00106                                        typename G::argument1, typename G::argument2> exact_type;
00107       };
00108 
00109       // Unary compositions implementation inherit from composition_unary_impl...
00110       template <bool has_lvalue, typename F, typename F_spe, typename G, typename G_spe>
00111       struct composition_unary_impl_helper;
00112 
00113       template <typename F, typename F_spe, typename G, typename G_spe>
00114       struct composition_unary_impl_helper<false, F, F_spe, G, G_spe>
00115       {
00116         typedef typename G_spe::argument argument;
00117         typedef typename F_spe::result   result;
00118         typedef composition_param<F, G> param;
00119 
00120         static result read(const param& p, const argument& x)
00121         {
00122           return p.f_(p.g_(x));
00123         }
00124       };
00125 
00126       template <typename F, typename F_spe, typename G, typename G_spe>
00127       struct composition_unary_impl_helper<true, F, F_spe, G, G_spe>
00128       : composition_unary_impl_helper<false, F, F_spe, G, G_spe>
00129       {
00130         typedef composition_unary_impl_helper<false, F, F_spe, G, G_spe> super;
00131         typedef typename G_spe::lvalue   lvalue;
00132 
00133         composition_unary_impl_helper() {}
00134         composition_unary_impl_helper(const typename super::param& p) : super(p) {}
00135 
00136         static void write(const typename super::param& p, lvalue l, const typename super::result& x)
00137         {
00138           typename G_spe::result r(p.g_(l));
00139 
00140           p.f_.set(r, x);
00141           p.g_.set(l, r);
00142         }
00143       };
00144 
00145       template <typename F, typename F_spe, typename G, typename G_spe>
00146       struct composition_unary_impl
00147       : composition_unary_impl_helper<mln_trait_fun_is_assignable_(G_spe)::value, F, F_spe, G, G_spe>
00148       {
00149         typedef composition_unary_impl_helper<mln_trait_fun_is_assignable_(G_spe)::value, F, F_spe, G, G_spe> super;
00150 
00151         composition_unary_impl() {}
00152         composition_unary_impl(const typename super::param& p) : super(p) {}
00153       };
00154 
00155       template <typename F, typename F_spe, typename G, typename G_spe>
00156       struct composition_binary_impl
00157       {
00158         typedef typename G_spe::argument1 argument1;
00159         typedef typename G_spe::argument2 argument2;
00160         typedef typename F_spe::result    result;
00161         typedef composition_param<F, G>   param;
00162 
00163         static result read(const param& p, const argument1& a, const argument2& b)
00164         {
00165           return p.f_(p.g_(a, b));
00166         }
00167       };
00168 
00169     } // end of namespace mln::fun::internal
00170 
00171   } // end of namespace mln::fun
00172 
00173   namespace trait
00174   {
00175 
00176     namespace next
00177     {
00178 
00179       template <typename F, typename G, typename T>
00180       struct set_precise_unary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>, T>
00181       {
00182         typedef typename G::template with<T>::ret G_fun;
00183         typedef typename F::template with<typename G_fun::result>::ret F_fun;
00184 
00185         typedef mln::fun::internal::composition_unary_impl<F, F_fun, G, G_fun> ret;
00186       };
00187 
00188       template <typename F, typename G, typename T1, typename T2>
00189       struct set_precise_binary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>, T1, T2>
00190       {
00191         typedef typename G::template with<T1, T2>::ret G_fun;
00192         typedef typename F::template with<typename G_fun::result>::ret F_fun;
00193 
00194         typedef mln::fun::internal::composition_binary_impl<F, F_fun, G, G_fun> ret;
00195       };
00196 
00197       template <typename F, typename G>
00198       struct set_precise_unary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Function_v2v, G>,
00199                                 typename G::argument>
00200       {
00201         typedef typename F::template with<typename G::result>::ret F_fun;
00202 
00203         typedef mln::fun::internal::composition_unary_impl<F, F_fun, G, G> ret;
00204       };
00205 
00206       template <typename F, typename G>
00207       struct set_precise_binary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>,
00208                                  typename G::argument1, typename G::argument2>
00209       {
00210         typedef typename F::template with<typename G::result>::ret F_fun;
00211 
00212         typedef mln::fun::internal::composition_binary_impl<F, F_fun, G, G> ret;
00213       };
00214 
00215     }  // end of namespace mln::trait::next
00216 
00217   }  // end of namespace mln::trait
00218 
00219 } // end of namespace mln
00220 
00221 #endif // ! MLN_FUN_COMPOSITION_HH

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