https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Solve infinite recursive calls in linear::impl::convolve_.
* mln/linear/convolve.hh
(convolve_(any, const I&, const Weighted_Window<W>&, any, O&)):
Move the body of this function...
(convolve_(const I&, const Weighted_Window<W>&, O&)):
...here (new function).
Use it to factor...
(convolve_(Speed_I, const I&, const Weighted_Window<W>&, Speed_O, O&))
(convolve_(any, const I&, const Weighted_Window<W>&, any, O&)):
...the implementations of these functions.
convolve.hh | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 61 insertions(+), 1 deletion(-)
Index: mln/linear/convolve.hh
--- mln/linear/convolve.hh (revision 1647)
+++ mln/linear/convolve.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -65,6 +65,54 @@
namespace impl
{
+ /* FIXME: We must clean up the interface of
+ mln::linear::impl::convolve_:
+
+ - either allow certain patterns of speed traits (e.g.,
+ any/any, fastest/fastest, fastest/any, etc.). In this
+ case, the generic version should abort at compile time;
+
+ - or accept all combinations (which is the current case), and
+ default to the slowest one (presumably any/any).
+ */
+
+ // Fwd decl.
+ template <typename I, typename W, typename O>
+ inline
+ void convolve_(const I& input,
+ const Weighted_Window<W>& w_win_,
+ O& output);
+
+ /// Default version, delegating to the generic version.
+ template <typename Speed_I, typename I, typename W,
+ typename Speed_O, typename O>
+ inline
+ void convolve_(Speed_I, const I& input,
+ const Weighted_Window<W>& w_win_,
+ Speed_O, O& output)
+ {
+ /* Don't delegate using such a call:
+
+ \code
+ impl::convolve_(trait::image::speed::any(), input,
+ w_win_,
+ trait::image::speed::any(), output);
+ \endcode
+
+ since it would end up with infinite recursion. The reason
+ is that the compiler would select this function (in which
+ you read this very comment), instead of the next one (with
+ input and output speed traits set to `any'), to resolve the
+ call. This is because C++ overloading rules favor the
+ generic function over the more specialized one. And we
+ cannot use explicit partial specialization, since it just
+ doesn't exist for functions.
+
+ Hence the chosen solution: create and call another
+ overloading for mln::linear::impl::convolve_, with no
+ unnatural selection behavior. */
+ impl::convolve_(input, w_win_, output);
+ }
template <typename I, typename W, typename O>
inline
@@ -72,6 +120,18 @@
const Weighted_Window<W>& w_win_,
trait::image::speed::any, O& output)
{
+ // Delegate the call to the generic version.
+ impl::convolve_(input, w_win_, output);
+ }
+
+ /// A factored implementation of the most generic version of
+ /// mln::linear::impl::convolve_.
+ template <typename I, typename W, typename O>
+ inline
+ void convolve_(const I& input,
+ const Weighted_Window<W>& w_win_,
+ O& output)
+ {
const W& w_win = exact(w_win_);
mln_piter(I) p(input.domain());