* mln/transform/fft.hh
(mln::transform::fft<T, internal::fft_real>::fft):
Properly initialize the plan of the inverse transform using
fftw_plan_dft_c2r_2d.
(mln::transform::fft<T, internal::fft_real>::transform_inv):
Use the entire complex values (not just their real parts) to
compute the inverse transform.
(mln::transform::class fft<T, internal::fft_cplx>::fft):
Call the proper function (fftw_plan_dft_2d) to create the plan of
the inverse transform.
Switch the input and the output so that the inverse transform uses
the right images.
---
milena/ChangeLog | 17 +++++++++++++++++
milena/mln/transform/fft.hh | 15 ++++++++-------
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 86a6f5e..9f4e622 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,20 @@
+2012-10-09 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Fix the Fast Fourier Transform.
+
+ * mln/transform/fft.hh
+ (mln::transform::fft<T, internal::fft_real>::fft):
+ Properly initialize the plan of the inverse transform using
+ fftw_plan_dft_c2r_2d.
+ (mln::transform::fft<T, internal::fft_real>::transform_inv):
+ Use the entire complex values (not just their real parts) to
+ compute the inverse transform.
+ (mln::transform::class fft<T, internal::fft_cplx>::fft):
+ Call the proper function (fftw_plan_dft_2d) to create the plan of
+ the inverse transform.
+ Switch the input and the output so that the inverse transform uses
+ the right images.
+
2012-10-09 Alexandre Abraham <abraham(a)lrde.epita.fr>
Import the FFTW-based Fast Fourier Transform.
diff --git a/milena/mln/transform/fft.hh b/milena/mln/transform/fft.hh
index 0dafa7b..cf0f1bb 100644
--- a/milena/mln/transform/fft.hh
+++ b/milena/mln/transform/fft.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009, 2012 EPITA Research and Development
+// Laboratory
//
// This file is part of the Milena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -418,8 +419,8 @@ namespace mln {
this->p = fftw_plan_dft_r2c_2d (original_im.nrows(), original_im.ncols(),
this->in, reinterpret_cast<fftw_complex*>(this->out), FFTW_ESTIMATE);
- this->p_inv = fftw_plan_dft_r2c_2d (original_im.nrows(), original_im.ncols(),
- this->in, reinterpret_cast<fftw_complex*>(this->out), FFTW_ESTIMATE);
+ this->p_inv = fftw_plan_dft_c2r_2d (original_im.nrows(), original_im.ncols(),
+ reinterpret_cast<fftw_complex*>(this->out), this->in, FFTW_ESTIMATE);
this->trans_im = image2d< std::complex<T> >(original_im.domain());
}
@@ -460,7 +461,7 @@ namespace mln {
for (unsigned row = 0; row < this->trans_im.nrows(); ++row)
for (unsigned col = 0; col <= this->trans_im.ncols() / 2; ++col)
this->out[row * (this->trans_im.ncols() / 2 + 1) + col] =
- opt::at(this->trans_im, row, col).real();
+ opt::at(this->trans_im, row, col);
fftw_execute(this->p_inv);
@@ -620,9 +621,9 @@ namespace mln {
this->p = fftw_plan_dft_2d(original_im.nrows(), original_im.ncols(),
this->in, this->out,
FFTW_FORWARD, FFTW_ESTIMATE);
- this->p_inv = fftw2d_plan_dft_2d(original_im.nrows(), original_im.ncols(),
- this->in, this->out,
- FFTW_BACKWARD, FFTW_ESTIMATE);
+ this->p_inv = fftw_plan_dft_2d(original_im.nrows(), original_im.ncols(),
+ this->out, this->in,
+ FFTW_BACKWARD, FFTW_ESTIMATE);
this->trans_im = image2d< std::complex<T> >(original_im.domain());
}
--
1.7.2.5
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch proxy-overload-problem-g++-4.7 has been created
at dff1809d32eef8a6e492992efd74736707855932 (commit)
- Log -----------------------------------------------------------------
dff1809 Highlight an overload resolution problem in proxies with g++-4.7.
-----------------------------------------------------------------------
hooks/post-receive
--
Olena, a generic and efficient image processing platform
* mln/core/image/vmorph/thru_image.hh,
* mln/fun/component/blue.hh,
* mln/fun/component/green.hh,
* mln/fun/component/red.hh,
* mln/fun/component/rgb.hh,
* mln/fun/param.hh,
* mln/fun/spe/unary.hh,
* mln/fun/unary.hh,
* mln/trait/functions.hh,
* mln/trait/next/solve.hh,
* mln/trait/next/solve_binary.hh,
* mln/trait/next/solve_proxy.hh,
* mln/trait/next/solve_unary.hh:
New.
* headers.mk,
* tests/unit_test/unit-tests.mk:
Regen.
---
milena/ChangeLog | 22 ++
milena/headers.mk | 13 +
milena/mln/core/image/vmorph/thru_image.hh | 319 ++++++++++++++++++++++++++
milena/mln/fun/component/blue.hh | 81 +++++++
milena/mln/fun/component/green.hh | 81 +++++++
milena/mln/fun/component/red.hh | 81 +++++++
milena/mln/fun/component/rgb.hh | 37 +++
milena/mln/fun/param.hh | 86 +++++++
milena/mln/fun/spe/unary.hh | 334 ++++++++++++++++++++++++++++
milena/mln/fun/unary.hh | 175 +++++++++++++++
milena/mln/trait/functions.hh | 251 +++++++++++++++++++++
milena/mln/trait/next/solve.hh | 146 ++++++++++++
milena/mln/trait/next/solve_binary.hh | 300 +++++++++++++++++++++++++
milena/mln/trait/next/solve_proxy.hh | 98 ++++++++
milena/mln/trait/next/solve_unary.hh | 170 ++++++++++++++
milena/tests/unit_test/unit-tests.mk | 26 +++
16 files changed, 2220 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/core/image/vmorph/thru_image.hh
create mode 100644 milena/mln/fun/component/blue.hh
create mode 100644 milena/mln/fun/component/green.hh
create mode 100644 milena/mln/fun/component/red.hh
create mode 100644 milena/mln/fun/component/rgb.hh
create mode 100644 milena/mln/fun/param.hh
create mode 100644 milena/mln/fun/spe/unary.hh
create mode 100644 milena/mln/fun/unary.hh
create mode 100644 milena/mln/trait/functions.hh
create mode 100644 milena/mln/trait/next/solve.hh
create mode 100644 milena/mln/trait/next/solve_binary.hh
create mode 100644 milena/mln/trait/next/solve_proxy.hh
create mode 100644 milena/mln/trait/next/solve_unary.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 894d261..6ce0fe2 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,25 @@
+2012-10-08 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Revive headers required by the RGB component functors.
+
+ * mln/core/image/vmorph/thru_image.hh,
+ * mln/fun/component/blue.hh,
+ * mln/fun/component/green.hh,
+ * mln/fun/component/red.hh,
+ * mln/fun/component/rgb.hh,
+ * mln/fun/param.hh,
+ * mln/fun/spe/unary.hh,
+ * mln/fun/unary.hh,
+ * mln/trait/functions.hh,
+ * mln/trait/next/solve.hh,
+ * mln/trait/next/solve_binary.hh,
+ * mln/trait/next/solve_proxy.hh,
+ * mln/trait/next/solve_unary.hh:
+ New.
+ * headers.mk,
+ * tests/unit_test/unit-tests.mk:
+ Regen.
+
2012-10-05 Roland Levillain <roland(a)lrde.epita.fr>
Provide typedefs mln::value::int_s24 and mln::value::int_u24.
diff --git a/milena/headers.mk b/milena/headers.mk
index 20f2f35..dbd26e9 100644
--- a/milena/headers.mk
+++ b/milena/headers.mk
@@ -313,6 +313,7 @@ mln/core/image/vertex_image.hh \
mln/core/image/vmorph/all.hh \
mln/core/image/vmorph/cast_image.hh \
mln/core/image/vmorph/fun_image.hh \
+mln/core/image/vmorph/thru_image.hh \
mln/core/image/vmorph/violent_cast_image.hh \
mln/core/internal/box_impl.hh \
mln/core/internal/check/image_all.hh \
@@ -507,6 +508,10 @@ mln/extension/fill.hh \
mln/fun/all.hh \
mln/fun/c.hh \
mln/fun/cast.hh \
+mln/fun/component/blue.hh \
+mln/fun/component/green.hh \
+mln/fun/component/red.hh \
+mln/fun/component/rgb.hh \
mln/fun/essential.hh \
mln/fun/i2v/all.hh \
mln/fun/i2v/all_to.hh \
@@ -537,8 +542,11 @@ mln/fun/p2v/elifs.hh \
mln/fun/p2v/essential.hh \
mln/fun/p2v/iota.hh \
mln/fun/p2v/ternary.hh \
+mln/fun/param.hh \
+mln/fun/spe/unary.hh \
mln/fun/stat/all.hh \
mln/fun/stat/mahalanobis.hh \
+mln/fun/unary.hh \
mln/fun/v2b/all.hh \
mln/fun/v2b/essential.hh \
mln/fun/v2b/lnot.hh \
@@ -1063,11 +1071,16 @@ mln/trait/ch_function_value.hh \
mln/trait/ch_value.hh \
mln/trait/concrete.hh \
mln/trait/essential.hh \
+mln/trait/functions.hh \
mln/trait/image/print.hh \
mln/trait/image/props.hh \
mln/trait/image_from_grid.hh \
mln/trait/images.hh \
mln/trait/neighborhood.hh \
+mln/trait/next/solve.hh \
+mln/trait/next/solve_binary.hh \
+mln/trait/next/solve_proxy.hh \
+mln/trait/next/solve_unary.hh \
mln/trait/op/all.hh \
mln/trait/op/and.hh \
mln/trait/op/decl.hh \
diff --git a/milena/mln/core/image/vmorph/thru_image.hh b/milena/mln/core/image/vmorph/thru_image.hh
new file mode 100644
index 0000000..e829b27
--- /dev/null
+++ b/milena/mln/core/image/vmorph/thru_image.hh
@@ -0,0 +1,319 @@
+// Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development
+// Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_CORE_IMAGE_VMORPH_THRU_IMAGE_HH
+# define MLN_CORE_IMAGE_VMORPH_THRU_IMAGE_HH
+
+/// \file
+///
+/// \brief Definition of a morpher that morph image values through a function.
+///
+/// \todo Debug constness of thru_image
+
+# include <mln/core/internal/image_value_morpher.hh>
+# include <mln/core/concept/meta_function.hh>
+# include <mln/metal/bexpr.hh>
+# include <mln/trait/functions.hh>
+
+
+namespace mln
+{
+
+ // Forward declaration.
+ template <typename I, typename F> class thru_image;
+
+ namespace internal
+ {
+ template <typename I, typename F> class thru_image_write;
+ template <typename I, typename F> class thru_image_read;
+
+ /// Find correct implementation
+ template <typename I, typename F>
+ struct thru_find_impl
+ {
+ typedef thru_image_write<I, F> write;
+ typedef thru_image_read<I, F> read;
+ typedef mlc_if(mlc_and(mln_trait_fun_is_assignable(F),
+ mlc_and(mlc_not(mlc_is_const(I)),
+ mlc_equal(mln_trait_image_pw_io(I),
+ trait::image::pw_io::read_write))),
+ write, read) ret;
+ };
+
+ /// Data structure for \c mln::thru_image<I>.
+ template <typename I, typename F>
+ struct data< thru_image<I, F> >
+ {
+ data(I& ima, const F& f);
+
+ I ima_;
+ F f_;
+ };
+
+ } // end of namespace mln::internal
+
+
+ namespace trait
+ {
+
+ template <typename I, typename F>
+ struct image_< thru_image<I, F> > : image_< typename mln::internal::thru_find_impl<I, F>::ret > // Same as I except...
+ {
+ // ...these changes.
+ typedef trait::image::category::value_morpher category;
+ typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
+ typedef trait::image::value_access::computed value_access;
+ };
+
+ template <typename I, typename F>
+ struct image_< mln::internal::thru_image_write<I, F> > : image_< I > // Same as I except...
+ {
+ typedef trait::image::vw_io::read_write vw_io;
+ };
+
+ template <typename I, typename F>
+ struct image_< mln::internal::thru_image_read<I, F> > : image_< I > // Same as I except...
+ {
+ typedef trait::image::vw_io::read vw_io;
+ };
+
+ } // end of namespace mln::trait
+
+
+
+ // FIXME: Doc!
+
+ namespace internal
+ {
+
+ template <typename I, typename F>
+ class thru_image_read : public internal::image_value_morpher< I, typename F::result, thru_image<I,F> >
+ {
+ public:
+
+ /// Skeleton.
+ typedef thru_image<tag::image_<I>, F> skeleton;
+
+ /// Point_Site associated type.
+ typedef mln_psite(I) psite;
+
+ /// Value associated type.
+ typedef mln_result(F) value;
+
+ /// Return type of read-only access.
+ typedef value rvalue;
+ typedef value lvalue; // Workaround for write operator()
+
+ rvalue operator()(const mln_psite(I)& p) const;
+ rvalue operator()(const mln_psite(I)& p);
+
+ };
+
+ // Inheritance from read ?!
+ template <typename I, typename F>
+ class thru_image_write : public thru_image_read<I,F>
+ {
+ public:
+
+ /// Type returned by the read-write pixel value operator.
+// typedef typename F::template lresult<typename F::argument>::ret lvalue;
+ typedef typename F::lresult lvalue;
+
+ using thru_image_read<I,F>::operator();
+ lvalue operator()(const mln_psite(I)& p);
+
+ };
+ }
+
+ /// Morph image values through a function.
+ ///
+ /// \ingroup modimagevaluemorpher
+ //
+ template <typename I, typename F>
+ class thru_image : public internal::thru_find_impl<I, F>::ret
+ {
+ public:
+
+ thru_image();
+ thru_image(I& ima);
+ thru_image(I& ima, const F& f);
+
+ void init_(I& ima, const F& f);
+
+ /// Const promotion via conversion.
+ operator thru_image<const I, F>() const;
+ };
+
+ template <typename I, typename F>
+ thru_image<I, F> thru(const mln::Function<F>& f,
+ Image<I>& ima);
+
+ template <typename I, typename F>
+ const thru_image<const I, F> thru(const mln::Function<F>& f,
+ const Image<I>& ima);
+
+ template <typename I, typename M>
+ thru_image<I, mln_fun_with(M, mln_value(I))>
+ thru(const mln::Meta_Function<M>& f, Image<I>& ima);
+
+ template <typename I, typename M>
+ const thru_image<const I, mln_fun_with(M, mln_value(I))>
+ thru(const mln::Meta_Function<M>& f, const Image<I>& ima);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // internal::data< thru_image<I,S> >
+
+ namespace internal
+ {
+
+ template <typename I, typename F>
+ inline
+ data< thru_image<I, F> >::data(I& ima, const F& f)
+ : ima_(ima),
+ f_(f)
+ {
+ }
+
+ } // end of namespace mln::internal
+
+ // thru_image<I>
+
+ template <typename I, typename F>
+ inline
+ thru_image<I, F>::thru_image()
+ {
+ }
+
+ template <typename I, typename F>
+ inline
+ thru_image<I, F>::thru_image(I& ima, const F& f)
+ {
+ mln_precondition(ima.is_valid());
+ init_(ima, f);
+ }
+
+ template <typename I, typename F>
+ inline
+ thru_image<I, F>::thru_image(I& ima)
+ {
+ mln_precondition(ima.is_valid());
+ init_(ima, F());
+ }
+
+ template <typename I, typename F>
+ inline
+ void
+ thru_image<I, F>::init_(I& ima, const F& f)
+ {
+ mln_precondition(! this->is_valid());
+ mln_precondition(ima.is_valid());
+ this->data_ = new internal::data< thru_image<I, F> >(ima, f);
+ }
+
+ template <typename I, typename F>
+ inline
+ thru_image<I, F>::operator thru_image<const I, F>() const
+ {
+ thru_image<const I, F> tmp(this->data_->ima_, this->data_->f_);
+ return tmp;
+ }
+
+ namespace internal
+ {
+
+ template <typename I, typename F>
+ inline
+ typename thru_image_read<I, F>::rvalue
+ thru_image_read<I, F>::operator()(const mln_psite(I)& p) const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->f_(this->data_->ima_(p));
+ }
+
+ template <typename I, typename F>
+ inline
+ typename thru_image_read<I, F>::rvalue
+ thru_image_read<I, F>::operator()(const mln_psite(I)& p)
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->f_(this->data_->ima_(p));
+ }
+
+ template <typename I, typename F>
+ inline
+ typename thru_image_write<I, F>::lvalue
+ thru_image_write<I, F>::operator()(const mln_psite(I)& p)
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->f_(this->data_->ima_(p));
+ }
+
+ }
+
+ // thru
+ template <typename I, typename F>
+ thru_image<I, F> thru(const mln::Function<F>& f,
+ Image<I>& ima)
+ {
+ thru_image<I, F> tmp(exact(ima), exact(f));
+ return tmp;
+ }
+
+ template <typename I, typename F>
+ thru_image<const I, F> thru(const mln::Function<F>& f,
+ const Image<I>& ima)
+ {
+ thru_image<const I, F> tmp(exact(ima), exact(f));
+ return tmp;
+ }
+
+ template <typename I, typename M>
+ thru_image<I, mln_fun_with(M, mln_value(I))>
+ thru(const mln::Meta_Function<M>& f, Image<I>& ima)
+ {
+ typedef mln_fun_with(M, mln_value(I)) F;
+ thru_image<I, F> tmp(exact(ima), F(exact(f).state()));
+
+ return tmp;
+ }
+
+ template <typename I, typename M>
+ thru_image<const I, mln_fun_with(M, mln_value(I))>
+ thru(const mln::Meta_Function<M>& f, const Image<I>& ima)
+ {
+ typedef mln_fun_with(M, mln_value(I)) F;
+ thru_image<const I, F> tmp(exact(ima), F(exact(f).state()));
+
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_IMAGE_VMORPH_THRU_IMAGE_HH
diff --git a/milena/mln/fun/component/blue.hh b/milena/mln/fun/component/blue.hh
new file mode 100644
index 0000000..3796be1
--- /dev/null
+++ b/milena/mln/fun/component/blue.hh
@@ -0,0 +1,81 @@
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_COMPONENT_BLUE_HH
+# define MLN_FUN_COMPONENT_BLUE_HH
+
+/// \file
+///
+/// Meta function to retrieve/modify the blue component.
+
+# include <mln/fun/unary.hh>
+# include <mln/value/rgb.hh>
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ struct blue : unary<blue> {};
+
+ } // end of namespace mln::fun
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ template <unsigned n>
+ struct set_precise_unary_<mln::fun::blue, mln::value::rgb<n> >
+ {
+ typedef set_precise_unary_ ret;
+ typedef mln::value::rgb<n> argument;
+ typedef typename argument::blue_t result;
+ typedef argument& lvalue;
+
+ static result read(const argument& x)
+ {
+ return x.blue();
+ }
+
+ static void write(lvalue l, const result& r)
+ {
+ l.blue() = r;
+ }
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_COMPONENT_BLUE_HH
diff --git a/milena/mln/fun/component/green.hh b/milena/mln/fun/component/green.hh
new file mode 100644
index 0000000..63c5f9e
--- /dev/null
+++ b/milena/mln/fun/component/green.hh
@@ -0,0 +1,81 @@
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_COMPONENT_GREEN_HH
+# define MLN_FUN_COMPONENT_GREEN_HH
+
+/// \file
+///
+/// Meta function to retrieve/modify the green component.
+
+# include <mln/fun/unary.hh>
+# include <mln/value/rgb.hh>
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ struct green : unary<green> {};
+
+ } // end of namespace mln::fun
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ template <unsigned n>
+ struct set_precise_unary_<mln::fun::green, mln::value::rgb<n> >
+ {
+ typedef set_precise_unary_ ret;
+ typedef mln::value::rgb<n> argument;
+ typedef typename argument::green_t result;
+ typedef argument& lvalue;
+
+ static result read(const argument& x)
+ {
+ return x.green();
+ }
+
+ static void write(lvalue l, const result& r)
+ {
+ l.green() = r;
+ }
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_COMPONENT_GREEN_HH
diff --git a/milena/mln/fun/component/red.hh b/milena/mln/fun/component/red.hh
new file mode 100644
index 0000000..3b40bc4
--- /dev/null
+++ b/milena/mln/fun/component/red.hh
@@ -0,0 +1,81 @@
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_COMPONENT_RED_HH
+# define MLN_FUN_COMPONENT_RED_HH
+
+/// \file
+///
+/// Meta function to retrieve/modify the red component.
+
+# include <mln/fun/unary.hh>
+# include <mln/value/rgb.hh>
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ struct red : unary<red> {};
+
+ } // end of namespace mln::fun
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ template <unsigned n>
+ struct set_precise_unary_<mln::fun::red, mln::value::rgb<n> >
+ {
+ typedef set_precise_unary_ ret;
+ typedef mln::value::rgb<n> argument;
+ typedef typename argument::red_t result;
+ typedef argument& lvalue;
+
+ static result read(const argument& x)
+ {
+ return x.red();
+ }
+
+ static void write(lvalue l, const result& r)
+ {
+ l.red() = r;
+ }
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_COMPONENT_RED_HH
diff --git a/milena/mln/fun/component/rgb.hh b/milena/mln/fun/component/rgb.hh
new file mode 100644
index 0000000..2a365d1
--- /dev/null
+++ b/milena/mln/fun/component/rgb.hh
@@ -0,0 +1,37 @@
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_COMPONENT_RGB_HH
+# define MLN_FUN_COMPONENT_RGB_HH
+
+/// \file
+///
+/// Meta functions to retrieve/modify rgb components.
+
+# include <mln/fun/component/red.hh>
+# include <mln/fun/component/green.hh>
+# include <mln/fun/component/blue.hh>
+
+#endif // ! MLN_FUN_COMPONENT_RGB_HH
diff --git a/milena/mln/fun/param.hh b/milena/mln/fun/param.hh
new file mode 100644
index 0000000..edeab7d
--- /dev/null
+++ b/milena/mln/fun/param.hh
@@ -0,0 +1,86 @@
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_PARAM_HH
+# define MLN_FUN_PARAM_HH
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ template <typename T>
+ struct stored
+ {
+ typedef T value;
+
+ const T& to_value() const
+ {
+ return t_;
+ }
+
+ T& to_value()
+ {
+ return t_;
+ }
+
+ operator const T& () const
+ {
+ return to_value();
+ }
+
+ operator T& ()
+ {
+ return to_value();
+ }
+
+ stored& operator = (const T& t)
+ {
+ t_ = t;
+ return *this;
+ }
+
+ protected:
+ T t_;
+ };
+
+ template <>
+ struct stored<void>
+ {
+ };
+
+ template <typename F>
+ struct parameter
+ {
+ typedef void param;
+ typedef void storage;
+ };
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_PARAM_HH
diff --git a/milena/mln/fun/spe/unary.hh b/milena/mln/fun/spe/unary.hh
new file mode 100644
index 0000000..47d7f41
--- /dev/null
+++ b/milena/mln/fun/spe/unary.hh
@@ -0,0 +1,334 @@
+// Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development
+// Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_SPE_UNARY_HH
+# define MLN_FUN_SPE_UNARY_HH
+
+# include <mln/core/concept/function.hh>
+# include <mln/trait/next/solve.hh>
+# include <mln/trait/functions.hh>
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace spe
+ {
+
+ // Wrapper for bijective functions
+ template <typename Fun, typename T>
+ struct lwrapper
+ {
+ typedef typename Fun::result result;
+ typedef typename Fun::argument argument;
+ typedef typename Fun::lvalue lvalue;
+ typedef lwrapper lresult;
+
+ lwrapper(const Fun& f, T& x)
+ : x_(&x), f_(&f)
+ {
+ }
+
+ result to_result() const
+ {
+ return (*f_)(*const_cast<const T*>(x_));
+ };
+
+ operator result() const
+ {
+ return to_result();
+ };
+
+ const result& operator = (const result& r) const
+ {
+ argument x(*x_);
+ f_->set(x, r);
+ *x_ = x;
+
+ return r;
+ }
+
+ private:
+ T *x_;
+ const Fun *f_;
+ };
+
+ template <typename Fun>
+ struct lwrapper<Fun, typename Fun::argument>
+ {
+ typedef typename Fun::result result;
+ typedef typename Fun::argument argument;
+ typedef typename Fun::lvalue lvalue;
+ typedef lwrapper lresult;
+
+ lwrapper(const Fun& f, argument& x)
+ : x_(&x), f_(&f)
+ {
+ }
+
+ result to_result() const
+ {
+ return (*f_)(*const_cast<const argument*>(x_));
+ };
+
+ operator result() const
+ {
+ return to_result();
+ };
+
+ const result& operator = (const result& r) const
+ {
+ f_->set(*x_, r);
+
+ return r;
+ }
+
+ private:
+ argument *x_;
+ const Fun *f_;
+ };
+
+ template <typename Fun, typename Any, typename T>
+ struct lwrapper<Fun, lwrapper<Any, T> >
+ {
+ typedef typename Fun::result result;
+ typedef typename Fun::argument argument;
+ typedef typename Fun::lvalue lvalue;
+ typedef lwrapper lresult;
+
+ lwrapper(const Fun& f, const lwrapper<Any, T>& m)
+ : m_(m), f_(&f)
+ {
+ }
+
+ result to_result() const
+ {
+ return (*f_)(m_.to_result());
+ };
+
+ operator result() const
+ {
+ return to_result();
+ };
+
+ const result& operator = (const result& r) const
+ {
+ argument m(m_);
+ f_->set(m, r);
+ m_ = m;
+
+ return r;
+ }
+
+ private:
+ const lwrapper<Any, T> m_;
+ const Fun *f_;
+ };
+
+ template <typename Fun, typename T>
+ struct unary;
+
+ namespace impl
+ {
+
+ template <bool param, bool set, typename Fun, typename T>
+ struct unary_impl;
+
+ template <typename Fun, typename T>
+ struct unary_impl<false, false, Fun, T> : Function_v2v< unary<Fun, T> >
+ {
+ typedef Fun flag;
+ typedef mln_trait_nunary(Fun, T) def;
+
+ typedef typename def::argument argument;
+ typedef typename def::result result;
+
+ result operator () (const argument& value) const
+ {
+ return def::read(value);
+ }
+
+ template <typename U>
+ void init(const U& value)
+ {
+ (void) value;
+ };
+
+ };
+
+ template <typename Fun, typename T>
+ struct unary_impl<false, true, Fun, T> : unary_impl<false, false, Fun, T>
+ {
+ typedef unary_impl<false, false, Fun, T> super;
+ typedef typename super::def::lvalue lvalue;
+
+ template <typename U>
+ struct lresult_with
+ {
+ typedef mln::fun::spe::lwrapper< unary<Fun, T>, U> ret;
+ };
+
+ typedef typename lresult_with<typename super::argument>::ret lresult;
+
+ void set(lvalue l, const typename super::result& r) const
+ {
+ super::def::write(l, r);
+ }
+
+ using super::operator ();
+
+ lresult apply_rw(typename super::argument& value) const
+ {
+ return lresult(exact(*this), value);
+ }
+
+ template <typename U>
+ typename lresult_with<U>::ret apply_rw(U& value) const
+ {
+ return typename lresult_with<U>::ret(exact(*this), value);
+ }
+
+ lresult operator () (typename super::argument& value) const
+ {
+ return apply_rw(value);
+ }
+ };
+
+ template <typename Fun, typename T>
+ struct unary_impl<true, false, Fun, T> : Function_v2v< unary<Fun, T> >
+ {
+ typedef Fun flag;
+ typedef mln_trait_nunary(Fun, T) def;
+
+ typedef typename def::argument argument;
+ typedef typename def::result result;
+
+ typedef mln_trait_fun_param(unary_impl) param;
+ typedef mln_trait_fun_storage(unary_impl) storage;
+
+ result operator () (const argument& value) const
+ {
+ return def::read(this->state_, value);
+ }
+
+ template <typename U>
+ void init(const U& value)
+ {
+ state_ = mln::trait::function::internal::introspect::has_storage_t<def, void>::compute(value);
+ };
+
+ stored<storage>& state()
+ {
+ return state_;
+ }
+
+ const stored<storage>& state() const
+ {
+ return state_;
+ }
+
+ protected:
+ stored<storage> state_;
+ };
+
+ template <typename Fun, typename T>
+ struct unary_impl<true, true, Fun, T> : unary_impl<true, false, Fun, T>
+ {
+ typedef unary_impl<true, false, Fun, T> super;
+ typedef typename super::def::lvalue lvalue;
+
+ template <typename U>
+ struct lresult_with
+ {
+ typedef mln::fun::spe::lwrapper< unary<Fun, T>, U> ret;
+ };
+
+ typedef typename lresult_with<typename super::argument>::ret lresult;
+
+ void set(lvalue l, const typename super::result& r) const
+ {
+ super::def::write(this->state(), l, r);
+ }
+
+ using super::operator ();
+
+ lresult apply_rw(typename super::argument& value) const
+ {
+ return lresult(exact(*this), value);
+ }
+
+ template <typename U>
+ typename lresult_with<U>::ret apply_rw(U& value) const
+ {
+ return typename lresult_with<U>::ret(exact(*this), value);
+ }
+
+ lresult operator () (typename super::argument& value) const
+ {
+ return apply_rw(value);
+ }
+ };
+
+ } // end of namespace mln::fun::spe::impl
+
+ template <typename Fun, typename T>
+ struct unary
+ : impl::unary_impl<mlc_or(mln_trait_fun_is_parametrable(mln_trait_nunary(Fun, T)), mln_trait_fun_is_parametrable(Fun))::value,
+ mln_trait_fun_is_assignable_(mln_trait_nunary(Fun, T))::value, Fun, T>
+ {
+ typedef mln_trait_nunary(Fun, T) def;
+ typedef impl::unary_impl<mlc_or(mln_trait_fun_is_parametrable(def), mln_trait_fun_is_parametrable(Fun))::value,
+ mln_trait_fun_is_assignable_(def)::value,
+ Fun,
+ T>
+ super;
+
+ unary() {}
+
+ template <typename U>
+ unary(const U& param)
+ {
+ this->init(param);
+ }
+
+ using super::operator();
+ };
+
+ } // end of namespace mln::fun::spe
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+template <typename F, typename T>
+std::ostream& operator << (std::ostream& o, const mln::fun::spe::lwrapper<F, T>& m)
+{
+ return o << m.to_result();
+}
+
+#endif // ! MLN_FUN_SPE_UNARY_HH
diff --git a/milena/mln/fun/unary.hh b/milena/mln/fun/unary.hh
new file mode 100644
index 0000000..1e1ee2b
--- /dev/null
+++ b/milena/mln/fun/unary.hh
@@ -0,0 +1,175 @@
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_FUN_UNARY_HH
+# define MLN_FUN_UNARY_HH
+
+# include <mln/core/concept/meta_function.hh>
+# include <mln/fun/spe/unary.hh>
+# include <mln/trait/next/solve.hh>
+
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ // Forward declarations, for composition with unary::operator()(Fun)
+ struct compose;
+
+ namespace internal
+ {
+
+ template <typename U>
+ struct unary_with {};
+
+ }
+
+ template <typename F, typename E = F>
+ struct unary: mln::Meta_Function_v2v< E >
+ {
+ typedef F flag;
+ typedef mln_trait_fun_param(flag) param;
+ typedef mln_trait_fun_storage(flag) storage;
+
+ template <typename T>
+ struct with {
+ typedef mln_trait_nunary(internal::unary_with<F>, T) def;
+ typedef typename def::ret ret;
+ };
+
+ template <typename T>
+ typename with<T>::ret::result operator()(const T& v) const
+ {
+ return with<T>::def::call(exact(*this), v);
+ }
+
+ template <typename T>
+ typename with<T>::ret::template lresult_with<T>::ret operator()(T& v) const
+ {
+ // See the commentary in next method.
+ typedef typename with<T>::ret fun_t;
+ fun_t f(state());
+ return f.apply_rw(v);
+ }
+
+ template <typename T, typename R>
+ void set(T& v, const R& r) const
+ {
+ // Decomposing "with<T>::ret(state()).set(v, r)" into 3 lines
+ // helps g++-3.3!
+ typedef typename with<T>::ret fun_t;
+ fun_t f(state());
+ f.set(v, r);
+ }
+
+ template <typename U>
+ void init(const U& value)
+ {
+ state_ = mln::trait::function::internal::introspect::has_storage_t<flag, void>::compute(value);
+ };
+
+ unary()
+ {
+ }
+
+ template <typename U>
+ unary(const U& param)
+ {
+ this->init(param);
+ }
+
+ stored<storage>& state()
+ {
+ return state_;
+ }
+
+ const stored<storage>& state() const
+ {
+ return state_;
+ }
+
+ protected:
+ stored<storage> state_;
+ };
+
+ } // end of namespace mln::fun
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ // Any type
+ template <typename F, typename T>
+ struct set_unary_< mln::fun::internal::unary_with<F>, mln::Object, T>
+ {
+ struct ret_t
+ {
+ typedef mln::fun::spe::unary<F, T> ret;
+
+ static typename ret::result call(const F& f, const T& v)
+ {
+ return ret(f.state())(v);
+ }
+ };
+
+ typedef ret_t ret;
+ };
+
+ // Meta Function
+ template <typename F, typename G>
+ struct set_unary_< mln::fun::internal::unary_with<F>, mln::Meta_Function, G>
+ {
+ // FIXME: Workaround for cyclic references (unary -> unary_with -> compose -> unary)
+ template <typename T>
+ struct identity
+ {
+ typedef T ret;
+ };
+
+ struct ret_t
+ {
+ typedef typename identity<mln::fun::compose>::ret::template with<F, G>::ret ret;
+
+ static typename ret::result call(const F& f, const G& g)
+ {
+ return ret()(f, g);
+ }
+
+ };
+
+ typedef ret_t ret;
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_UNARY_HH
diff --git a/milena/mln/trait/functions.hh b/milena/mln/trait/functions.hh
new file mode 100644
index 0000000..01b8330
--- /dev/null
+++ b/milena/mln/trait/functions.hh
@@ -0,0 +1,251 @@
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_TRAIT_FUNCTIONS_HH
+# define MLN_TRAIT_FUNCTIONS_HH
+
+# include <mln/metal/bexpr.hh>
+# include <mln/metal/if.hh>
+# include <mln/fun/param.hh>
+# include <mln/trait/next/solve.hh>
+
+# define mln_trait_fun_is_assignable(Fun) typename mln::trait::function::is_assignable< Fun >::ret
+# define mln_trait_fun_is_assignable_(Fun) mln::trait::function::is_assignable< Fun >::ret
+# define mln_trait_fun_is_assignable__1comma(A, B) typename mln::trait::function::is_assignable< A, B >::ret
+# define mln_trait_fun_is_assignable__1comma_(A, B) mln::trait::function::is_assignable< A, B >::ret
+
+# define mln_trait_fun_is_parametrable(Fun) typename mln::trait::function::is_parametrable< Fun >::ret
+# define mln_trait_fun_is_parametrable_(Fun) mln::trait::function::is_parametrable< Fun >::ret
+
+# define mln_trait_fun_lvalue(Fun) typename mln::trait::function::get_lvalue< Fun >::ret
+# define mln_trait_fun_param(Fun) typename mln::trait::function::get_param< Fun >::ret
+# define mln_trait_fun_storage(Fun) typename mln::trait::function::get_storage< Fun >::ret
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ namespace function
+ {
+
+ namespace internal
+ {
+
+ namespace introspect
+ {
+
+ template <typename T>
+ struct except_void_t
+ {
+ typedef void ret;
+ };
+
+ template <>
+ struct except_void_t<void>;
+
+ // Lvalue solver
+
+ template <typename T, typename V>
+ struct has_lvalue_t
+ {
+ typedef metal::false_ ret;
+ typedef void type;
+ };
+
+ template <typename T>
+ struct has_lvalue_t<T, typename except_void_t<typename T::lvalue>::ret>
+ {
+ typedef metal::true_ ret;
+ typedef typename T::lvalue type;
+ };
+
+ // Parameter solver
+ template <typename T, typename V>
+ struct param_solver;
+
+ template <typename T, typename V>
+ struct param_flag_solver
+ {
+ typedef typename mln::fun::parameter<T> ret;
+ };
+
+ template <typename T>
+ struct param_flag_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::flag>::param>::ret>
+ {
+ typedef mln::fun::parameter<typename T::flag> ret;
+ };
+
+ template <typename T, typename V>
+ struct param_def_solver
+ {
+ typedef typename param_flag_solver<T, V>::ret ret;
+ };
+
+ template <typename T>
+ struct param_def_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::def>::param>::ret>
+ {
+ typedef mln::fun::parameter<typename T::def> ret;
+ };
+
+ template <typename T, typename V>
+ struct param_solver : param_def_solver<T, V>
+ {
+ };
+
+ template <typename T>
+ struct param_solver<T, typename except_void_t<typename T::param>::ret>
+ {
+ typedef T ret;
+ };
+
+ template <typename T, typename V>
+ struct has_param_t
+ {
+ typedef metal::false_ ret;
+ typedef void type;
+ };
+
+ template <typename T>
+ struct has_param_t<T, typename except_void_t<typename param_solver<T,void>::ret::param>::ret>
+ {
+ typedef metal::true_ ret;
+ typedef typename param_solver<T,void>::ret::param type;
+ };
+
+ template <typename T, typename V>
+ struct storage_solver;
+
+ template <typename T, typename V>
+ struct storage_flag_solver
+ {
+ typedef typename mln::fun::parameter<T> ret;
+ };
+
+ template <typename T>
+ struct storage_flag_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::flag>::storage>::ret>
+ {
+ typedef mln::fun::parameter<typename T::flag> ret;
+ };
+
+ template <typename T, typename V>
+ struct storage_def_solver
+ {
+ typedef typename storage_flag_solver<T, V>::ret ret;
+ };
+
+ template <typename T>
+ struct storage_def_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::def>::storage>::ret>
+ {
+ typedef mln::fun::parameter<typename T::def> ret;
+ };
+
+ template <typename T, typename V>
+ struct storage_solver : storage_def_solver<T, V>
+ {
+ };
+
+ template <typename T>
+ struct storage_solver<T, typename except_void_t<typename T::storage>::ret>
+ {
+ typedef T ret;
+ };
+
+ template <typename T, typename V>
+ struct has_storage_t
+ {
+ typedef has_param_t<T, V> has_param;
+
+ typedef metal::false_ ret;
+ typedef typename has_param::type type;
+
+ template <typename U>
+ static inline
+ const U& compute(const U& t)
+ {
+ return t;
+ }
+
+ };
+
+ template <typename T>
+ struct has_storage_t<T, typename except_void_t<typename param_solver<T,void>::ret::storage>::ret>
+ {
+ typedef metal::true_ ret;
+ typedef typename param_solver<T,void>::ret def;
+
+ typedef typename def::storage type;
+
+ template <typename U>
+ static inline
+ type compute(const U& p)
+ {
+ return def::compute(p);
+ }
+
+ };
+
+ } // end of namespace mln::trait::fun::internal::introspect
+
+ } // end of namespace mln::trait::fun::internal
+
+ template <typename F>
+ struct is_assignable
+ {
+ typedef typename internal::introspect::has_lvalue_t<F, void>::ret ret;
+ };
+
+ template <typename F>
+ struct is_parametrable
+ {
+ typedef typename internal::introspect::has_param_t<F, void>::ret ret;
+ };
+
+ template <typename F>
+ struct get_lvalue
+ {
+ typedef typename internal::introspect::has_lvalue_t<F, void>::type ret;
+ };
+
+ template <typename F>
+ struct get_param
+ {
+ typedef typename internal::introspect::has_param_t<F, void>::type ret;
+ };
+
+ template <typename F>
+ struct get_storage
+ {
+ typedef typename internal::introspect::has_storage_t<F, void>::type ret;
+ };
+
+ } // end of namespace mln::trait::fun
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+#endif // ! MLN_TRAIT_FUNCTIONS_HH
diff --git a/milena/mln/trait/next/solve.hh b/milena/mln/trait/next/solve.hh
new file mode 100644
index 0000000..747bdaa
--- /dev/null
+++ b/milena/mln/trait/next/solve.hh
@@ -0,0 +1,146 @@
+// Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_TRAIT_NEXT_SOLVE_HH
+# define MLN_TRAIT_NEXT_SOLVE_HH
+
+/// \file
+///
+/// FIXME
+
+# include <mln/core/category.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/ret.hh>
+# include <mln/trait/solve.hh>
+
+
+// FIXME: Just for the record (use it...)
+
+# ifndef MLN_DEBUG_TRAITS
+# endif // ! MLN_DEBUG_TRAITS
+
+
+# define mln_trait_nunary(Name, T) typename mln::trait::next::solve_unary< Name, T >::ret
+# define mln_trait_nunary_(Name, T) mln::trait::next::solve_unary< Name, T >::ret
+
+# define mln_trait_nbinary(Name, T1, T2) typename mln::trait::next::solve_binary< Name, T1, T2 >::ret
+# define mln_trait_nbinary_(Name, T1, T2) mln::trait::next::solve_binary< Name, T1, T2 >::ret
+
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ // Unary case.
+
+
+ template < typename Name,
+ typename T >
+ struct set_precise_unary_
+ {
+ typedef undefined ret;
+ };
+
+
+ template < typename Name,
+ template <class> class Category_T, typename T >
+ struct set_unary_
+ {
+ typedef undefined ret;
+ };
+
+ template < typename Name,
+ typename T >
+ struct set_unary_< Name, Unknown, T > // Blocker; top of inheritance.
+ {
+ typedef not_found ret;
+ };
+
+
+
+
+ // Binary case.
+
+
+ template < typename Name,
+ typename L,
+ typename R >
+ struct set_precise_binary_
+ {
+ typedef undefined ret;
+ };
+
+
+ template < typename Name,
+ template <class> class Category_L, typename L,
+ template <class> class Category_R, typename R >
+ struct set_binary_
+ {
+ typedef undefined ret;
+ };
+
+ template < typename Name,
+ typename L,
+ template <class> class Category_R, typename R >
+ struct set_binary_< Name, Unknown, L, Category_R, R > // Left blocker.
+ {
+ typedef not_found ret;
+ };
+
+ template < typename Name,
+ template <class> class Category_L, typename L,
+ typename R >
+ struct set_binary_< Name, Category_L, L, Unknown, R > // Right blocker.
+ {
+ typedef not_found ret;
+ };
+
+ template < typename Name,
+ typename L,
+ typename R >
+ struct set_binary_< Name, Unknown, L, Unknown, R > // Blocker.
+ {
+ typedef not_found ret;
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+# include <mln/trait/next/solve_unary.hh>
+# include <mln/trait/next/solve_binary.hh>
+# include <mln/trait/next/solve_proxy.hh>
+
+#endif // ! MLN_TRAIT_NEXT_SOLVE_HH
diff --git a/milena/mln/trait/next/solve_binary.hh b/milena/mln/trait/next/solve_binary.hh
new file mode 100644
index 0000000..0eccf26
--- /dev/null
+++ b/milena/mln/trait/next/solve_binary.hh
@@ -0,0 +1,300 @@
+// Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_TRAIT_NEXT_SOLVE_BINARY_HH
+# define MLN_TRAIT_NEXT_SOLVE_BINARY_HH
+
+/// \file
+///
+/// FIXME
+
+# include <mln/core/category.hh>
+# include <mln/core/routine/exact.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/ret.hh>
+# include <mln/trait/next/solve.hh>
+
+
+// FIXME: Just for the record (use it...)
+
+# ifndef MLN_DEBUG_TRAITS
+# endif // ! MLN_DEBUG_TRAITS
+
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ namespace internal
+ {
+
+
+ template < typename Name,
+ typename Category_L, typename L,
+ typename Category_R, typename R >
+ struct trait_set_binary_;
+
+ template < typename Name,
+ template <class> class Category_L, typename _l, typename L,
+ template <class> class Category_R, typename _r, typename R >
+ struct trait_set_binary_< Name,
+ Category_L<_l>, L,
+ Category_R<_r>, R >
+ {
+ typedef typename mln::trait::next::set_binary_<Name,
+ Category_L, L,
+ Category_R, R>::ret ret;
+ };
+
+
+ // triplet_ret_
+
+ template < unsigned i_L_, unsigned i_R_, typename ret_ >
+ struct triplet_
+ {
+ typedef ret_ ret;
+ };
+
+
+ // merge_triplets_
+
+ template < typename L_trp, typename R_trp >
+ struct merge_triplets_;
+
+ template < unsigned L_i_L, unsigned L_i_R, typename L_ret,
+ unsigned R_i_L, unsigned R_i_R, typename R_ret >
+ struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>,
+ triplet_<R_i_L, R_i_R, R_ret> >
+ {
+ typedef metal::bool_<(L_i_L <= R_i_L && L_i_R <= R_i_R)> take_L;
+ typedef metal::bool_<(R_i_L <= L_i_L && R_i_R <= L_i_R)> take_R;
+ typedef metal::or_<take_L, take_R> ok;
+ typedef typename metal::if_< metal::and_<ok, take_L>,
+ triplet_<L_i_L, L_i_R, L_ret>,
+ typename metal::if_< metal::and_<ok, take_R>,
+ triplet_<R_i_L, R_i_R, R_ret>,
+ triplet_<0,0, not_found> >::ret >::ret ret;
+ };
+
+ template < unsigned i_L, unsigned i_R, typename LR_ret >
+ struct merge_triplets_< triplet_<i_L, i_R, LR_ret>,
+ triplet_<i_L, i_R, LR_ret> >
+ {
+ typedef triplet_<i_L, i_R, LR_ret> ret;
+ };
+
+
+ template < unsigned L_i_L, unsigned L_i_R, unsigned L_i_max,
+ unsigned R_i_L, unsigned R_i_R, unsigned R_i_max >
+ // L_i_max and R_i_max differ
+ struct helper_merge_triplets_same_ret_
+ {
+ // The winning couple between L_* and R_* is the one which
+ // maximum index is the smallest; for instance, with:
+ // left branch giving L_i_L = 5 and L_i_R = 1 so L_i_max = 5
+ // right branch giving L_i_L = 3 and L_i_R = 4 so R_i_max = 4
+ // the right branch wins.
+ enum { i_L = (L_i_max < R_i_max ? L_i_L : R_i_L),
+ i_R = (L_i_max < R_i_max ? L_i_R : R_i_R) };
+ };
+
+ template < unsigned L_i_L, unsigned L_i_R, unsigned i_max,
+ unsigned R_i_L, unsigned R_i_R >
+ // L_i_max is equal to R_i_max
+ struct helper_merge_triplets_same_ret_< L_i_L, L_i_R, i_max,
+ R_i_L, R_i_R, i_max >
+ {
+ // The winning couple is the one with the minimum index.
+ enum { L_i_min = (L_i_L < L_i_R ? L_i_L : L_i_R),
+ R_i_min = (R_i_L < R_i_R ? R_i_L : R_i_R),
+ i_L = (L_i_min < R_i_min ? L_i_L : R_i_L),
+ i_R = (L_i_min < R_i_min ? L_i_R : R_i_R) };
+ };
+
+
+ template < unsigned L_i_L, unsigned L_i_R, typename LR_ret,
+ unsigned R_i_L, unsigned R_i_R >
+ struct merge_triplets_< triplet_<L_i_L, L_i_R, LR_ret>,
+ triplet_<R_i_L, R_i_R, LR_ret> >
+ {
+ typedef helper_merge_triplets_same_ret_< L_i_L, L_i_R, (L_i_L > L_i_R ? L_i_L : L_i_R),
+ R_i_L, R_i_R, (R_i_L > R_i_R ? R_i_L : R_i_R) > helper;
+ typedef triplet_<helper::i_L, helper::i_R, LR_ret> ret;
+ };
+
+ template < unsigned L_i_L, unsigned L_i_R, typename L_ret >
+ struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>,
+ triplet_< 0, 0, not_found> >
+ {
+ typedef triplet_<L_i_L, L_i_R, L_ret> ret;
+ };
+
+ template < unsigned R_i_L, unsigned R_i_R, typename R_ret >
+ struct merge_triplets_< triplet_< 0, 0, not_found>,
+ triplet_<R_i_L, R_i_R, R_ret> >
+ {
+ typedef triplet_<R_i_L, R_i_R, R_ret> ret;
+ };
+
+ template <> // To disambiguate.
+ struct merge_triplets_< triplet_<0, 0, not_found>,
+ triplet_<0, 0, not_found> >
+ {
+ typedef triplet_<0u,0u, not_found> ret;
+ };
+
+
+
+ // Fwd decl.
+ template < typename Name,
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
+ struct get_binary_;
+
+
+ template < typename user_ret, /* != not_found and != undefined */
+ typename Name,
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
+ struct helper_get_binary_
+ {
+ typedef triplet_< i_L, i_R, user_ret > ret; // The user has defined 'ret' so we return it.
+ };
+
+ template < typename Name,
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
+ struct helper_get_binary_< /* user_ret == */ not_found,
+ Name, i_L, Category_L, L, i_R, Category_R, R >
+ {
+ typedef triplet_< 0, 0, not_found > ret; // End of search due to a blocker; 'ret' is not found.
+ };
+
+
+ template < typename Name,
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
+ struct helper_get_binary_< /* user_ret == */ undefined,
+ Name, i_L,Category_L, L, i_R,Category_R, R >
+ {
+ // No user definition for 'ret' so treillis construction in a static recursive way.
+
+ // FIXME: We *do* need to handle this search with a priority!
+ // FIXME: for a result can be found in both branches...
+
+ typedef typename mln::internal::super_category_< Category_L, L >::ret Super_Category_L;
+ typedef typename mln::internal::super_category_< Category_R, R >::ret Super_Category_R;
+
+ typedef get_binary_< Name,
+ i_L + 1, Super_Category_L, L,
+ i_R, Category_R, R > L_branch;
+ typedef mlc_ret(L_branch) L_trp;
+
+ typedef get_binary_< Name,
+ i_L, Category_L, L,
+ i_R + 1, Super_Category_R, R > R_branch;
+ typedef mlc_ret(R_branch) R_trp;
+
+ typedef typename merge_triplets_< L_trp, R_trp >::ret ret;
+ };
+
+
+ template < typename Name,
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
+ struct get_binary_
+ {
+ typedef typename trait_set_binary_<Name, Category_L,L,
+ Category_R,R>::ret user_ret; // First get 'user_ret'
+ typedef helper_get_binary_<user_ret, Name, i_L,Category_L,L,
+ i_R,Category_R,R> helper; // Set the helper to make a decision.
+ typedef mlc_ret(helper) ret; // Return a triplet.
+ };
+
+
+ template < typename precise_ret,
+ typename Name,
+ typename Category_L, typename L,
+ typename Category_R, typename R >
+ struct helper_choose_binary_wrt_ /* precise_ret != undefined */
+ {
+ typedef precise_ret ret; // -> A precise ret has been defined so it is it.
+ };
+
+ template < typename Name,
+ typename Category_L, typename L,
+ typename Category_R, typename R >
+ struct helper_choose_binary_wrt_< /* precise_ret == */ undefined,
+ Name, Category_L, L, Category_R, R >
+ {
+ typedef typename get_binary_< Name,
+ 0, Category_L, L,
+ 0, Category_R, R >::ret triplet; // Browse upwards the category inheritance
+ typedef mlc_ret(triplet) ret; // to fetch ret from 'get_binary_'s.
+ };
+
+
+ template < typename Name,
+ typename Category_L, typename L,
+ typename Category_R, typename R >
+ struct helper_solve_binary_
+ {
+ typedef typename set_precise_binary_<Name, L, R>::ret precise_ret; /* undefined or not (?) */
+ typedef helper_choose_binary_wrt_<precise_ret, Name, Category_L,L, Category_R,R> helper;
+ typedef mlc_ret(helper) ret;
+ };
+
+ } // end of namespace mln::trait::internal
+
+
+ // FIXME: Postfix solve_binary with a '-'(?)
+ template < typename Name,
+ typename L_,
+ typename R_ >
+ struct solve_binary
+ {
+ typedef mln_exact(L_) L;
+ typedef mln_exact(R_) R;
+ typedef typename mln::category<L>::ret Category_L;
+ typedef typename mln::category<R>::ret Category_R;
+ typedef internal::helper_solve_binary_< Name, Category_L, L, Category_R, R > meta_code;
+ typedef typename meta_code::ret ret;
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_NEXT_SOLVE_BINARY_HH
diff --git a/milena/mln/trait/next/solve_proxy.hh b/milena/mln/trait/next/solve_proxy.hh
new file mode 100644
index 0000000..c2e2dc1
--- /dev/null
+++ b/milena/mln/trait/next/solve_proxy.hh
@@ -0,0 +1,98 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_TRAIT_NEXT_SOLVE_PROXY_HH
+# define MLN_TRAIT_NEXT_SOLVE_PROXY_HH
+
+/// \file
+///
+/// Proxy support for "next" trait solver.
+
+
+# include <mln/core/concept/object.hh>
+# include <mln/core/concept/proxy.hh>
+# include <mln/core/concept/proxy.hxx>
+
+# include <mln/trait/next/solve.hh>
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ // Forward declaration
+ // Needed by mln_trait_nbinary.
+ template < typename Name, typename L_, typename R_ >
+ struct solve_binary;
+ template < typename Name, typename T_ > struct solve_unary;
+
+
+
+ // Unary ops.
+
+ template < typename Op, typename P >
+ struct set_unary_< Op, mln::Proxy, P >
+ {
+ typedef mlc_unqualif(mln_q_subject(P)) S;
+ typedef mln_trait_nunary(Op, S) ret;
+ };
+
+ // Binary ops.
+
+ template < typename Op, typename L, typename R >
+ struct set_binary_< Op, mln::Proxy, L, mln::Proxy, R >
+ {
+ typedef mln::internal::helper_unprox_binop<L, R> helper;
+ typedef mln_trait_nbinary(Op,
+ typename helper::L_ret,
+ typename helper::R_ret) ret;
+ };
+
+ template < typename Op, typename P, typename O >
+ struct set_binary_< Op, mln::Proxy, P, mln::Object, O >
+ {
+ typedef mlc_unqualif(mln_q_subject(P)) S;
+ typedef mln_trait_nbinary(Op, S, O) ret;
+ };
+
+ template < typename Op, typename O, typename P >
+ struct set_binary_< Op, mln::Object, O, mln::Proxy, P >
+ {
+ typedef mlc_unqualif(mln_q_subject(P)) S;
+ typedef mln_trait_nbinary(Op, O, S) ret;
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_NEXT_SOLVE_PROXY_HH
diff --git a/milena/mln/trait/next/solve_unary.hh b/milena/mln/trait/next/solve_unary.hh
new file mode 100644
index 0000000..86b1d9a
--- /dev/null
+++ b/milena/mln/trait/next/solve_unary.hh
@@ -0,0 +1,170 @@
+// Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_TRAIT_NEXT_SOLVE_UNARY_HH
+# define MLN_TRAIT_NEXT_SOLVE_UNARY_HH
+
+/*!
+ * \file
+ *
+ * \brief FIXME
+ *
+ *
+ */
+
+# include <mln/core/category.hh>
+# include <mln/core/routine/exact.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/ret.hh>
+# include <mln/trait/next/solve.hh>
+
+
+// FIXME: Just for the record (use it...)
+
+# ifndef MLN_DEBUG_TRAITS
+# endif // ! MLN_DEBUG_TRAITS
+
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ namespace internal
+ {
+
+
+ template < typename Name,
+ typename Category,
+ typename T >
+ struct trait_set_unary_;
+
+ template < typename Name,
+ template <class> class Category, typename _,
+ typename T >
+ struct trait_set_unary_< Name, Category<_>, T >
+ {
+ typedef typename mln::trait::next::set_unary_<Name, Category, T>::ret ret;
+ };
+
+
+ // Fwd decls.
+ template < typename Name,
+ typename Category, typename T >
+ struct get_unary_;
+
+
+ template < typename user_ret, /* != not_found and != undefined */
+ typename Name,
+ typename Category, typename T >
+ struct helper_get_unary_
+ {
+ typedef user_ret ret; // The user has defined 'ret' so we return it.
+ };
+
+
+ template < typename Name,
+ typename Category, typename T >
+ struct helper_get_unary_< /* user_ret == */ not_found,
+ Name, Category, T >
+ {
+ typedef not_found ret; // End of search due to a blocker; 'ret' is not found.
+ };
+
+
+ template < typename Name,
+ typename Category, typename T >
+ struct helper_get_unary_< /* user_ret == */ undefined,
+ Name, Category, T >
+ {
+ typedef typename mln::internal::super_category_< Category, T >::ret Super_Category;
+ typedef typename get_unary_<Name, Super_Category, T>::ret ret; // No user ret definition => Recursion.
+ };
+
+
+ template < typename Name,
+ typename Category, typename T >
+ struct get_unary_
+ {
+ typedef typename trait_set_unary_<Name, Category, T>::ret user_ret; // First get 'user_ret'
+ typedef helper_get_unary_<user_ret, Name, Category, T> helper; // Set the helper to make a decision.
+ typedef mlc_ret(helper) ret; // Return.
+ };
+
+
+ template < typename precise_ret,
+ typename Name,
+ typename Category, typename T >
+ struct helper_choose_unary_wrt_ /* precise_ret != undefined */
+ {
+ typedef precise_ret ret; // -> A precise ret has been defined so it is it.
+ };
+
+ template < typename Name,
+ typename Category, typename T >
+ struct helper_choose_unary_wrt_< /* precise_ret == */ undefined,
+ Name, Category, T >
+ {
+ typedef typename get_unary_<Name, Category, T>::ret ret; // -> Go up into the category inheritance
+ // to fetch a ret from 'set_unary_'s.
+ };
+
+ template < typename Name,
+ typename Category, typename T >
+ struct helper_solve_unary_
+ {
+ typedef typename set_precise_unary_<Name, T>::ret precise_ret;
+ typedef helper_choose_unary_wrt_< precise_ret, /* undefined or not (?) */
+ Name, Category, T> helper;
+ typedef mlc_ret(helper) ret;
+ };
+
+ } // end of namespace mln::trait::next::internal
+
+
+ template < typename Name,
+ typename T_ >
+ struct solve_unary
+ {
+ typedef mln_exact(T_) T;
+ typedef typename mln::category<T>::ret Category;
+ typedef internal::helper_solve_unary_< Name, Category, T > meta_code;
+ typedef typename meta_code::ret ret;
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_NEXT_SOLVE_UNARY_HH
diff --git a/milena/tests/unit_test/unit-tests.mk b/milena/tests/unit_test/unit-tests.mk
index 2d2864e..4fc2dad 100644
--- a/milena/tests/unit_test/unit-tests.mk
+++ b/milena/tests/unit_test/unit-tests.mk
@@ -378,6 +378,7 @@ mln_core_image_vertex_image \
mln_core_image_vmorph_all \
mln_core_image_vmorph_cast_image \
mln_core_image_vmorph_fun_image \
+mln_core_image_vmorph_thru_image \
mln_core_image_vmorph_violent_cast_image \
mln_core_internal_box_impl \
mln_core_internal_check_image_all \
@@ -563,6 +564,10 @@ mln_extension_fill \
mln_fun_all \
mln_fun_c \
mln_fun_cast \
+mln_fun_component_blue \
+mln_fun_component_green \
+mln_fun_component_red \
+mln_fun_component_rgb \
mln_fun_essential \
mln_fun_i2v_all \
mln_fun_i2v_all_to \
@@ -593,8 +598,11 @@ mln_fun_p2v_elifs \
mln_fun_p2v_essential \
mln_fun_p2v_iota \
mln_fun_p2v_ternary \
+mln_fun_param \
+mln_fun_spe_unary \
mln_fun_stat_all \
mln_fun_stat_mahalanobis \
+mln_fun_unary \
mln_fun_v2b_all \
mln_fun_v2b_essential \
mln_fun_v2b_lnot \
@@ -1105,11 +1113,16 @@ mln_trait_ch_function_value \
mln_trait_ch_value \
mln_trait_concrete \
mln_trait_essential \
+mln_trait_functions \
mln_trait_image_print \
mln_trait_image_props \
mln_trait_image_from_grid \
mln_trait_images \
mln_trait_neighborhood \
+mln_trait_next_solve \
+mln_trait_next_solve_binary \
+mln_trait_next_solve_proxy \
+mln_trait_next_solve_unary \
mln_trait_op_all \
mln_trait_op_and \
mln_trait_op_decl \
@@ -1629,6 +1642,7 @@ mln_core_image_vertex_image_SOURCES = mln_core_image_vertex_image.cc
mln_core_image_vmorph_all_SOURCES = mln_core_image_vmorph_all.cc
mln_core_image_vmorph_cast_image_SOURCES = mln_core_image_vmorph_cast_image.cc
mln_core_image_vmorph_fun_image_SOURCES = mln_core_image_vmorph_fun_image.cc
+mln_core_image_vmorph_thru_image_SOURCES = mln_core_image_vmorph_thru_image.cc
mln_core_image_vmorph_violent_cast_image_SOURCES = mln_core_image_vmorph_violent_cast_image.cc
mln_core_internal_box_impl_SOURCES = mln_core_internal_box_impl.cc
mln_core_internal_check_image_all_SOURCES = mln_core_internal_check_image_all.cc
@@ -1814,6 +1828,10 @@ mln_extension_fill_SOURCES = mln_extension_fill.cc
mln_fun_all_SOURCES = mln_fun_all.cc
mln_fun_c_SOURCES = mln_fun_c.cc
mln_fun_cast_SOURCES = mln_fun_cast.cc
+mln_fun_component_blue_SOURCES = mln_fun_component_blue.cc
+mln_fun_component_green_SOURCES = mln_fun_component_green.cc
+mln_fun_component_red_SOURCES = mln_fun_component_red.cc
+mln_fun_component_rgb_SOURCES = mln_fun_component_rgb.cc
mln_fun_essential_SOURCES = mln_fun_essential.cc
mln_fun_i2v_all_SOURCES = mln_fun_i2v_all.cc
mln_fun_i2v_all_to_SOURCES = mln_fun_i2v_all_to.cc
@@ -1844,8 +1862,11 @@ mln_fun_p2v_elifs_SOURCES = mln_fun_p2v_elifs.cc
mln_fun_p2v_essential_SOURCES = mln_fun_p2v_essential.cc
mln_fun_p2v_iota_SOURCES = mln_fun_p2v_iota.cc
mln_fun_p2v_ternary_SOURCES = mln_fun_p2v_ternary.cc
+mln_fun_param_SOURCES = mln_fun_param.cc
+mln_fun_spe_unary_SOURCES = mln_fun_spe_unary.cc
mln_fun_stat_all_SOURCES = mln_fun_stat_all.cc
mln_fun_stat_mahalanobis_SOURCES = mln_fun_stat_mahalanobis.cc
+mln_fun_unary_SOURCES = mln_fun_unary.cc
mln_fun_v2b_all_SOURCES = mln_fun_v2b_all.cc
mln_fun_v2b_essential_SOURCES = mln_fun_v2b_essential.cc
mln_fun_v2b_lnot_SOURCES = mln_fun_v2b_lnot.cc
@@ -2356,11 +2377,16 @@ mln_trait_ch_function_value_SOURCES = mln_trait_ch_function_value.cc
mln_trait_ch_value_SOURCES = mln_trait_ch_value.cc
mln_trait_concrete_SOURCES = mln_trait_concrete.cc
mln_trait_essential_SOURCES = mln_trait_essential.cc
+mln_trait_functions_SOURCES = mln_trait_functions.cc
mln_trait_image_print_SOURCES = mln_trait_image_print.cc
mln_trait_image_props_SOURCES = mln_trait_image_props.cc
mln_trait_image_from_grid_SOURCES = mln_trait_image_from_grid.cc
mln_trait_images_SOURCES = mln_trait_images.cc
mln_trait_neighborhood_SOURCES = mln_trait_neighborhood.cc
+mln_trait_next_solve_SOURCES = mln_trait_next_solve.cc
+mln_trait_next_solve_binary_SOURCES = mln_trait_next_solve_binary.cc
+mln_trait_next_solve_proxy_SOURCES = mln_trait_next_solve_proxy.cc
+mln_trait_next_solve_unary_SOURCES = mln_trait_next_solve_unary.cc
mln_trait_op_all_SOURCES = mln_trait_op_all.cc
mln_trait_op_and_SOURCES = mln_trait_op_and.cc
mln_trait_op_decl_SOURCES = mln_trait_op_decl.cc
--
1.7.2.5