Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
take_n_times.hh
1 // Copyright (C) 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_ACCU_IMAGE_TAKE_N_TIMES_HH
27 # define MLN_ACCU_IMAGE_TAKE_N_TIMES_HH
28 
35 
36 # include <mln/core/concept/accumulator.hh>
37 # include <mln/core/concept/image.hh>
38 # include <mln/border/resize_equal.hh>
39 
40 
41 namespace mln
42 {
43 
44  namespace accu
45  {
46 
47  namespace image
48  {
49 
50  template <typename I, typename J>
51  void
52  take_n_times(Image<I>& input, const Image<J>& n_times, const mln_deduce(I, value, argument)& arg);
53 
54  template <typename I, typename J, typename K>
55  void
56  take_n_times(Image<I>& input, const Image<J>& n_times, const Image<K>& arg);
57 
58 
59 
60 # ifndef MLN_INCLUDE_ONLY
61 
62 
63  // Tests.
64 
65  namespace internal
66  {
67 
68  template <typename I, typename J>
69  inline
70  void
71  take_n_times_tests(Image<I>& input_, const Image<J>& n_times_)
72  {
73  I& input = exact(input_);
74  const J& n_times = exact(n_times_);
75 
76  mln_precondition(input.is_valid());
77  mln_precondition(n_times.is_valid());
78 
79  mln_precondition(n_times.domain() <= input.domain());
80 
81  (void) input;
82  (void) n_times;
83  }
84 
85  template <typename I, typename J, typename K>
86  inline
87  void
88  take_n_times_tests(Image<I>& input_, const Image<J>& n_times_, const Image<K>& arg_)
89  {
90  I& input = exact(input_);
91  const J& n_times = exact(n_times_);
92  const K& arg = exact(arg_);
93 
94  mln_precondition(input.is_valid());
95  mln_precondition(n_times.is_valid());
96  mln_precondition(arg.is_valid());
97 
98  mln_precondition(arg.domain() <= input.domain());
99  mln_precondition(arg.domain() <= n_times.domain());
100 
101  (void) input;
102  (void) n_times;
103  (void) arg;
104  }
105 
106  } // end of namespace mln::accu::image::internal
107 
108 
109  // Implementations.
110 
111  namespace impl
112  {
113 
114  // Generic versions.
115 
116  namespace generic
117  {
118 
119  template <typename I, typename J, typename K>
120  inline
121  void
122  take_n_times(Image<I>& input_, const Image<J>& n_times_, const Image<K>& arg_)
123  {
124  trace::entering("accu::impl::image::generic::take_n_times");
125 
126  mlc_is_a(mln_value(I), Accumulator)::check();
127  mlc_converts_to(mln_value(J), unsigned)::check();
128  mlc_converts_to(mln_value(K), mln_deduce(I, value, argument))::check();
129 
130  I& input = exact(input_);
131  const J& n_times = exact(n_times_);
132  const K& arg = exact(arg_);
133 
134  internal::take_n_times_tests(input, n_times, arg);
135 
136  mln_piter(J) p(arg.domain());
137  for_all(p)
138  input(p).take_n_times(n_times(p), arg(p));
139 
140  trace::exiting("accu::impl::image::generic::take_n_times");
141  }
142 
143  template <typename I, typename J>
144  inline
145  void
146  take_n_times(Image<I>& input_, const Image<J>& n_times_, const mln_deduce(I, value, argument)& arg)
147  {
148  trace::entering("accu::impl::image::generic::take_n_times");
149 
150  mlc_is_a(mln_value(I), Accumulator)::check();
151  mlc_converts_to(mln_value(J), unsigned)::check();
152 
153  I& input = exact(input_);
154  const J& n_times = exact(n_times_);
155 
156  internal::take_n_times_tests(input, n_times);
157 
158  mln_piter(J) p(n_times.domain());
159  for_all(p)
160  input(p).take_n_times(n_times(p), arg);
161 
162  trace::exiting("accu::impl::image::generic::take_n_times");
163  }
164 
165  } // end of namespace mln::accu::image::impl::generic
166 
167 
168  // Fastest versions.
169 
170  template <typename I, typename J>
171  inline
172  void
173  take_n_times_fastest(Image<I>& input_, const Image<J>& n_times_, const mln_deduce(I, value, argument)& arg)
174  {
175  trace::entering("accu::impl::image::take_n_times_fastest");
176 
177  mlc_is_a(mln_value(I), Accumulator)::check();
178  mlc_converts_to(mln_value(J), unsigned)::check();
179 
180  I& input = exact(input_);
181  const J& n_times = exact(n_times_);
182 
183  internal::take_n_times_tests(input, n_times);
184  // Extra (stronger) test:
185  mln_precondition(n_times.domain() == input.domain());
186 
187  border::resize_equal(input, n_times);
188 
189  mln_pixter(I) p_in(input);
190  mln_pixter(const J) p_ntm(n_times);
191  for_all_2(p_in, p_ntm)
192  p_in.val().take_n_times( p_ntm.val(), arg );
193 
194  trace::exiting("accu::impl::image::take_n_times_fastest");
195  }
196 
197  template <typename I, typename J, typename K>
198  inline
199  void
200  take_n_times_fastest(Image<I>& input_, const Image<J>& n_times_, const Image<K>& arg_)
201  {
202  trace::entering("accu::impl::image::take_n_times_fastest");
203 
204  mlc_is_a(mln_value(I), Accumulator)::check();
205  mlc_converts_to(mln_value(J), unsigned)::check();
206  mlc_converts_to(mln_value(K), mln_deduce(I, value, argument))::check();
207 
208  I& input = exact(input_);
209  const J& n_times = exact(n_times_);
210  const K& arg = exact(arg_);
211 
212  internal::take_n_times_tests(input, n_times, arg);
213 
214  // Extra (stronger) tests.
215  mln_precondition(arg.domain() == input.domain());
216  mln_precondition(arg.domain() == n_times.domain());
217 
218  border::resize(n_times, input.border());
219  border::resize(arg, input.border());
220 
221  mln_pixter(I) p_in(input);
222  mln_pixter(const J) p_ntm(n_times);
223  mln_pixter(const K) p_arg(arg);
224  for_all_3(p_in, p_ntm, p_arg)
225  p_in.val().take_n_times( p_ntm.val(), p_arg.val() );
226 
227  trace::exiting("accu::impl::image::take_n_times_fastest");
228  }
229 
230  } // end of namespace mln::accu::image::impl
231 
232 
233 
234  // Dispatch.
235 
236  namespace internal
237  {
238 
239  // 'arg' as value.
240 
241  template <typename I, typename J>
242  inline
243  void
244  take_n_times_dispatch(trait::image::speed::any,
245  trait::image::speed::any,
246  Image<I>& input, const Image<J>& n_times, const mln_deduce(I, value, argument)& arg)
247  {
248  impl::generic::take_n_times(input, n_times, arg);
249  }
250 
251  template <typename I, typename J>
252  inline
253  void
254  take_n_times_dispatch(trait::image::speed::fastest,
255  trait::image::speed::fastest,
256  Image<I>& input, const Image<J>& n_times, const mln_deduce(I, value, argument)& arg)
257  {
258  if (exact(n_times).domain() == exact(input).domain())
259  impl::take_n_times_fastest(input, n_times, arg);
260  else
261  impl::generic::take_n_times(input, n_times, arg);
262  }
263 
264  template <typename I, typename J>
265  inline
266  void
267  take_n_times_dispatch(Image<I>& input, const Image<J>& n_times, const mln_deduce(I, value, argument)& arg)
268  {
269  take_n_times_dispatch(mln_trait_image_speed(I)(),
270  mln_trait_image_speed(J)(),
271  input, n_times, arg);
272  }
273 
274  // Triplet of images.
275 
276  template <typename I, typename J, typename K>
277  inline
278  void
279  take_n_times_dispatch(trait::image::speed::any,
280  trait::image::speed::any,
281  trait::image::speed::any,
282  Image<I>& input, const Image<J>& n_times, const Image<K>& arg)
283  {
284  impl::generic::take_n_times(input, n_times, arg);
285  }
286 
287  template <typename I, typename J, typename K>
288  inline
289  void
290  take_n_times_dispatch(trait::image::speed::fastest,
291  trait::image::speed::fastest,
292  trait::image::speed::fastest,
293  Image<I>& input, const Image<J>& n_times, const Image<K>& arg)
294  {
295  if (exact(n_times).domain() == exact(input).domain() &&
296  exact(arg) .domain() == exact(input).domain())
297  impl::take_n_times_fastest(input, n_times, arg);
298  else
299  impl::generic::take_n_times(input, n_times, arg);
300  }
301 
302  template <typename I, typename J, typename K>
303  inline
304  void
305  take_n_times_dispatch(Image<I>& input, const Image<J>& n_times, const Image<K>& arg)
306  {
307  take_n_times_dispatch(mln_trait_image_speed(I)(),
308  mln_trait_image_speed(J)(),
309  mln_trait_image_speed(K)(),
310  input, n_times, arg);
311  }
312 
313  } // end of namespace mln::accu::image::internal
314 
315 
316  // Facades.
317 
318  template <typename I, typename J>
319  void
320  take_n_times(Image<I>& input, const Image<J>& n_times, const mln_deduce(I, value, argument)& arg)
321  {
322  trace::entering("accu::image::take_n_times");
323 
324  mlc_is_a(mln_value(I), Accumulator)::check();
325  mlc_converts_to(mln_value(J), unsigned)::check();
326 
327  internal::take_n_times_tests(input, n_times);
328  internal::take_n_times_dispatch(input, n_times, arg);
329 
330  trace::exiting("accu::image::take_n_times");
331  }
332 
333  template <typename I, typename J, typename K>
334  inline
335  void
336  take_n_times(Image<I>& input, const Image<J>& n_times, const Image<K>& arg)
337  {
338  trace::entering("accu::image::take_n_times");
339 
340  mlc_is_a(mln_value(I), Accumulator)::check();
341  mlc_converts_to(mln_value(J), unsigned)::check();
342  mlc_converts_to(mln_value(K), mln_deduce(I, value, argument))::check();
343 
344  internal::take_n_times_tests(input, n_times, arg);
345  internal::take_n_times_dispatch(input, n_times, arg);
346 
347  trace::exiting("accu::image::take_n_times");
348  }
349 
350 # endif // ! MLN_INCLUDE_ONLY
351 
352  } // end of namespace mln::accu::image
353 
354  } // end of namespace mln::accu
355 
356 } // end of namespace mln
357 
358 
359 #endif // ! MLN_ACCU_IMAGE_TAKE_N_TIMES_HH