Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
composition.hh
1 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_FUN_COMPOSITION_HH
27 # define MLN_FUN_COMPOSITION_HH
28 
29 # include <mln/fun/unary.hh>
30 # include <mln/fun/binary.hh>
31 # include <mln/fun/param.hh>
32 
33 namespace mln
34 {
35  // Composition
36  namespace fun
37  {
38 
39  namespace internal
40  {
41 
42  // Compositions may take this has initialization parameter
43  template <typename F, typename G>
44  struct composition_param
45  {
46  composition_param(const F& f, const G& g) : f_(f), g_(g) {}
47  composition_param() {}
48 
49  F f_;
50  G g_;
51  };
52 
53  // Composition types...
54  template <template <class> class CatF, typename F,
55  template <class> class CatG, typename G>
56  struct composition;
57 
58  } // end of namespace mln::fun::internal
59 
60  template <template <class> class CatF, typename F,
61  template <class> class CatG, typename G>
62  struct parameter< internal::composition<CatF, F, CatG, G> >
63  {
64  typedef internal::composition_param<F, G> param;
65  };
66 
67  namespace internal
68  {
69 
70  // Meta
71  template <typename F, typename G>
72  struct composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>
73  : mln::fun::unary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G> >
74  {
75  typedef mln::fun::unary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G> > super;
76 
77  composition() {};
78  composition(const composition_param<F, G>& p) : super(p) {};
79 
80  typedef composition exact_type;
81  };
82 
83  template <typename F, typename G>
84  struct composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>
85  : mln::fun::binary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G> >
86  {
87  typedef mln::fun::binary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G> > super;
88 
89  composition() {};
90  composition(const composition_param<F, G>& p) : super(p) {};
91 
92  typedef composition exact_type;
93  };
94 
95  // Concrete
96  template <typename F, typename G>
97  struct composition<mln::Meta_Function_v2v, F, mln::Function_v2v, G>
98  {
99  typedef mln::fun::spe::unary< composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>, typename G::argument> exact_type;
100  };
101 
102  template <typename F, typename G>
103  struct composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>
104  {
105  typedef mln::fun::spe::binary< composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>,
106  typename G::argument1, typename G::argument2> exact_type;
107  };
108 
109  // Unary compositions implementation inherit from composition_unary_impl...
110  template <bool has_lvalue, typename F, typename F_spe, typename G, typename G_spe>
111  struct composition_unary_impl_helper;
112 
113  template <typename F, typename F_spe, typename G, typename G_spe>
114  struct composition_unary_impl_helper<false, F, F_spe, G, G_spe>
115  {
116  typedef typename G_spe::argument argument;
117  typedef typename F_spe::result result;
118  typedef composition_param<F, G> param;
119 
120  static result read(const param& p, const argument& x)
121  {
122  return p.f_(p.g_(x));
123  }
124  };
125 
126  template <typename F, typename F_spe, typename G, typename G_spe>
127  struct composition_unary_impl_helper<true, F, F_spe, G, G_spe>
128  : composition_unary_impl_helper<false, F, F_spe, G, G_spe>
129  {
130  typedef composition_unary_impl_helper<false, F, F_spe, G, G_spe> super;
131  typedef typename G_spe::lvalue lvalue;
132 
133  composition_unary_impl_helper() {}
134  composition_unary_impl_helper(const typename super::param& p) : super(p) {}
135 
136  static void write(const typename super::param& p, lvalue l, const typename super::result& x)
137  {
138  typename G_spe::result r(p.g_(l));
139 
140  p.f_.set(r, x);
141  p.g_.set(l, r);
142  }
143  };
144 
145  template <typename F, typename F_spe, typename G, typename G_spe>
146  struct composition_unary_impl
147  : composition_unary_impl_helper<mln_trait_fun_is_assignable_(G_spe)::value, F, F_spe, G, G_spe>
148  {
149  typedef composition_unary_impl_helper<mln_trait_fun_is_assignable_(G_spe)::value, F, F_spe, G, G_spe> super;
150 
151  composition_unary_impl() {}
152  composition_unary_impl(const typename super::param& p) : super(p) {}
153  };
154 
155  template <typename F, typename F_spe, typename G, typename G_spe>
156  struct composition_binary_impl
157  {
158  typedef typename G_spe::argument1 argument1;
159  typedef typename G_spe::argument2 argument2;
160  typedef typename F_spe::result result;
161  typedef composition_param<F, G> param;
162 
163  static result read(const param& p, const argument1& a, const argument2& b)
164  {
165  return p.f_(p.g_(a, b));
166  }
167  };
168 
169  } // end of namespace mln::fun::internal
170 
171  } // end of namespace mln::fun
172 
173  namespace trait
174  {
175 
176  namespace next
177  {
178 
179  template <typename F, typename G, typename T>
180  struct set_precise_unary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>, T>
181  {
182  typedef typename G::template with<T>::ret G_fun;
183  typedef typename F::template with<typename G_fun::result>::ret F_fun;
184 
185  typedef mln::fun::internal::composition_unary_impl<F, F_fun, G, G_fun> ret;
186  };
187 
188  template <typename F, typename G, typename T1, typename T2>
189  struct set_precise_binary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>, T1, T2>
190  {
191  typedef typename G::template with<T1, T2>::ret G_fun;
192  typedef typename F::template with<typename G_fun::result>::ret F_fun;
193 
194  typedef mln::fun::internal::composition_binary_impl<F, F_fun, G, G_fun> ret;
195  };
196 
197  template <typename F, typename G>
198  struct set_precise_unary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Function_v2v, G>,
199  typename G::argument>
200  {
201  typedef typename F::template with<typename G::result>::ret F_fun;
202 
203  typedef mln::fun::internal::composition_unary_impl<F, F_fun, G, G> ret;
204  };
205 
206  template <typename F, typename G>
207  struct set_precise_binary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>,
208  typename G::argument1, typename G::argument2>
209  {
210  typedef typename F::template with<typename G::result>::ret F_fun;
211 
212  typedef mln::fun::internal::composition_binary_impl<F, F_fun, G, G> ret;
213  };
214 
215  } // end of namespace mln::trait::next
216 
217  } // end of namespace mln::trait
218 
219 } // end of namespace mln
220 
221 #endif // ! MLN_FUN_COMPOSITION_HH