Olena-patches
  Threads by month 
                
            - ----- 2025 -----
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2024 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2023 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2022 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2021 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2020 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2019 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2018 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2017 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2016 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2015 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2014 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2013 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2012 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2011 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2010 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2009 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2008 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2007 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2006 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2005 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2004 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 
- 9625 discussions
 
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-02  Matthieu Garrigues  <garrigues(a)lrde.epita.fr>
	My log.
	* sandbox/garrigues/log: List all my tasks in milena.
---
 log |   35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
Index: trunk/milena/sandbox/garrigues/log
===================================================================
--- trunk/milena/sandbox/garrigues/log	(revision 0)
+++ trunk/milena/sandbox/garrigues/log	(revision 1219)
@@ -0,0 +1,35 @@
+* Gestion de la 1d.
+
+* Conversions de (window, point) a vec_p.
+
+* Conversions de histo a image1d.
+
+* Tests sur la modification de comportement des types de valeurs (Sandbox).
+
+* valeurs RGB.
+
+* println with border.
+
+* Chargement / Sauvegarde des types PNM 8/16, fits, pfm.
+
+* Reprise du track pointer de olena.
+
+* Mise a jour des image heritant d'image_adaptator.
+
+* Mise a jour des classes pour le 'garbage collector'.
+
+* Creation du morpheur identite.
+
+* Mise a jour des classes d'images morpheuses en consequences de l'arrivee
+des morpheurs.
+
+* Test de l'heritage en diamant pour la class image_identity.
+
+* Creation des plain images (Images dont les donnes ne sont pas partagees).
+
+* Deplacement des inits en dehors du namespace impl pour contourner un
+ probleme du compilateur.
+
+* Creation des types graylevel et gray.
+
+* Creation du type float01_ et float01.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-02  Matthieu Garrigues  <garrigues(a)lrde.epita.fr>
	Add float01 values. float01_<n> type is used to represent quantified
	float numbers in the range [0..1].
	* mln/value/float01.hh: New.
	* mln/value/float01_.hh: New.
	* mln/value/float01_16.hh: New.
	* mln/value/float01_8.hh: New.
	* tests/value_float01.cc: New.
---
 mln/value/float01.hh    |  244 ++++++++++++++++++++++++++++++++++++++++++++++++
 mln/value/float01_.hh   |  218 ++++++++++++++++++++++++++++++++++++++++++
 mln/value/float01_16.hh |   55 ++++++++++
 mln/value/float01_8.hh  |   55 ++++++++++
 tests/value_float01.cc  |   77 +++++++++++++++
 5 files changed, 649 insertions(+)
Index: trunk/milena/tests/value_float01.cc
===================================================================
--- trunk/milena/tests/value_float01.cc	(revision 0)
+++ trunk/milena/tests/value_float01.cc	(revision 1218)
@@ -0,0 +1,77 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+#include <iostream>
+#include <mln/value/float01_8.hh>
+#include <mln/value/float01_16.hh>
+
+
+
+float fi(int x) { return 0.5; }
+int ii(int x) { return 1; }
+
+float fd(double x) { return 0.5; }
+int id(double x) { return 1; }
+
+int main()
+{
+  using namespace mln::value;
+
+  float01_8  a(0.5);
+  float01_16 b(0.5);
+
+  assert(approx_equal(b,a));
+
+  std::cout << b << std::endl;
+  b = b + 0.2;
+  std::cout << b << std::endl;
+  b = b - 0.2;
+  std::cout << b << std::endl;
+  b = b * 1.5;
+  std::cout << b << std::endl;
+  b = b / 4.6;
+  std::cout << b << std::endl;
+
+  b = b / 3;
+  std::cout << b << std::endl;
+  b = b * 1;
+  std::cout << b << std::endl;
+
+  a = fi(a);
+  a = ii(a);
+  a = fd(a);
+  a = id(a);
+
+  b = a;
+  a = b;
+  b = 0.34;
+  std::cout << b << std::endl;
+  b = 0;
+  std::cout << b << std::endl;
+  b = 1;
+  std::cout << b << std::endl;
+}
Index: trunk/milena/mln/value/float01_8.hh
===================================================================
--- trunk/milena/mln/value/float01_8.hh	(revision 0)
+++ trunk/milena/mln/value/float01_8.hh	(revision 1218)
@@ -0,0 +1,55 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_VALUE_FLOAT01_8_HH
+# define MLN_VALUE_FLOAT01_8_HH
+
+/*! \file mln/value/float01_8.hh
+ *
+ * \brief Define the alias value::float01_8.
+ */
+
+# include <mln/value/float01_.hh>
+
+
+namespace mln
+{
+
+  namespace value
+  {
+
+
+    /// Alias for 8 bit float01.
+    typedef float01_<8> float01_8;
+
+
+  } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_FLOAT01_8_HH
Index: trunk/milena/mln/value/float01_.hh
===================================================================
--- trunk/milena/mln/value/float01_.hh	(revision 0)
+++ trunk/milena/mln/value/float01_.hh	(revision 1218)
@@ -0,0 +1,218 @@
+// Copyright (C) 2006, 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_VALUE_FLOAT01__HH
+# define MLN_CORE_VALUE_FLOAT01__HH
+
+# include <iostream>
+# include <mln/core/contract.hh>
+# include <mln/metal/math.hh>
+# include <mln/metal/bexpr.hh>
+# include <mln/value/internal/value_like.hh>
+# include <mln/value/internal/encoding.hh>
+# include <mln/value/float01.hh>
+# include <mln/value/props.hh>
+
+namespace mln
+{
+
+  namespace value
+  {
+
+    /// Fwd decl.
+    class float01;
+
+
+    /// General float01-level class on n bits.
+    template <unsigned n>
+    class float01_
+      : public internal::value_like_< double,
+				      float01_<n> >
+    {
+    public:
+
+      /// Encoding associated type.
+      typedef typename internal::encoding_unsigned_<n>::ret enc;
+
+      /// Ctor.
+      float01_();
+
+      /// Ctor.
+      float01_(const double val);
+
+      /// Access to std type.
+      double value() const;
+
+      void set_ind(unsigned long val);
+
+      enc value_ind() const;
+
+      /// Op encoding_t.
+      operator double() const;
+
+      /// Op float01_.
+      operator float01_() const;
+
+      /// Op<.
+      bool operator<(const float01_<n>& rhs) const;
+
+      float01_<n>& operator=(const double val);
+      /// Op==.
+      // bool operator==(const float01_<n>& rhs) const;
+
+    protected:
+      enc val_;
+    };
+
+
+    template <unsigned n>
+    struct props< float01_<n> >
+    {
+      static const std::size_t card_ = metal::pow<2, n>::value;
+      static const float01_<n> min() { return 0; }
+      static const float01_<n> max() { return 1; }
+      static const unsigned nbits = n;
+      typedef trait::kind::data kind;
+      typedef float sum;
+      typedef float interop;
+    };
+
+
+    /// Op<<.
+    template <unsigned n>
+    std::ostream& operator<<(std::ostream& ostr, const float01_<n>& g);
+
+
+    template <unsigned n, unsigned m>
+    bool approx_equal(const float01_<n>& lhs, const float01_<m>& rhs);
+
+    template <unsigned n>
+    bool operator==(const float01_<n>& lhs, const float01_<n>& rhs);
+
+    template <unsigned n>
+    bool approx_equal(const float01_<n>& lhs, const double f);
+
+# ifndef MLN_INCLUDE_ONLY
+
+    // Float01_<n>.
+
+    template <unsigned n>
+    float01_<n>::float01_()
+      : val_(0)
+    {
+    }
+
+    template <unsigned n>
+    float01_<n>::float01_(const double val)
+      : val_( int(val * (mln_card_(float01_<n>) - 1)) )
+    {
+      mln_precondition(val >= 0);
+      mln_precondition(val <= 1);
+    }
+
+    template <unsigned n>
+    double
+    float01_<n>::value() const
+    {
+      return (double(val_) / (mln_card_(float01_<n>) - 1));
+    }
+
+    template <unsigned n>
+    void
+    float01_<n>::set_ind(unsigned long val)
+    {
+      val_ = val;
+    }
+
+    template <unsigned n>
+    typename float01_<n>::enc
+    float01_<n>::value_ind() const
+    {
+      return (val_);
+    }
+
+    template <unsigned n>
+    float01_<n>&
+    float01_<n>::operator=(const double val)
+    {
+      mln_precondition(val >= 0);
+      mln_precondition(val <= 1);
+      this->val_ = long(val * (mln_card_(float01_<n>) - 1));
+      return *this;
+    }
+
+    template <unsigned n>
+    float01_<n>::operator float01_() const
+    {
+      float01 tmp(n, val_);
+      return tmp;
+    }
+
+    template <unsigned n>
+    float01_<n>::operator double() const
+    {
+      return double(val_) / (mln_card_(float01_<n>) - 1);
+    }
+
+    template <unsigned n>
+    bool float01_<n>::operator<(const float01_<n>& rhs) const
+    {
+      return val_ < rhs.val_;
+    }
+
+    template <unsigned n>
+    std::ostream& operator<<(std::ostream& ostr, const float01_<n>& g)
+    {
+      return ostr << g.value();
+    }
+
+    template <unsigned n>
+    bool operator==(const float01_<n>& lhs, const float01_<n>& rhs)
+    {
+      return lhs.value_ind() == rhs.value_ind();
+    }
+
+    template <unsigned n, unsigned m>
+    bool approx_equal(const float01_<n>& lhs, const float01_<m>& rhs)
+    {
+      return float01(lhs) == float01(rhs);
+    }
+
+    template <unsigned n>
+    bool approx_equal(const float01_<n>& lhs, const double f)
+    {
+      return float01(lhs) == float01_<n>(f);
+    }
+
+# endif
+
+
+  } // end of namespace mln::value
+
+} // end of namespace mln
+
+#endif // ! MLN_CORE_VALUE_FLOAT01__HH
Index: trunk/milena/mln/value/float01.hh
===================================================================
--- trunk/milena/mln/value/float01.hh	(revision 0)
+++ trunk/milena/mln/value/float01.hh	(revision 1218)
@@ -0,0 +1,244 @@
+// Copyright (C) 2006, 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_VALUE_FLOAT01_HH
+# define MLN_VALUE_FLOAT01_HH
+
+# include <iostream>
+
+# include <mln/core/concept/value.hh>
+# include <mln/value/float01_.hh>
+
+
+
+namespace mln
+{
+
+  // Fwd decls.
+  namespace value
+  {
+    template <unsigned N> class float01_;
+    class float01;
+
+    /// General float01_ class where n bits is not know at compile-time.
+    /// This class is used for exchange between float01_ types purpose.
+
+    class float01 : public Value<float01>
+    {
+    public:
+
+      /// Encoding associated type.
+      typedef double enc;
+
+      /// Equivalent associated type.
+      typedef double equiv;
+
+      /// Ctor.
+      float01();
+
+      /// Ctor.
+      template <unsigned N>
+      float01(const float01_<N>& val);
+
+      /// Ctor.
+      float01(unsigned nbits, double val);
+
+      /// Access to std type.
+      double value() const;
+      unsigned long value_ind() const;
+
+      unsigned nbits() const;
+
+      void set_nbits(unsigned nbits);
+
+      float01 to_nbits(unsigned nbits) const;
+
+      template <unsigned N>
+      operator float01_<N>() const;
+
+    protected:
+      unsigned nbits_;
+      unsigned long val_;
+    };
+
+    std::ostream& operator<<(std::ostream& ostr, const float01& g);
+
+    bool operator==(const float01& lhs, const float01& rhs);
+    bool operator<(const float01& lhs, const float01& rhs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace internal
+    {
+
+      unsigned long two_pow_(unsigned n)
+      {
+	if (n == 0)
+	  return 1;
+	else
+	  return 2 * two_pow_(n - 1);
+      }
+
+      unsigned long two_pow_n_minus_1(unsigned n)
+      {
+	  return two_pow_(n) - 1;
+      }
+
+      template <unsigned n_dest>
+      unsigned long convert(unsigned n_src, unsigned long val)
+      {
+	if (n_dest == n_src)
+	  return val;
+	else
+	  if (n_dest > n_src)
+	    return val * two_pow_n_minus_1(n_dest) / two_pow_n_minus_1(n_src);
+	  else
+	    return val / two_pow_(n_src - n_dest);
+      }
+
+    } // end of mln::value::internal
+
+    // Float01.
+
+    float01::float01()
+      : nbits_(0)
+    {
+    }
+
+    template <unsigned n>
+    float01::float01(const float01_<n>& g)
+      : nbits_(n),
+	val_(g.value_ind())
+    {
+    }
+
+    float01::float01(unsigned nbits, double val)
+      : nbits_(nbits),
+	val_(unsigned(val * internal::two_pow_n_minus_1(nbits)))
+    {
+    }
+
+    double float01::value() const
+    {
+      mln_invariant(nbits_ != 0);
+      return val_ / internal::two_pow_n_minus_1(nbits_);
+    }
+
+    unsigned long float01::value_ind() const
+    {
+      mln_invariant(nbits_ != 0);
+      return val_;
+    }
+
+    unsigned float01::nbits() const
+    {
+      return nbits_;
+    }
+
+
+
+    void float01::set_nbits(unsigned nbits)
+    {
+      mln_precondition(nbits != 0);
+      mln_invariant(nbits_ != 0);
+      if (nbits == nbits_)
+	return;
+      if (nbits > nbits_)
+	{
+	  val_ *= internal::two_pow_n_minus_1(nbits);
+	  val_ /= internal::two_pow_n_minus_1(nbits_);
+	}
+      else // nbits < nbits_
+	{
+	  val_ /= internal::two_pow_(nbits_ - nbits);
+	}
+      nbits_ = nbits;
+    }
+
+
+    float01 float01::to_nbits(unsigned nbits) const
+    {
+      mln_precondition(nbits != 0);
+      mln_invariant(nbits_ != 0);
+      float01 tmp(*this);
+      tmp.set_nbits(nbits);
+      return tmp;
+    }
+
+
+    template <unsigned n>
+    float01::operator float01_<n>() const
+    {
+      mln_precondition(nbits_ != 0);
+      float01_<n> tmp;
+      tmp.set_ind(internal::convert<n>(nbits_, val_));
+      mln_assertion(tmp.value() < internal::two_pow_(n));
+      return tmp;
+    }
+
+    // operators
+
+    std::ostream& operator<<(std::ostream& ostr, const float01& g)
+    {
+      return ostr << g.value() << '/' << g.nbits() << "nbits";
+    }
+
+    bool operator==(const float01& lhs, const float01& rhs)
+    {
+      mln_precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+
+      if (rhs.nbits() == lhs.nbits())
+	return lhs.value_ind() == rhs.value_ind();
+
+      if (lhs.nbits() < rhs.nbits())
+	return lhs.value_ind() == rhs.to_nbits(lhs.nbits()).value_ind();
+      else
+      {
+	return lhs.to_nbits(rhs.nbits()).value_ind() == rhs.value_ind();
+      }
+    }
+
+    bool operator<(const float01& lhs, const float01& rhs)
+    {
+      mln_precondition(lhs.nbits() != 0 and rhs.nbits() != 0);
+      if (rhs.nbits() == lhs.nbits())
+	return lhs.value() < rhs.value();
+      if (lhs.nbits() > rhs.nbits())
+	return lhs.value() < rhs.to_nbits(lhs.nbits()).value();
+      else
+	return lhs.to_nbits(rhs.nbits()).value() < rhs.value();
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_FLOAT01_HH
Index: trunk/milena/mln/value/float01_16.hh
===================================================================
--- trunk/milena/mln/value/float01_16.hh	(revision 0)
+++ trunk/milena/mln/value/float01_16.hh	(revision 1218)
@@ -0,0 +1,55 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_VALUE_FLOAT01_16_HH
+# define MLN_VALUE_FLOAT01_16_HH
+
+/*! \file mln/value/float01_16.hh
+ *
+ * \brief Define the alias value::float01_16.
+ */
+
+# include <mln/value/float01_.hh>
+
+
+namespace mln
+{
+
+  namespace value
+  {
+
+
+    /// Alias for 16 bit float01.
+    typedef float01_<16> float01_16;
+
+
+  } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_FLOAT01_16_HH
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-02  Guillaume Duhamel  <guillaume.duhamel(a)lrde.epita.fr>
	Add empty in queue_p.
	Update.
	* queue_p.hh: Add empty.
---
 queue_p.hh |   26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)
Index: trunk/milena/mln/core/queue_p.hh
===================================================================
--- trunk/milena/mln/core/queue_p.hh	(revision 1216)
+++ trunk/milena/mln/core/queue_p.hh	(revision 1217)
@@ -79,12 +79,18 @@
     /// Test is \p p belongs to this point set.
     bool has(const P& p) const;
 
+    /// Test if queue is empty or not.
+    bool empty() const;
+
     /// Give the number of points.
     std::size_t npoints() const;
 
     /// Give the exact bounding box.
     const box_<P>& bbox() const;
 
+    /// Push force a point \p p in the queue.
+    queue_p<P>& push_force(const P& p);
+
     /// Push a point \p p in the queue.
     queue_p<P>& push(const P& p);
 
@@ -162,6 +168,13 @@
   }
 
   template <typename P>
+  bool
+  queue_p<P>::empty() const
+  {
+    return (q_.empty());
+  }
+
+  template <typename P>
   std::size_t
   queue_p<P>::npoints() const
   {
@@ -180,10 +193,8 @@
 
   template <typename P>
   queue_p<P>&
-  queue_p<P>::push(const P& p)
+  queue_p<P>::push_force(const P& p)
   {
-    mln_precondition(! has(p));
-    // FIXME: Our choice is "error if multiple insertions"
     q_.push_back(p);
     if (! vect_needs_update_)
       {
@@ -194,6 +205,15 @@
   }
 
   template <typename P>
+  queue_p<P>&
+  queue_p<P>::push(const P& p)
+  {
+    mln_precondition(! has(p));
+    // FIXME: Our choice is "error if multiple insertions"
+    return this->push_force(p);
+  }
+
+  template <typename P>
   void
   queue_p<P>::pop()
   {
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-02  Simon Nivault  <simon.nivault(a)lrde.epita.fr>
	Fix for compile.
	* mln/metal/vec.hh: Fix definition of vprod to reflect declaration..
---
 vec.hh |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Index: trunk/milena/mln/metal/vec.hh
===================================================================
--- trunk/milena/mln/metal/vec.hh	(revision 1215)
+++ trunk/milena/mln/metal/vec.hh	(revision 1216)
@@ -533,7 +533,7 @@
     // vprod
 
     template <typename T, typename U>
-    vec<3, T> // typename binary_arith_trait<T, U>::ret>
+    vec<3, mln_trait_op_times(T,U)> // typename binary_arith_trait<T, U>::ret>
     vprod(const vec<3, T>& lhs, const vec<3, U>& rhs)
     {
       vec<3, T> tmp; // FIXME typename binary_arith_trait<T, U>::ret> tmp;
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Improve the traits system.
	Improve the trait system.
	* mln/core/category.hh: New.
	* mln/core/concept/image.hh,
	* mln/core/concept/function.hh,
	* mln/core/concept/meta_accumulator.hh,
	* mln/core/concept/value_set.hh,
	* mln/core/concept/weighted_window.hh,
	* mln/core/concept/browsing.hh,
	* mln/core/concept/dpoint.hh,
	* mln/core/concept/point_set.hh,
	* mln/core/concept/object.hh,
	* mln/core/concept/neighborhood.hh,
	* mln/core/concept/window.hh,
	* mln/core/concept/value.hh,
	* mln/core/concept/point_site.hh,
	* mln/core/concept/accumulator.hh (category): New.
	* mln/trait/solve.hh: New.
	* mln/core/trait/op_plus.hh: Rename as...
	* mln/trait/op_plus.hh: ...this.
	Update.
	* mln/core/trait/promote.hh: Rename as...
	* mln/trait/promote.hh: ...this.
	Update.
	* mln/core/trait/all.hh: Update.
	* mln/trait/all.hh: New.
	* mln/trait/op_minus.hh: New.
	* mln/trait/op_uminus.hh: New.
	* mln/trait/op_times.hh: New.
	* tests/trait_op_plus.cc: New.
	* mln/metal/binary_arith_trait.hh: Remove; obsolete.
	* mln/value/props.hh: Update.
	(vec, mat): Move to the file they belong to.
	Then use it.
	* mln/core/ops.hh,
	* mln/metal/mat.hh,
	* mln/metal/vec.hh,
	* mln/value/int_s.hh,
	* mln/value/int_u.hh: Use traits.
	Update.
	* mln/arith/plus.hh: Add code to be activated.
	Disambiguation.
	* mln/trait/images.hh (fixme): Rename as...
	(fixme_): ...this to avoid conflict with mln::internal::fixme.
	* mln/pw/image.hh: Update.
	* mln/border/mirror.hh,
	* mln/border/resize.hh,
	* mln/core/dpoints_piter.hh,
	* mln/core/image1d_b.hh,
	* mln/core/image2d_b.hh,
	* mln/core/image3d_b.hh,
	* mln/core/pset_if.hh,
	* mln/core/pset_if_piter.hh: Fully name fixme.
	* mln/border/fill.hh (fixme): Remove include.
	Misc.
	* mln/border/duplicate.hh: Fix typo.
	* mln/metal/mat.hh (operator*=): Fix sig.
	Fix params order.
	* mln/value/rgb.hh (min, max): Remove, cause meaningless.
	(operator-, operator+): Likewise.
	(card_): Set to 0.
 mln/arith/plus.hh                    |   27 +++++
 mln/border/fill.hh                   |    2 
 mln/border/mirror.hh                 |    2 
 mln/border/resize.hh                 |    2 
 mln/core/category.hh                 |   67 ++++++++++++
 mln/core/concept/accumulator.hh      |    2 
 mln/core/concept/browsing.hh         |    2 
 mln/core/concept/dpoint.hh           |    2 
 mln/core/concept/function.hh         |    2 
 mln/core/concept/image.hh            |    2 
 mln/core/concept/meta_accumulator.hh |    1 
 mln/core/concept/neighborhood.hh     |    2 
 mln/core/concept/object.hh           |    1 
 mln/core/concept/point_set.hh        |    2 
 mln/core/concept/point_site.hh       |    7 +
 mln/core/concept/value.hh            |    2 
 mln/core/concept/value_set.hh        |    2 
 mln/core/concept/weighted_window.hh  |    2 
 mln/core/concept/window.hh           |    2 
 mln/core/dpoints_piter.hh            |    2 
 mln/core/image1d_b.hh                |    5 
 mln/core/image2d_b.hh                |    5 
 mln/core/image3d_b.hh                |    5 
 mln/core/ops.hh                      |   18 +--
 mln/core/pset_if.hh                  |    2 
 mln/core/pset_if_piter.hh            |    3 
 mln/core/trait/all.hh                |    4 
 mln/metal/mat.hh                     |  184 +++++++++++++++++++++++------------
 mln/metal/vec.hh                     |  143 ++++++++++++++++++++-------
 mln/pw/image.hh                      |    4 
 mln/trait/all.hh                     |   55 ++++++++++
 mln/trait/images.hh                  |    8 -
 mln/trait/op_minus.hh                |   67 ++++++++++++
 mln/trait/op_plus.hh                 |   94 ++---------------
 mln/trait/op_times.hh                |   67 ++++++++++++
 mln/trait/op_uminus.hh               |   65 ++++++++++++
 mln/trait/promote.hh                 |   55 ++++------
 mln/trait/solve.hh                   |  176 +++++++++++++++++++++++++++++++++
 mln/value/int_s.hh                   |   42 +++++++
 mln/value/int_u.hh                   |   39 +++++++
 mln/value/props.hh                   |   32 ------
 mln/value/rgb.hh                     |   91 +++++++++--------
 tests/trait_op_plus.cc               |   91 +++++++++++++++++
 43 files changed, 1085 insertions(+), 303 deletions(-)
Index: tests/trait_op_plus.cc
--- tests/trait_op_plus.cc	(revision 0)
+++ tests/trait_op_plus.cc	(revision 0)
@@ -0,0 +1,91 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+/*! \file tests/trait_op_plus.cc
+ *
+ * \brief Tests on mln::trait::op_plus.
+ */
+
+#include <mln/core/concept/image.hh>
+#include <mln/trait/op_plus.hh>
+
+
+namespace mln
+{
+
+
+  template <typename T>
+  struct my_image2d : Image< my_image2d<T> >
+  {
+  };
+
+
+  namespace trait
+  {
+
+    // int + float -> float
+
+    template <>
+    struct set_precise_binary_< op_plus, int, float >
+    {
+      typedef float ret;
+    };
+
+
+    // Image I + Image J -> bool (demo type!)
+
+    template <typename I, typename J>
+    struct set_binary_< op_plus, Image, I,  Image, J >
+    {
+      typedef bool ret;
+    };
+
+    // precise definition: my_image2d<T> + my_image2d<U> -> my_image2d<V> ('&' is to avoid compiling an empty class)
+
+    template <typename T, typename U>
+    struct set_precise_binary_< op_plus, my_image2d<T>, my_image2d<U> >
+    {
+      typedef mln_trait_op_plus(T, U) V; 
+      typedef my_image2d<V>& ret;
+    };
+
+  }
+  
+}
+
+int main()
+{
+  using namespace mln;
+  {
+    mln_trait_op_plus_(int, float) tmp;
+    tmp = 5.1f;
+  }
+  {
+    my_image2d<float>* ptr;
+    mln_trait_op_plus_(my_image2d<int>, my_image2d<float>) tmp = *ptr;
+  }
+}
Index: mln/trait/op_plus.hh
--- mln/trait/op_plus.hh	(revision 1204)
+++ mln/trait/op_plus.hh	(working copy)
@@ -28,103 +28,34 @@
 #ifndef MLN_TRAIT_OP_PLUS_HH
 # define MLN_TRAIT_OP_PLUS_HH
 
+# include <mln/trait/promote.hh>
 
-# define mln_op_plus(T, U) typename mln::trait::op_plus< T , U >::ret
 
+# define mln_trait_op_plus(L, R)  typename mln::trait::op_plus< L , R >::ret
+# define mln_trait_op_plus_(L, R)          mln::trait::op_plus< L , R >::ret
 
 
-namespace mln
-{
 
-  namespace metal
+namespace mln
   {
 
-    template <unsigned n, typename T>
-    class vec;
-
-    template <unsigned n, unsigned m, typename T>
-    class mat;
-
-  } // end of namespace mln::metal
-
   namespace trait
   {
 
-    template <typename T, typename U>
-    struct op_plus;
-
 
-    template <typename T>
-    struct op_plus<T, T>
+    template <typename L, typename R>
+    struct op_plus : public solve_binary<op_plus, L, R>
     {
-      typedef T ret;
     };
 
-    template <>
-    struct op_plus<int, float>
-    {
-      typedef float ret;
-    };
-    template <>
-    struct op_plus<float, int>
-    {
-      typedef float ret;
-    };
 
-    template <>
-    struct op_plus<int, double>
+    /// Default definition of op_plus is given by the promote trait.
+    template <template <class> class Category_L, typename L,
+	      template <class> class Category_R, typename R>
+    struct set_binary_< op_plus, Category_L, L, Category_R, R >
+      :
+      public promote< L, R >
     {
-      typedef double ret;
-    };
-    template <>
-    struct op_plus<double, int>
-    {
-      typedef double ret;
-    };
-
-    template <>
-    struct op_plus<double, float>
-    {
-      typedef double ret;
-    };
-    template <>
-    struct op_plus<float, double>
-    {
-      typedef double ret;
-    };
-
-    template <unsigned n, typename T, typename U>
-    struct op_plus<metal::vec<n, T>, U>
-    {
-      typedef metal::vec<n, mln_op_plus(T, U)> ret;
-    };
-    template <typename U, unsigned n, typename T>
-    struct op_plus<U, metal::vec<n, T> >
-    {
-      typedef metal::vec<n, mln_op_plus(T, U)> ret;
-    };
-
-    template <unsigned n, typename T, typename U>
-    struct op_plus<metal::vec<n, T>, metal::vec<n, U> >
-    {
-      typedef metal::vec<n, mln_op_plus(T, U)> ret;
-    };
-
-    template <unsigned n, unsigned m, typename T, typename U>
-    struct op_plus<metal::mat<n, m, T>, U>
-    {
-      typedef metal::mat<n, m, mln_op_plus(T, U)> ret;
-    };
-    template <typename U, unsigned n, unsigned m, typename T>
-    struct op_plus<U, metal::mat<n, m, T> >
-    {
-      typedef metal::mat<n, m, mln_op_plus(T, U)> ret;
-    };
-
-    template <unsigned n, unsigned m, typename T, typename U>
-    struct op_plus<metal::mat<n, m, T>, metal::mat<n, m, U> >
-    {
-      typedef metal::mat<n, m, mln_op_plus(T, U)> ret;
     };
 
 
@@ -132,4 +63,5 @@
 
 } // end of namespace mln
 
+
 #endif // ! MLN_TRAIT_OP_PLUS_HH
Index: mln/trait/images.hh
--- mln/trait/images.hh	(revision 1214)
+++ mln/trait/images.hh	(working copy)
@@ -192,8 +192,8 @@
       struct two_d    : any { std::string str() const { return "space::two_d"; } };
       struct three_d  : any { std::string str() const { return "space::three_d"; } };
 
-      struct fixme // So FIXME!
-	: any { std::string str() const { return "space::fixme"; } };
+      struct fixme_ // So FIXME!
+	: any { std::string str() const { return "space::fixme_"; } };
     };
 
     struct size
@@ -211,8 +211,8 @@
       struct aligned
 	: regular { std::string str() const { return "support::aligned"; } };
 
-      struct fixme // So FIXME!
-	: any { std::string str() const { return "support::fixme"; } };
+      struct fixme_ // So FIXME!
+	: any { std::string str() const { return "support::fixme_"; } };
     };
 
     struct border
Index: mln/trait/promote.hh
--- mln/trait/promote.hh	(revision 1204)
+++ mln/trait/promote.hh	(working copy)
@@ -28,79 +28,76 @@
 #ifndef MLN_TRAIT_PROMOTE_HH
 # define MLN_TRAIT_PROMOTE_HH
 
+# include <mln/trait/solve.hh>
 
-# define mln_promote(T, U) typename mln::trait::promote< T , U >::ret
+
+# define mln_trait_promote(T, U) typename mln::trait::promote< T , U >::ret
 
 
 
 namespace mln
 {
 
-  namespace metal
+  namespace trait
   {
 
-    template <unsigned n, typename T>
-    class vec;
-
-    template <unsigned n, unsigned m, typename T>
-    class mat;
+    /// Declaration of the "promote" trait.
+    template <typename T, typename U>
+    struct promote : public solve_binary<promote, T, U>
+    {
+    };
 
-  } // end of namespace mln::metal
 
-  namespace trait
+    /// Default case when the same type is involved twice: return this
+    /// type.
+    template <template <class> class Category, typename T>
+    struct set_binary_< promote, Category, T, Category, T >
   {
+      typedef T ret;
+    };
 
-    template <typename T, typename U>
-    struct promote;
 
+    // Definitions for some built-ins.
 
     template <>
-    struct promote<int, float>
+    struct set_precise_binary_< promote, int, float >
     {
       typedef float ret;
     };
+
     template <>
-    struct promote<float, int>
+    struct set_precise_binary_< promote, float, int >
     {
       typedef float ret;
     };
 
     template <>
-    struct promote<int, double>
+    struct set_precise_binary_< promote, int, double >
     {
       typedef double ret;
     };
+
     template <>
-    struct promote<double, int>
+    struct set_precise_binary_< promote, double, int >
     {
       typedef double ret;
     };
 
     template <>
-    struct promote<double, float>
+    struct set_precise_binary_< promote, float, double >
     {
       typedef double ret;
     };
+
     template <>
-    struct promote<float, double>
+    struct set_precise_binary_< promote, double, float >
     {
       typedef double ret;
     };
 
-    template <unsigned n, typename T, typename U>
-    struct promote<metal::vec<n, T>, metal::vec<n, U> >
-    {
-      typedef metal::vec<n, mln_promote(T, U)> ret;
-    };
-
-    template <unsigned n, unsigned m, typename T, typename U>
-    struct promote<metal::mat<n, m, T>, metal::mat<n, m, U> >
-    {
-      typedef metal::mat<n, m, mln_promote(T, U)> ret;
-    };
-
   } // end of namespace mln::trait
 
 } // end of namespace mln
 
+
 #endif // ! MLN_TRAIT_PROMOTE_HH
Index: mln/trait/solve.hh
--- mln/trait/solve.hh	(revision 0)
+++ mln/trait/solve.hh	(revision 0)
@@ -0,0 +1,176 @@
+// Copyright (C) 2006  EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_SOLVE_HH
+# define MLN_TRAIT_SOLVE_HH
+
+# include <mln/core/category.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+
+
+
+namespace mln
+{
+
+  namespace trait
+  {
+
+
+    struct undefined;
+
+
+    // Unary case.
+
+
+    template < template <class> class Name,
+	       typename T >
+    struct set_precise_unary_
+    {
+      typedef undefined ret;
+    };
+
+
+    template < template <class> class Name,
+	       template <class> class Category_T, typename T >
+    struct set_unary_
+    {
+      typedef undefined ret;
+    };
+    
+
+    namespace internal
+    {
+
+      template < template <class> class Name,
+		 template <class> class Category_T, typename T >
+      struct helper_choose_unary_
+      {
+	typedef typename set_unary_<Name, Category_T,T>::ret category_ret;
+	typedef typename set_precise_unary_<Name, T>::ret precise_ret;
+	typedef mlc_if( mlc_equal(precise_ret,
+				  undefined),
+			category_ret,
+			precise_ret ) ret;
+      };
+
+      template < template <class> class Name,
+		 typename Category_T_void, typename T >
+      struct helper_solve_unary_;
+
+      template < template <class> class Name,
+		 template <class> class Category_T, typename T >
+      struct helper_solve_unary_< Name,
+				  Category_T<void>, T > : helper_choose_unary_< Name,
+										Category_T, T >
+      {
+      };
+
+    } // end of namespace mln::trait::internal
+
+
+    template < template <class> class Name,
+	       typename T >
+    struct solve_unary : internal::helper_solve_unary_< Name,
+							typename mln::category<T>::ret, T >
+    {
+    };
+
+
+
+    // Binary case.
+    
+
+    template < template <class, class> class Name,
+	       template <class> class Category_L, typename L,
+	       template <class> class Category_R, typename R >
+    struct set_binary_
+    {
+      typedef undefined ret;
+    };
+
+
+    template < template <class, class> class Name,
+	       typename L,
+	       typename R >
+    struct set_precise_binary_
+    {
+      typedef undefined ret;
+    };
+
+
+    namespace internal
+    {
+
+      template < template <class, class> class Name,
+		 template <class> class Category_L, typename L,
+		 template <class> class Category_R, typename R >
+      struct helper_choose_binary_
+      {
+	typedef typename set_binary_<Name, Category_L,L, Category_R,R>::ret category_ret;
+	typedef typename set_precise_binary_<Name, L, R>::ret precise_ret;
+	typedef mlc_if( mlc_equal(precise_ret,
+				  undefined),
+			category_ret,
+			precise_ret ) ret;
+      };
+
+      template < template <class, class> class Name,
+		 typename Category_L_void, typename L,
+		 typename Category_R_void, typename R >
+      struct helper_solve_binary_;
+
+      template < template <class, class> class Name,
+		 template <class> class Category_L, typename L,
+		 template <class> class Category_R, typename R >
+      struct helper_solve_binary_< Name,
+				   Category_L<void>, L,
+				   Category_R<void>, R > : helper_choose_binary_< Name,
+										  Category_L, L,
+										  Category_R, R >
+      {
+      };
+
+    } // end of namespace mln::trait::internal
+
+
+    template < template <class, class> class Name,
+	       typename L,
+	       typename R >
+    struct solve_binary : internal::helper_solve_binary_< Name,
+							  typename mln::category<L>::ret, L,
+							  typename mln::category<R>::ret, R >
+    {
+    };
+
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_SOLVE_HH
Index: mln/trait/all.hh
--- mln/trait/all.hh	(revision 0)
+++ mln/trait/all.hh	(revision 0)
@@ -0,0 +1,55 @@
+// Copyright (C) 2006  EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_ALL_HH
+# define MLN_TRAIT_ALL_HH
+
+
+namespace mln
+{
+
+  // FIXME: Doc!
+  namespace trait
+  {}
+
+} // end of namespace mln
+
+
+# include <mln/trait/solve.hh>
+
+// promote
+# include <mln/trait/promote.hh>
+
+// arith
+# include <mln/trait/op_plus.hh>
+# include <mln/trait/op_times.hh>
+# include <mln/trait/op_minus.hh>
+# include <mln/trait/op_uminus.hh>
+
+
+
+#endif // ! MLN_TRAIT_ALL_HH
Index: mln/trait/op_minus.hh
--- mln/trait/op_minus.hh	(revision 0)
+++ mln/trait/op_minus.hh	(revision 0)
@@ -0,0 +1,67 @@
+// Copyright (C) 2006  EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_OP_MINUS_HH
+# define MLN_TRAIT_OP_MINUS_HH
+
+# include <mln/trait/promote.hh>
+
+
+# define mln_trait_op_minus(L, R)  typename mln::trait::op_minus< L , R >::ret
+# define mln_trait_op_minus_(L, R)          mln::trait::op_minus< L , R >::ret
+
+
+
+namespace mln
+{
+
+  namespace trait
+  {
+
+
+    template <typename L, typename R>
+    struct op_minus : public solve_binary<op_minus, L, R>
+    {
+    };
+
+
+    /// Default definition of op_minus is given by the promote trait.
+    template <template <class> class Category_L, typename L,
+	      template <class> class Category_R, typename R>
+    struct set_binary_< op_minus, Category_L, L, Category_R, R >
+      :
+      public promote< L, R >
+    {
+    };
+
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_OP_MINUS_HH
Index: mln/trait/op_uminus.hh
--- mln/trait/op_uminus.hh	(revision 0)
+++ mln/trait/op_uminus.hh	(revision 0)
@@ -0,0 +1,65 @@
+// Copyright (C) 2006  EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_OP_UMINUS_HH
+# define MLN_TRAIT_OP_UMINUS_HH
+
+# include <mln/trait/solve.hh>
+
+
+# define mln_trait_op_uminus(T)  typename mln::trait::op_uminus< T >::ret
+# define mln_trait_op_uminus_(T)          mln::trait::op_uminus< T >::ret
+
+
+
+namespace mln
+{
+
+  namespace trait
+  {
+
+
+    template <typename T>
+    struct op_uminus : public solve_unary<op_uminus, T>
+    {
+    };
+
+
+    /// Default definition of op_uminus is the input type itself.
+    template <template <class> class Category, typename T>
+    struct set_unary_< op_uminus, Category, T >
+    {
+      typedef T ret;
+    };
+
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_OP_UMINUS_HH
Index: mln/trait/op_times.hh
--- mln/trait/op_times.hh	(revision 0)
+++ mln/trait/op_times.hh	(revision 0)
@@ -0,0 +1,67 @@
+// Copyright (C) 2006  EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_OP_TIMES_HH
+# define MLN_TRAIT_OP_TIMES_HH
+
+# include <mln/trait/promote.hh>
+
+
+# define mln_trait_op_times(L, R)  typename mln::trait::op_times< L , R >::ret
+# define mln_trait_op_times_(L, R)          mln::trait::op_times< L , R >::ret
+
+
+
+namespace mln
+{
+
+  namespace trait
+  {
+
+
+    template <typename L, typename R>
+    struct op_times : public solve_binary<op_times, L, R>
+    {
+    };
+
+
+    /// Default definition of op_times is given by the promote trait.
+    template <template <class> class Category_L, typename L,
+	      template <class> class Category_R, typename R>
+    struct set_binary_< op_times, Category_L, L, Category_R, R >
+      :
+      public promote< L, R >
+    {
+    };
+
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_OP_TIMES_HH
Index: mln/core/dpoints_piter.hh
--- mln/core/dpoints_piter.hh	(revision 1214)
+++ mln/core/dpoints_piter.hh	(working copy)
@@ -100,7 +100,7 @@
 
   // FIXME:
   template <typename D>
-  class dpoints_bkd_piter : public internal::fixme
+  class dpoints_bkd_piter : public mln::internal::fixme
   {};
 
 
Index: mln/core/category.hh
--- mln/core/category.hh	(revision 0)
+++ mln/core/category.hh	(revision 0)
@@ -0,0 +1,67 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_CATEGORY_HH
+# define MLN_CORE_CATEGORY_HH
+
+/*! \file mln/core/category.hh
+ * \brief Definition of the category holder type.
+ */
+
+
+namespace mln
+{
+
+  // FIXME: Doc!
+
+
+  template <typename E>
+  struct Unknown;
+
+
+  template <typename T>
+  struct category
+  {
+    typedef typename T::category ret; // FIXME: if found or Unknown<void> => write a meta-program...
+  };
+
+
+  // The case of built-in types.
+
+  template <typename E>
+  struct Built_In;
+
+  template <> struct category< int >    { typedef Built_In<void> ret; };
+  template <> struct category< float >  { typedef Built_In<void> ret; };
+  template <> struct category< double > { typedef Built_In<void> ret; };
+  // FIXME: ...
+
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_CATEGORY_HH
Index: mln/core/image2d_b.hh
--- mln/core/image2d_b.hh	(revision 1214)
+++ mln/core/image2d_b.hh	(working copy)
@@ -33,6 +33,7 @@
  * \brief Definition of the basic mln::image2d_b class.
  */
 
+# include <mln/core/internal/fixme.hh>
 # include <mln/core/internal/image_primary.hh>
 # include <mln/core/box2d.hh>
 
@@ -533,7 +534,7 @@
     template <typename T, typename W>
     struct bkd_qixter< image2d_b<T>, W >
     {
-      typedef internal::fixme ret;
+      typedef mln::internal::fixme ret;
     };
 
     // nixter
@@ -553,7 +554,7 @@
     template <typename T, typename N>
     struct bkd_nixter< image2d_b<T>, N >
     {
-      typedef internal::fixme ret;
+      typedef mln::internal::fixme ret;
     };
 
   } // end of namespace mln::trait
Index: mln/core/trait/all.hh
--- mln/core/trait/all.hh	(revision 1214)
+++ mln/core/trait/all.hh	(working copy)
@@ -47,10 +47,10 @@
 # include <mln/core/trait/is_fast.hh>
 # include <mln/core/trait/pixter.hh>
 # include <mln/core/trait/op_mult.hh>
-# include <mln/core/trait/op_plus.hh>
+// FIXME # include <mln/core/trait/op_plus.hh>
 # include <mln/core/trait/op_minus.hh>
 # include <mln/core/trait/op_uminus.hh>
-# include <mln/core/trait/promote.hh>
+// FIXME # include <mln/core/trait/promote.hh>
 
 
 #endif // ! MLN_CORE_TRAIT_ALL_HH
Index: mln/core/ops.hh
--- mln/core/ops.hh	(revision 1214)
+++ mln/core/ops.hh	(working copy)
@@ -30,13 +30,13 @@
 
 /*! \file mln/core/ops.hh
  * \brief Definitions of some operators.
- *
- * \todo Traits are in mln/trait/ not in mln/metal/!
  */
 
 # include <mln/core/concept/object.hh>
 # include <mln/core/exact.hh>
-# include <mln/metal/binary_arith_trait.hh>
+
+# include <mln/trait/op_plus.hh>
+# include <mln/trait/op_times.hh>
 
 
 namespace mln
@@ -100,7 +100,7 @@
 
   // FIXME: Doc!
   template <typename O>
-  mlc_bin_arith(int, O)
+  mln_trait_op_plus(O, int)
   operator+(int lhs, const Object<O>& rhs)
   {
     return exact(rhs) + lhs;
@@ -108,7 +108,7 @@
 
   // FIXME: Doc!
   template <typename O>
-  mlc_bin_arith(float, O)
+  mln_trait_op_plus(O, float)
   operator+(float lhs, const Object<O>& rhs)
   {
     return exact(rhs) + lhs;
@@ -116,7 +116,7 @@
 
   // FIXME: Doc!
   template <typename O>
-  mlc_bin_arith(double, O)
+  mln_trait_op_plus(O, double)
   operator+(double lhs, const Object<O>& rhs)
   {
     return exact(rhs) + lhs;
@@ -126,7 +126,7 @@
 
   // FIXME: Doc!
   template <typename O>
-  mlc_bin_arith(int, O)
+  mln_trait_op_times(O, int)
   operator*(int lhs, const Object<O>& rhs)
   {
     return exact(rhs) * lhs;
@@ -134,7 +134,7 @@
 
   // FIXME: Doc!
   template <typename O>
-  mlc_bin_arith(float, O)
+  mln_trait_op_times(O, float)
   operator*(float lhs, const Object<O>& rhs)
   {
     return exact(rhs) * lhs;
@@ -142,7 +142,7 @@
 
   // FIXME: Doc!
   template <typename O>
-  mlc_bin_arith(double, O)
+  mln_trait_op_times(O, double)
   operator*(double lhs, const Object<O>& rhs)
   {
     return exact(rhs) * lhs;
Index: mln/core/pset_if.hh
--- mln/core/pset_if.hh	(revision 1214)
+++ mln/core/pset_if.hh	(working copy)
@@ -77,7 +77,7 @@
     typedef pset_if_fwd_piter_<S,F> fwd_piter;
 
     /// Backward Point_Iterator associated type.
-    typedef internal::fixme bkd_piter;
+    typedef mln::internal::fixme bkd_piter;
 
 
     /// Constructor with a point set \p pset and a predicate \p f.
Index: mln/core/pset_if_piter.hh
--- mln/core/pset_if_piter.hh	(revision 1214)
+++ mln/core/pset_if_piter.hh	(working copy)
@@ -77,7 +77,8 @@
   // FIXME:
   template <typename S, typename F>
   class pset_if_bkd_piter_
-    : public internal::fixme
+    :
+    public mln::internal::fixme
   {};
 
 
Index: mln/core/concept/image.hh
--- mln/core/concept/image.hh	(revision 1214)
+++ mln/core/concept/image.hh	(working copy)
@@ -57,6 +57,8 @@
   template <typename E>
   struct Image : public Object<E>
   {
+    typedef Image<void> category;
+
     /*
       // to be provided in concrete image classes:
 
Index: mln/core/concept/function.hh
--- mln/core/concept/function.hh	(revision 1214)
+++ mln/core/concept/function.hh	(working copy)
@@ -47,6 +47,8 @@
   template <typename E>
   struct Function : public Object<E>
   {
+    typedef Function<void> category;
+
     /*
       An operator() has to be provided.  Its signature depends
       on the particular function-object one considers.
Index: mln/core/concept/meta_accumulator.hh
--- mln/core/concept/meta_accumulator.hh	(revision 1214)
+++ mln/core/concept/meta_accumulator.hh	(working copy)
@@ -60,6 +60,7 @@
   template <typename E>
   struct Meta_Accumulator : public Object<E>
   {
+    typedef Meta_Accumulator<void> category;
   protected:
     Meta_Accumulator();
   };
Index: mln/core/concept/value_set.hh
--- mln/core/concept/value_set.hh	(revision 1214)
+++ mln/core/concept/value_set.hh	(working copy)
@@ -46,6 +46,8 @@
   template <typename E>
   struct Value_Set : public Object<E>
   {
+    typedef Value_Set<void> category;
+
     /*
       typedef value;
       typedef fwd_viter;
Index: mln/core/concept/weighted_window.hh
--- mln/core/concept/weighted_window.hh	(revision 1214)
+++ mln/core/concept/weighted_window.hh	(working copy)
@@ -49,6 +49,8 @@
   template <typename E>
   struct Weighted_Window : public Object<E>
   {
+    typedef Weighted_Window<void> category;
+
     /*
       typedef fwd_qiter;
       typedef bkd_piter;
Index: mln/core/concept/browsing.hh
--- mln/core/concept/browsing.hh	(revision 1214)
+++ mln/core/concept/browsing.hh	(working copy)
@@ -46,6 +46,8 @@
   template <typename E>
   struct Browsing : public Object<E>
   {
+    typedef Browsing<void> category;
+
     void init();
     void final();
 
Index: mln/core/concept/dpoint.hh
--- mln/core/concept/dpoint.hh	(revision 1214)
+++ mln/core/concept/dpoint.hh	(working copy)
@@ -53,6 +53,8 @@
   template <typename E>
   struct Dpoint : public Object<E>
   {
+    typedef Dpoint<void> category;
+
     /*
       typedef point;
       typedef coord;
Index: mln/core/concept/point_set.hh
--- mln/core/concept/point_set.hh	(revision 1214)
+++ mln/core/concept/point_set.hh	(working copy)
@@ -48,6 +48,8 @@
   template <typename E>
   struct Point_Set : public Object<E>
   {
+    typedef Point_Set<void> category;
+
     /*
       typedef mesh;
 
Index: mln/core/concept/object.hh
--- mln/core/concept/object.hh	(revision 1214)
+++ mln/core/concept/object.hh	(working copy)
@@ -67,6 +67,7 @@
   struct Object
   {
     typedef E exact_t;
+    typedef Object<void> category; // Default.
   protected:
     Object();
   };
Index: mln/core/concept/neighborhood.hh
--- mln/core/concept/neighborhood.hh	(revision 1214)
+++ mln/core/concept/neighborhood.hh	(working copy)
@@ -46,6 +46,8 @@
   template <typename E>
   struct Neighborhood : public Object<E>
   {
+    typedef Neighborhood<void> category;
+
     /*
       typedef niter;
       typedef fwd_niter;
Index: mln/core/concept/window.hh
--- mln/core/concept/window.hh	(revision 1214)
+++ mln/core/concept/window.hh	(working copy)
@@ -48,6 +48,8 @@
   template <typename E>
   struct Window : public Object<E>
   {
+    typedef Window<void> category;
+
     /*
       typedef point;
       typedef dpoint;
Index: mln/core/concept/value.hh
--- mln/core/concept/value.hh	(revision 1214)
+++ mln/core/concept/value.hh	(working copy)
@@ -46,6 +46,8 @@
   template <typename E>
   struct Value : public Object<E>
   {
+    typedef Value<void> category;
+
     /*
       typedef enc;   // encoding type
       typedef equiv; // equivalent type
Index: mln/core/concept/point_site.hh
--- mln/core/concept/point_site.hh	(revision 1214)
+++ mln/core/concept/point_site.hh	(working copy)
@@ -38,6 +38,11 @@
 namespace mln
 {
 
+  // Fwd decl (used in the "category" definition).
+  template <typename P> struct Point;
+
+
+
   /*! \brief Base class for implementation classes of the notion of
    *  "point site".
    *
@@ -64,6 +69,8 @@
   struct Point_Site : public Object<E>,
 		      public Generalized_Point<E>
   {
+    typedef Point<void> category; // FIXME: This is a hack!  Change the hierarchy...
+
     /*
     const point* pointer_() const
     {
Index: mln/core/concept/accumulator.hh
--- mln/core/concept/accumulator.hh	(revision 1214)
+++ mln/core/concept/accumulator.hh	(working copy)
@@ -52,6 +52,8 @@
   template <typename E>
   struct Accumulator : public Object<E>
   {
+    typedef Accumulator<void> category;
+
     /*
       typedef value;
       typedef result;
Index: mln/core/image1d_b.hh
--- mln/core/image1d_b.hh	(revision 1214)
+++ mln/core/image1d_b.hh	(working copy)
@@ -33,6 +33,7 @@
  * \brief Definition of the basic mln::image1d_b class.
  */
 
+# include <mln/core/internal/fixme.hh>
 # include <mln/core/internal/image_primary.hh>
 # include <mln/core/box1d.hh>
 
@@ -481,7 +482,7 @@
     template <typename T>
     struct bkd_pixter< image1d_b<T> >
     {
-      typedef internal::fixme ret;
+      typedef mln::internal::fixme ret;
     };
 
     // qixter
@@ -501,7 +502,7 @@
     template <typename T, typename W>
     struct bkd_qixter< image1d_b<T>, W >
     {
-      typedef internal::fixme ret;
+      typedef mln::internal::fixme ret;
     };
 
   } // end of namespace mln::trait
Index: mln/core/image3d_b.hh
--- mln/core/image3d_b.hh	(revision 1214)
+++ mln/core/image3d_b.hh	(working copy)
@@ -33,6 +33,7 @@
  * \brief Definition of the basic mln::image3d_b class.
  */
 
+# include <mln/core/internal/fixme.hh>
 # include <mln/core/internal/image_primary.hh>
 # include <mln/core/box3d.hh>
 
@@ -521,7 +522,7 @@
     template <typename T>
     struct bkd_pixter< image3d_b<T> >
     {
-      typedef internal::fixme ret;
+      typedef mln::internal::fixme ret;
     };
 
     // qixter
@@ -541,7 +542,7 @@
     template <typename T, typename W>
     struct bkd_qixter< image3d_b<T>, W >
     {
-      typedef internal::fixme ret;
+      typedef mln::internal::fixme ret;
     };
 
   } // end of namespace mln::trait
Index: mln/metal/mat.hh
--- mln/metal/mat.hh	(revision 1214)
+++ mln/metal/mat.hh	(working copy)
@@ -32,10 +32,14 @@
 
 # include <mln/core/concept/object.hh>
 # include <mln/core/contract.hh>
-# include <mln/metal/binary_arith_trait.hh>
+# include <mln/trait/all.hh>
+# include <mln/value/props.hh>
+
 
 // FIXME: Document.
 
+
+
 namespace mln
 {
 
@@ -81,25 +85,78 @@
   namespace trait
   {
     
-    template <typename L, typename R>
-    struct mult;
+    // promote
+
+    template <unsigned n, unsigned m, typename T, typename U>
+    struct set_precise_binary_<promote, metal::mat<n,m, T>, metal::mat<n,m, U> >
+    {
+      typedef metal::mat<n,m, mln_trait_promote(T, U)> ret;
+    };
+
+
+    // mat + mat
+
+    template <unsigned n, unsigned m, typename T,
+	      typename U>
+    struct set_precise_binary_<op_plus, metal::mat<n, m, T>, metal::mat<n, m, U> >
+    {
+      typedef metal::mat<n, m, mln_trait_op_plus(T, U)> ret;
+    };
+
+    // FIXME: + mat
+
+    // mat - mat
+
+    template <unsigned n, unsigned m, typename T,
+	      typename U>
+    struct set_precise_binary_<op_minus, metal::mat<n, m, T>, metal::mat<n, m, U> >
+    {
+      typedef metal::mat<n, m, mln_trait_op_minus(T, U)> ret;
+    };
+
+    // - mat
 
+    template <unsigned n, unsigned m, typename T>
+    struct set_precise_unary_<op_uminus, metal::mat<n, m, T> >
+    {
+      typedef metal::mat<n, m, mln_trait_op_uminus(T)> ret;
+    };
+
+    // mat * mat
 
     template <unsigned n, unsigned o, typename T,
 	      unsigned m, typename U>
-    struct mult< metal::mat<n,o,T>, metal::mat<o,m,U> >
+    struct set_precise_binary_<op_times, metal::mat<n,o,T>, metal::mat<o,m,U> >
     {
-      typedef metal::mat< n, m, mlc_bin_arith(T,U) > ret;
+      typedef metal::mat< n, m, mln_trait_op_times(T,U) > ret;
     };
 
+    // mat * s
+
     template <unsigned n, unsigned m, typename T,
-	      typename U>
-    struct mult< metal::mat<n,m,T>, U >
+	      typename S>
+    struct set_precise_binary_<op_times, metal::mat<n,m,T>, S >
     {
-      typedef metal::mat< n, m, mlc_bin_arith(T,U) > ret;
+      typedef metal::mat< n, m, mln_trait_op_times(T,S) > ret;
     };
 
-  }
+  } // end of namespace mln::trait
+
+
+
+  namespace value
+  {
+
+    template <unsigned n, unsigned m, typename T>
+    struct props< metal::mat<n,m,T> >
+    {
+      typedef trait::kind::data kind;
+      static const std::size_t card_ = n * m * mln_card_(T);
+      typedef metal::mat<n,m, mln_value_sum(T)> sum;
+    };
+
+  } // end of namespace mln::value
+
 
 
   namespace metal
@@ -111,47 +168,53 @@
     bool
     operator=(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
 
-    // +
+    // + 
     template <unsigned n, unsigned m, typename T, typename U>
     mat<n,m,T>&
     operator+=(mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
 
+    // + (binary)
+
     template <unsigned n, unsigned m, typename T, typename U>
-    mat<n,m,mlc_bin_arith(T,U)>
+    mat<n, m, mln_trait_op_plus(T,U)>
     operator+(mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
 
-    // -
+    // - 
     template <unsigned n, unsigned m, typename T, typename U>
     mat<n,m,T>&
     operator-=(mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
 
+    // - (binary)
+
     template <unsigned n, unsigned m, typename T, typename U>
-    mat<n,m,mlc_bin_arith(T,U)>
+    mat<n, m, mln_trait_op_minus(T,U)>
     operator-(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
 
+    // - (unary)
+
     template <unsigned n, unsigned m, typename T>
-    mat<n,m,T>
+    mat<n, m, mln_trait_op_uminus(T)>
     operator-(const mat<n,m,T>& lhs);
 
     // Operator *.
 
     template <unsigned n, unsigned o, typename T,
 	      unsigned m, typename U>
-    mat<n,m,mlc_bin_arith(T,U)>
-    operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs);
+    mat<n, m, mln_trait_op_times(T,U)>
+    operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs); // mat * mat
 
     template <unsigned n, unsigned m, typename T,
-	      typename U>
-    mat<n,m,mlc_bin_arith(T,U)>
-    operator*(const mat<n,m,T>& lhs, const U& rhs);
+	      typename S>
+    mat<n, m, mln_trait_op_times(T,S)>
+    operator*(const mat<n,m,T>& lhs, const S& s); // mat * s
 
     // * 
-    template <unsigned n, unsigned m, unsigned o, typename T, typename U>
-    mat<n,m,T>&
-    operator*=(mat<n,o,T>& lhs, const mat<o,m,U>& rhs);
+    template <unsigned n, typename T, typename U>
+    mat<n,n,T>&
+    operator*=(mat<n,n,T>& lhs, const mat<n,n,U>& rhs);
 
     template <unsigned n, unsigned m, typename T, typename U>
     mat<n,m,T>&
@@ -159,15 +222,15 @@
     
     // Operator /.
 
-    template <unsigned n, unsigned m, typename T, typename U>
-    mat<n,m,mlc_bin_arith(T,U)>
-    operator/(const mat<n,m,T>& lhs, const U& scalar);
+    template <unsigned n, unsigned m, typename T, typename S>
+    mat<n, m, mln_trait_op_times(T,S)> // FIXME: times instead of div...
+    operator/(const mat<n,m,T>& lhs, const S& s);
 
     // / 
-    template <unsigned n, unsigned m, typename T, typename U>
+    template <unsigned n, unsigned m, typename T, typename S>
     mat<n,m,T>&
-    operator/=(mat<n,m,T>& lhs, const U& scalar);
+    operator/=(mat<n,m,T>& lhs, const S& s);
 
     // <<
     
@@ -192,12 +255,16 @@
     template <unsigned n, unsigned m, typename T>
     mat<n,m,T> mat<n,m,T>::identity()
     {
-      mat<n,m,T> id;
-
+      static mat<n,m,T> id_;
+      static bool flower = true;
+      if (flower)
+	{
       for (unsigned i = 0; i < n; ++i)
 	for (unsigned j = 0; j < m; ++j)
-	  id.data_[i][j] = (i = j);
-      return id;
+	      id_.data_[i][j] = (i = j);
+	  flower = false;
+	}
+      return id_;
     }
 
     template <unsigned n, unsigned m, typename T>
@@ -279,10 +346,10 @@
     // Operator +.
 
     template <unsigned n, unsigned m, typename T, typename U>
-    mat<n,m,mlc_bin_arith(T,U)>
+    mat<n, m, mln_trait_op_plus(T,U)>
     operator+(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
     {
-      mat<n,m,mlc_bin_arith(T,U)> tmp;
+      mat<n, m, mln_trait_op_plus(T,U)> tmp;
       for (unsigned i = 0; i < n; ++i)
 	for (unsigned j = 0; j < m; ++j)
 	  tmp[i][j] = lhs(i, j) + rhs(i, j);
@@ -304,10 +371,10 @@
     // Operators -.
 
     template <unsigned n, unsigned m, typename T, typename U>
-    mat<n,m,mlc_bin_arith(T,U)>
+    mat<n,m, mln_trait_op_minus(T,U)>
     operator-(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
     {
-      mat<n,m,mlc_bin_arith(T,U)> tmp;
+      mat<n,m, mln_trait_op_minus(T,U)> tmp;
       for (unsigned i = 0; i < n; ++i)
 	for (unsigned j = 0; j < m; ++j)
 	  tmp(i, j) = lhs(i, j) - rhs(i, j);
@@ -315,10 +382,10 @@
     }
 
     template <unsigned n, unsigned m, typename T>
-    mat<n,m,T>
+    mat<n,m, mln_trait_op_uminus(T)>
     operator-(const mat<n,m,T>& rhs)
     {
-      mat<n,m,T> tmp;
+      mat<n,m, mln_trait_op_uminus(T)> tmp;
       for (unsigned i = 0; i < n; ++i)
 	for (unsigned j = 0; i < m; ++i)
 	  tmp(i, j) = - rhs(i, j);
@@ -327,21 +394,22 @@
 
     // * 
-    template <unsigned n, unsigned m, unsigned o, typename T, typename U>
-    mat<n,m,T>&
-    operator*=(mat<n,o,T>& lhs, const mat<o,m,U>& rhs)
+    template <unsigned n, typename T, typename U>
+    mat<n,n,T>&
+    operator*=(mat<n,n,T>& lhs, const mat<n,n,U>& rhs)
     {
-      lhs = lhs * rhs; // FIXME: OK?
+      // FIXME: Optimize!
+      lhs = lhs * rhs;
       return lhs;
     }
 
     template <unsigned n, unsigned m, typename T, typename U>
     mat<n,m,T>&
-    operator*=(mat<n,m,T>& lhs, const U& scalar)
+    operator*=(mat<n,m,T>& lhs, const U& s)
     {
       for (unsigned i = 0; i < n; ++i)
 	for (unsigned j = 0; j < m; ++j)
-	  lhs(i, j) *= scalar;
+	  lhs(i, j) *= s;
       return lhs;
     }
 
@@ -349,10 +417,10 @@
 
     template <unsigned n, unsigned o, typename T,
 	      unsigned m, typename U>
-    mat<n,m,mlc_bin_arith(T,U)>
+    mat<n,m, mln_trait_op_times(T,U)>
     operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs)
     {
-      mat<n,m,mlc_bin_arith(T,U)> tmp;
+      mat<n,m, mln_trait_op_times(T,U)> tmp;
       for (unsigned i = 0; i < n; ++i)
 	for (unsigned j = 0; j < m; ++j)
 	  {
@@ -364,39 +432,39 @@
     }
 
     template <unsigned n, unsigned m, typename T,
-	      typename U>
-    mat<n,m,mlc_bin_arith(T,U)>
-    operator*(const mat<n,m,T>& lhs, const U& rhs)
+	      typename S>
+    mat<n,m, mln_trait_op_times(T,S)>
+    operator*(const mat<n,m,T>& lhs, const S& s)
     {
-      mat<n,m,mlc_bin_arith(T,U)> tmp;
+      mat<n,m, mln_trait_op_times(T,S)> tmp;
       for (unsigned i = 0; i < n; ++i)
 	for (unsigned j = 0; j < m; ++j)
-	  tmp(i, j) = lhs(i, j) * rhs;
+	  tmp(i, j) = lhs(i, j) * s;
       return tmp;
     }
 
     // /
 
-    template <unsigned n, unsigned m, typename T, typename U>
+    template <unsigned n, unsigned m, typename T, typename S>
     mat<n,m,T>&
-    operator/=(mat<n,m,T>& lhs, const U& scalar)
+    operator/=(mat<n,m,T>& lhs, const S& s)
     {
       for (unsigned i = 0; i < n; ++i)
 	for (unsigned j = 0; j < m; ++j)
-	  lhs(i, j) /= scalar;
+	  lhs(i, j) /= s;
       return lhs;
     }
 
     // Operator /.
 
-    template <unsigned n, unsigned m, typename T, typename U>
-    mat<n,m,mlc_bin_arith(T,U)>
-    operator/(const mat<n,m,T>& lhs, const U& scalar)
+    template <unsigned n, unsigned m, typename T, typename S>
+    mat<n,m, mln_trait_op_times(T,S)> // FIXME: Use div, not times!
+    operator/(const mat<n,m,T>& lhs, const S& s)
     {
-      mat<n,m,mlc_bin_arith(T,U)> tmp;
+      mat<n,m, mln_trait_op_times(T,S)> tmp;
       for (unsigned i = 0; i < n; ++i)
 	for (unsigned j = 0; j < m; ++j)
-	  tmp[i][j] = lhs(i, j) / scalar;
+	  tmp[i][j] = lhs(i, j) / s;
       return tmp;
     }
 
Index: mln/metal/vec.hh
--- mln/metal/vec.hh	(revision 1214)
+++ mln/metal/vec.hh	(working copy)
@@ -32,7 +32,9 @@
 # include <cmath>
 
 # include <mln/core/concept/object.hh>
-# include <mln/metal/binary_arith_trait.hh>
+# include <mln/trait/all.hh>
+# include <mln/value/props.hh>
+
 
 // FIXME: Document.
 
@@ -154,6 +156,79 @@
       const vec<n, T>& normalize();
     };
 
+  } // end of namespace mln::metal
+
+
+  namespace trait
+  {
+
+    // promote
+
+    template <unsigned n, typename T, typename U>
+    struct set_precise_binary_<promote, metal::vec<n, T>, metal::vec<n, U> >
+    {
+      typedef metal::vec<n, mln_trait_promote(T, U)> ret;
+    };
+
+
+    // vec + vec
+
+    template <unsigned n, typename T, typename U>
+    struct set_precise_binary_<op_plus, metal::vec<n, T>, metal::vec<n, U> >
+    {
+      typedef metal::vec<n, mln_trait_op_plus(T, U)> ret;
+    };
+
+    // FIXME: + vec !
+
+    // vec - vec
+
+    template <unsigned n, typename T, typename U>
+    struct set_precise_binary_<op_minus, metal::vec<n, T>, metal::vec<n, U> >
+    {
+      typedef metal::vec<n, mln_trait_op_minus(T, U)> ret;
+    };
+
+    // - vec
+
+    template <unsigned n, typename T>
+    struct set_precise_unary_<op_uminus, metal::vec<n, T> >
+    {
+      typedef metal::vec<n, mln_trait_op_uminus(T)> ret;
+    };
+
+    // vec * s
+
+    template <unsigned n, typename T, typename S>
+    struct set_precise_binary_<op_times, metal::vec<n, T>, S >
+    {
+      typedef metal::vec<n, mln_trait_op_times(T, S)> ret;
+    };
+
+    // FIXME: vec / s
+    
+  } // end of namespace mln::trait
+
+
+
+  namespace value
+  {
+
+    template <unsigned n, typename T>
+    struct props< metal::vec<n,T> >
+    {
+      typedef trait::kind::data kind;
+      static const std::size_t card_ = n * mln_card_(T);
+      typedef metal::vec<n, mln_value_sum(T)> sum;
+    };
+
+  } // end of namespace mln::value
+
+
+
+  namespace metal
+  {
+
     // eq
 
     template <unsigned n, typename T, typename U>
@@ -169,7 +244,7 @@
     operator+=(vec<n,T>& lhs, const vec<n,U>& rhs);
     
     template <unsigned n, typename T, typename U>
-    vec<n, typename binary_arith_trait<T,U>::ret >
+    vec<n, mln_trait_op_plus(T,U)>
     operator+(const vec<n,T>& lhs, const vec<n,U>& rhs);
     
     // -
@@ -179,32 +254,32 @@
     operator-=(vec<n,T>& lhs, const vec<n,U>& rhs);
     
     template <unsigned n, typename T, typename U>
-    vec<n, typename binary_arith_trait<T,U>::ret>
+    vec<n, mln_trait_op_minus(T,U)>
     operator-(const vec<n,T>& lhs, const vec<n,U>& rhs);
     
     template <unsigned n, typename T>
-    vec<n, T>
+    vec<n, mln_trait_op_uminus(T)>
     operator-(const vec<n,T>& lhs);
     
     // *
     
     template <unsigned n, typename T, typename S>
     vec<n,T>&
-    operator*=(vec<n,T>& lhs, const S& scalar);
+    operator*=(vec<n,T>& lhs, const S& s);
     
     template <unsigned n, typename T, typename S>
-    vec<n, typename binary_arith_trait<T,S>::ret>
-    operator*(const S& scalar, const vec<n,T>& lhs);
+    vec<n, mln_trait_op_times(T,S)>
+    operator*(const vec<n,T>& lhs, const S& s);
     
     // /
     
     template <unsigned n, typename T, typename S>
     vec<n,T>&
-    operator/=(vec<n,T>& lhs, const S& scalar);
+    operator/=(vec<n,T>& lhs, const S& s);
     
     template <unsigned n, typename T, typename S>
-    vec<n, typename binary_arith_trait<T,S>::ret>
-    operator/(const vec<n,T>& lhs, const S& scalar);
+    vec<n, mln_trait_op_times(T,S)> // FIXME: Use div instead!
+    operator/(const vec<n,T>& lhs, const S& s);
     
     // <<
     
@@ -220,10 +295,10 @@
     std::ostream&
     operator<<(std::ostream& ostr, const vec<n,signed char>& v);
 
-    // vprod
+    // vprod // FIXME: Generalize...
 
     template <typename T, typename U>
-    vec<3, typename binary_arith_trait<T, U>::ret>
+    vec<3, mln_trait_op_times(T,U)> // FIXME: Sum of product...
     vprod(const vec<3, T>& lhs, const vec<3, U>& rhs);
 
 
@@ -335,10 +410,10 @@
     }
     
     template <unsigned n, typename T, typename U>
-    vec<n, typename binary_arith_trait<T,U>::ret >
+    vec<n, mln_trait_op_plus(T,U)>
     operator+(const vec<n,T>& lhs, const vec<n,U>& rhs)
     {
-      vec<n, typename binary_arith_trait<T,U>::ret> tmp;
+      vec<n, mln_trait_op_plus(T,U)> tmp;
       for (unsigned i = 0; i < n; ++i)
 	tmp[i] = lhs[i] + rhs[i];
       return tmp;
@@ -357,20 +432,20 @@
     }
     
     template <unsigned n, typename T, typename U>
-    vec<n, typename binary_arith_trait<T,U>::ret>
+    vec<n, mln_trait_op_minus(T,U)>
     operator-(const vec<n,T>& lhs, const vec<n,U>& rhs)
     {
-      vec<n, typename binary_arith_trait<T,U>::ret> tmp;
+      vec<n, mln_trait_op_minus(T,U)> tmp;
       for (unsigned i = 0; i < n; ++i)
 	tmp[i] = lhs[i] - rhs[i];
       return tmp;
     }
     
     template <unsigned n, typename T>
-    vec<n, T>
+    vec<n, mln_trait_op_uminus(T)>
     operator-(const vec<n,T>& lhs)
     {
-      vec<n, T> tmp;
+      vec<n, mln_trait_op_uminus(T)> tmp;
       for (unsigned i = 0; i < n; ++i)
 	tmp[i] = - lhs[i];
       return tmp;
@@ -381,20 +456,20 @@
     
     template <unsigned n, typename T, typename S>
     vec<n,T>&
-    operator*=(vec<n,T>& lhs, const S& scalar)
+    operator*=(vec<n,T>& lhs, const S& s)
     {
       for (unsigned i = 0; i < n; ++i)
-	lhs[i] *= scalar;
+	lhs[i] *= s;
       return lhs;
     }
     
     template <unsigned n, typename T, typename S>
-    vec<n, typename binary_arith_trait<T,S>::ret>
-    operator*(const S& scalar, const vec<n,T>& lhs)
+    vec<n, mln_trait_op_times(T,S)>
+    operator*(const vec<n,T>& lhs, const S& s)
     {
-      vec<n, typename binary_arith_trait<T,S>::ret> tmp;
+      vec<n, mln_trait_op_times(T,S)> tmp;
       for (unsigned i = 0; i < n; ++i)
-	tmp[i] = lhs[i] * scalar;
+	tmp[i] = lhs[i] * s;
       return tmp;
     }
     
@@ -403,22 +478,22 @@
     
     template <unsigned n, typename T, typename S>
     vec<n,T>&
-    operator/=(vec<n,T>& lhs, const S& scalar)
+    operator/=(vec<n,T>& lhs, const S& s)
     {
-      mln_precondition(scalar != 0);
+      mln_precondition(s != 0);
       for (unsigned i = 0; i < n; ++i)
-	lhs[i] /= scalar;
+	lhs[i] /= s;
       return lhs;
     }
     
     template <unsigned n, typename T, typename S>
-    vec<n, typename binary_arith_trait<T,S>::ret>
-    operator/(const vec<n,T>& lhs, const S& scalar)
+    vec<n, mln_trait_op_times(T,S)> // FIXME: Use div.
+    operator/(const vec<n,T>& lhs, const S& s)
     {
-      mln_precondition(scalar != 0);
-      vec<n, typename binary_arith_trait<T,S>::ret> tmp;
+      mln_precondition(s != 0);
+      vec<n, mln_trait_op_times(T,S)> tmp;
       for (unsigned i = 0; i < n; ++i)
-	tmp[i] = lhs[i] / scalar;
+	tmp[i] = lhs[i] / s;
       return tmp;
     }
     
@@ -458,10 +533,10 @@
     // vprod
 
     template <typename T, typename U>
-    vec<3, typename binary_arith_trait<T, U>::ret>
+    vec<3, T> // typename binary_arith_trait<T, U>::ret>
     vprod(const vec<3, T>& lhs, const vec<3, U>& rhs)
     {
-      vec<3, typename binary_arith_trait<T, U>::ret> tmp;
+      vec<3, T> tmp; // FIXME typename binary_arith_trait<T, U>::ret> tmp;
       tmp[0] = lhs[1] * rhs[2] - lhs[2] * rhs[1];
       tmp[1] = lhs[2] * rhs[0] - lhs[0] * rhs[2];
       tmp[2] = lhs[0] * rhs[1] - lhs[1] * rhs[0];
Index: mln/arith/plus.hh
--- mln/arith/plus.hh	(revision 1214)
+++ mln/arith/plus.hh	(working copy)
@@ -39,11 +39,26 @@
 
 # include <mln/pw/cst.hh>
 # include <mln/pw/image.hh>
+# include <mln/trait/op_plus.hh>
 
 
 namespace mln
 {
 
+
+//   namespace trait
+//   {
+
+//     template <typename L, typename R>
+//     struct op_plus< Image,L, Image,R >
+//     {
+//       typedef mln_trait_op_plus(mln_value(L), mln_value(R)) value;
+//       typedef mln_ch_value(L, value) ret;
+//     };
+
+//   } // end of namespace mln::trait
+
+
   namespace arith
   {
 
@@ -136,6 +151,7 @@
 
     // Facades.
 
+
     template <typename L, typename R, typename O>
     void plus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
     {
@@ -144,6 +160,17 @@
       impl::plus_(exact(lhs), exact(rhs), exact(output));
     }
 
+
+//     template <typename L, typename R>
+//     mln_trait_op_plus(L, R)
+//     plus(const Image<L>& lhs, const Image<R>& rhs)
+//     {
+//       mln_precondition(exact(rhs).domain() = exact(lhs).domain());
+//       mln_precondition(exact(output).domain() = exact(lhs).domain());
+//       impl::plus_(exact(lhs), exact(rhs), exact(output));
+//     }
+
+
     template <typename I, typename V, typename O>
     void plus_cst(const Image<I>& input, const V& val, Image<O>& output)
     {
Index: mln/value/props.hh
--- mln/value/props.hh	(revision 1214)
+++ mln/value/props.hh	(working copy)
@@ -39,12 +39,8 @@
 # include <cfloat>
 
 # include <mln/core/macros.hh>
-# include <mln/trait/kind.hh>
-
 # include <mln/metal/bool.hh>
-# include <mln/metal/vec.hh>
-# include <mln/metal/mat.hh>
-# include <mln/metal/binary_arith_trait.hh>
+# include <mln/trait/kind.hh>
 
 
 /// Get the minimum value of type \c T.
@@ -58,7 +54,7 @@
 /// Get the number of values for value type \c T.
 # define mln_card_(T) mln::value::props< T >::card_
 
-# define mln_value_card_(T) mln::value::props< T >::card_ // Better than the above name.
+# define mln_value_card_(T) mln::value::props< T >::card_ // Better than the above name. FIXME: Remove above def.
 
 
 /// Get the kind of value type \c T.
@@ -72,6 +68,8 @@
 /// Give the summation type for values of type \c T.
 # define mln_sum(T) typename mln::value::props< T >::sum
 
+# define mln_value_sum(T) typename mln::value::props< T >::sum // FIXME: Remove above def.
+
 
 
 namespace mln
@@ -230,28 +228,6 @@
       typedef double sum;
     };
 
-    // records
-
-    template <unsigned n, typename T>
-    struct props<metal::vec<n,T> >
-    {
-      static const metal::vec<n,T> min() { return make::vec<n>(mln_min(T)); }
-      static const metal::vec<n,T> max() { return make::vec<n>(mln_max(T)); }
-      typedef trait::kind::data kind;
-      static const std::size_t card_ = n * mln_card_(T);
-      typedef mlc_bin_arith(float,T) sum;
-    };
-
-    template <unsigned n, unsigned m, typename T>
-    struct props<metal::mat<n,m,T> >
-    {
-      static const metal::mat<n,m,T> min() { return make::mat<n,m>(mln_min(T)); }
-      static const metal::mat<n,m,T> max() { return make::mat<n,m>(mln_max(T)); }
-      typedef trait::kind::data kind;
-      static const std::size_t card_ = n * m * mln_card_(T);
-      typedef mlc_bin_arith(float,T) sum;
-    };
-
   } // end of namespace mln::value
 
 } // end of namespace mln
Index: mln/value/rgb.hh
--- mln/value/rgb.hh	(revision 1214)
+++ mln/value/rgb.hh	(working copy)
@@ -95,19 +95,21 @@
 
       /// addition
       rgb<n> operator+(const rgb<n>& v) const;
-      rgb<n> operator+(const enc& i) const;
-      rgb<n> operator+(const size_t& i) const;
+      // FIXME: was:
+//       rgb<n> operator+(const enc& i) const;
+//       rgb<n> operator+(const size_t& i) const;
 
       /// substraction
       rgb<n> operator-(const rgb<n>& v) const;
-      rgb<n> operator-(const enc& i) const;
-      rgb<n> operator-(const size_t& i) const;
+      // FIXME: was:
+//       rgb<n> operator-(const enc& i) const;
+//       rgb<n> operator-(const size_t& i) const;
 
       /// multiplication
-      rgb<n> operator*(const enc& i) const;
+      rgb<n> operator*(const enc& i) const; // FIXME: Use int instead of enc...
 
       /// division
-      rgb<n> operator/(const enc& i) const;
+      rgb<n> operator/(const enc& i) const; // FIXME: Likewise!
 
       /// Self addition
       rgb<n>& operator+=(const rgb<n>& v);
@@ -126,16 +128,19 @@
       equiv c_;
     };
 
+
     template <unsigned n>
     struct props< rgb<n> >
     {
       static const unsigned nbits = 24;
-      static const std::size_t card_ = metal::pow<2, nbits>::value;
-      static const rgb<n> max() { rgb<n> c(props< int_u<n> >::max); return c; }
-      static const rgb<n> min() { const rgb<n> c(props< int_u<n> >::min()); return c; }
+      static const std::size_t card_ = 0; // FIXME: was: metal::pow<2, nbits>::value;
       typedef trait::kind::color kind;
       typedef float_x3_t sum;
       typedef uchar_x3_t interop;
+
+      // FIXME: was:
+//       static const rgb<n> max() { rgb<n> c(props< int_u<n> >::max); return c; }
+//       static const rgb<n> min() { const rgb<n> c(props< int_u<n> >::min()); return c; }
     };
 
 
@@ -225,23 +230,23 @@
       return res;
     }
 
-    template <unsigned n>
-    rgb<n>
-    rgb<n>::operator-(const size_t& i_) const
-    {
-      enc i(i_);
-      return (*this - i);
-    }
-
-    template <unsigned n>
-    rgb<n>
-    rgb<n>::operator-(const enc& i) const
-    {
-      rgb<n> res;
-      for (int j = 0; j < 3; j++)
-	res.c_[j] = this->c_[j] - i;
-      return res;
-    }
+//     template <unsigned n>
+//     rgb<n>
+//     rgb<n>::operator-(const size_t& i_) const
+//     {
+//       enc i(i_);
+//       return (*this - i);
+//     }
+
+//     template <unsigned n>
+//     rgb<n>
+//     rgb<n>::operator-(const enc& i) const
+//     {
+//       rgb<n> res;
+//       for (int j = 0; j < 3; j++)
+// 	res.c_[j] = this->c_[j] - i;
+//       return res;
+//     }
 
     template <unsigned n>
     rgb<n>
@@ -253,23 +258,23 @@
       return res;
     }
 
-    template <unsigned n>
-    rgb<n>
-    rgb<n>::operator+(const size_t& i_) const
-    {
-      enc i(i_);
-      return (*this + i);
-    }
-
-    template <unsigned n>
-    rgb<n>
-    rgb<n>::operator+(const enc& i) const
-    {
-      rgb<n> res;
-      for (int j = 0; j < 3; j++)
-	res.c_[j] = this->c_[j] + i;
-      return res;
-    }
+//     template <unsigned n>
+//     rgb<n>
+//     rgb<n>::operator+(const size_t& i_) const
+//     {
+//       enc i(i_);
+//       return (*this + i);
+//     }
+
+//     template <unsigned n>
+//     rgb<n>
+//     rgb<n>::operator+(const enc& i) const
+//     {
+//       rgb<n> res;
+//       for (int j = 0; j < 3; j++)
+// 	res.c_[j] = this->c_[j] + i;
+//       return res;
+//     }
 
     template <unsigned n>
     rgb<n>&
Index: mln/value/int_s.hh
--- mln/value/int_s.hh	(revision 1214)
+++ mln/value/int_s.hh	(working copy)
@@ -37,12 +37,54 @@
 # include <mln/value/internal/value_like.hh>
 # include <mln/value/internal/encoding.hh>
 # include <mln/value/props.hh>
+# include <mln/trait/all.hh>
 # include <mln/debug/format.hh>
 
 
 namespace mln
 {
 
+
+  // Fwd decl.
+  namespace value { template <unsigned n> struct int_s; }
+
+
+
+  namespace trait
+  {
+
+    // promote
+
+    template <unsigned n>
+    struct set_precise_binary_< promote, mln::value::int_s<n>, int >
+    {
+      typedef int ret;
+    };
+
+    template <unsigned n>
+    struct set_precise_binary_< promote, int, mln::value::int_s<n> >
+    {
+      typedef int ret;
+    };
+
+    template <unsigned n>
+    struct set_precise_binary_< promote, mln::value::int_s<n>, float >
+    {
+      typedef float ret;
+    };
+
+    template <unsigned n>
+    struct set_precise_binary_< promote, float, mln::value::int_s<n> >
+    {
+      typedef float ret;
+    };
+
+    // FIXME: Is that all? (No!)
+
+  } // end of namespace mln::trait
+
+
+
   namespace value
   {
 
Index: mln/value/int_u.hh
--- mln/value/int_u.hh	(revision 1214)
+++ mln/value/int_u.hh	(working copy)
@@ -37,12 +37,51 @@
 # include <mln/value/internal/value_like.hh>
 # include <mln/value/internal/encoding.hh>
 # include <mln/value/props.hh>
+# include <mln/trait/all.hh>
 # include <mln/debug/format.hh>
 
 
 namespace mln
 {
 
+  // Fwd decl.
+  namespace value { template <unsigned n> struct int_u; }
+
+
+  namespace trait
+  {
+
+    // promote
+
+    template <unsigned n>
+    struct set_precise_binary_< promote, mln::value::int_u<n>, int >
+    {
+      typedef int ret;
+    };
+
+    template <unsigned n>
+    struct set_precise_binary_< promote, int, mln::value::int_u<n> >
+    {
+      typedef int ret;
+    };
+
+    template <unsigned n>
+    struct set_precise_binary_< promote, mln::value::int_u<n>, float >
+    {
+      typedef float ret;
+    };
+
+    template <unsigned n>
+    struct set_precise_binary_< promote, float, mln::value::int_u<n> >
+    {
+      typedef float ret;
+    };
+
+    // FIXME: Is that all? (No!)
+
+  } // end of namespace mln::trait
+
+
   namespace value
   {
 
Index: mln/border/resize.hh
--- mln/border/resize.hh	(revision 1214)
+++ mln/border/resize.hh	(working copy)
@@ -69,7 +69,7 @@
       mln_precondition(ima.has_data());
       if (ima.border() >= thickness)
 	return;
-      internal::fixme();
+      mln::internal::fixme();
       mln_postcondition(ima.border() >= thickness);
       return;
     }
Index: mln/border/fill.hh
--- mln/border/fill.hh	(revision 1214)
+++ mln/border/fill.hh	(working copy)
@@ -34,7 +34,6 @@
  */
 
 # include <mln/core/concept/image.hh>
-# include <mln/core/internal/fixme.hh>
 
 
 namespace mln
@@ -115,7 +114,6 @@
       typedef mln_point(I) P;
       const I& ima = exact(ima_);
       mln_precondition(ima.has_data());
-
       if (!ima.border ())
 	return;
       if (sizeof(mln_value(I)) = 1)
Index: mln/border/duplicate.hh
Index: mln/border/mirror.hh
--- mln/border/mirror.hh	(revision 1214)
+++ mln/border/mirror.hh	(working copy)
@@ -63,7 +63,7 @@
     {
       const I& ima = exact(ima_);
       mln_precondition(ima.has_data());
-      internal::fixme();
+      mln::internal::fixme();
     }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: mln/pw/image.hh
--- mln/pw/image.hh	(revision 1214)
+++ mln/pw/image.hh	(working copy)
@@ -86,9 +86,9 @@
       typedef trait::value::fixme     value;
 
       typedef trait::access::browsing access;
-      typedef trait::space::fixme     space;
+      typedef trait::space::fixme_    space;
       typedef trait::size::regular    size;
-      typedef trait::support::fixme   support;
+      typedef trait::support::fixme_  support;
 
       typedef trait::border::none     border;
       typedef trait::data::computed   data;
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            milena r1214: Add algorithm for extend labeling	(slow 3min for this test)
                        
                        
by Guillaume Duhamel 01 Oct '07
                    by Guillaume Duhamel 01 Oct '07
01 Oct '07
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-01  Guillaume Duhamel  <guillaume.duhamel(a)lrde.epita.fr>
	Add algorithm for extend labeling (slow 3min for this test).
	* labeling_algo.cc: New.
	* labeling_algo.hh: New.
	Update.
	* graph_labeling.hh: Update.
---
 graph_labeling.hh |    2 -
 labeling_algo.cc  |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 labeling_algo.hh  |   63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 126 insertions(+), 1 deletion(-)
Index: trunk/milena/sandbox/duhamel/graph_labeling.hh
===================================================================
--- trunk/milena/sandbox/duhamel/graph_labeling.hh	(revision 1213)
+++ trunk/milena/sandbox/duhamel/graph_labeling.hh	(revision 1214)
@@ -14,7 +14,7 @@
 
 namespace mln
 {
-  template <typename I, typename N, typename T>
+  template <typename I, typename N>
   mesh_p<point2d>*
   make_graph (Image<I>& ima_,
 	      const Neighborhood<N>& nbh)
Index: trunk/milena/sandbox/duhamel/labeling_algo.cc
===================================================================
--- trunk/milena/sandbox/duhamel/labeling_algo.cc	(revision 0)
+++ trunk/milena/sandbox/duhamel/labeling_algo.cc	(revision 1214)
@@ -0,0 +1,62 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+/*! \file tests/labeling_foreground.cc
+ *
+ * \brief Test on mln::labeling::foreground.
+ */
+
+# include <mln/core/image2d_b.hh>
+# include <mln/core/sub_image.hh>
+# include <mln/core/neighb2d.hh>
+# include <mln/value/int_u8.hh>
+# include <mln/level/fill.hh>
+# include <mln/io/pbm/load.hh>
+# include <mln/labeling/foreground.hh>
+# include <mln/debug/println.hh>
+# include "labeling_algo.hh"
+
+int main()
+{
+  using namespace mln;
+  using value::int_u8;
+
+  image2d_b<bool> in = io::pbm::load("../../img/toto.pbm");
+  image2d_b<unsigned> lab(in.domain());
+  image2d_b<unsigned> out(in.domain());
+
+  unsigned n;
+  labeling::foreground(in, c4(), lab, n);
+  std::cout << n << std::endl;
+
+  image2d_b<int> input(in.domain());
+  level::fill(input, lab);
+
+  debug::println(lab | make::box2d(50, 30));
+  out = make_algo (lab, c4 ());
+  debug::println(out | make::box2d(50, 30));
+}
Index: trunk/milena/sandbox/duhamel/labeling_algo.hh
===================================================================
--- trunk/milena/sandbox/duhamel/labeling_algo.hh	(revision 0)
+++ trunk/milena/sandbox/duhamel/labeling_algo.hh	(revision 1214)
@@ -0,0 +1,63 @@
+# include <mln/core/queue_p.hh>
+# include <mln/core/clone.hh>
+
+namespace mln
+{
+  template <typename I, typename N>
+  I
+  make_algo (Image<I>& ima_,
+	     const Neighborhood<N>& nbh)
+  {
+    I& ima = exact(ima_);
+    I out = clone(ima_);
+    queue_p<mln_point (I)> q;
+    int i;
+
+    // init
+    {
+    mln_fwd_piter(I) p(ima.domain());
+    mln_niter(N) n(nbh, p);
+
+    for_all (p)
+      {
+	if (ima(p) == 0)
+	  for_all(n)
+	    if (ima(n) != 0)
+	      {
+		q.push (p);
+		goto end;
+	      }
+      end:
+	i = 0;
+      }
+    }
+
+    std::cout << "q points = "
+	      << q.npoints ()
+	      << std::endl;
+    //body
+    {
+      while (q.npoints ())
+	{
+
+	  mln_point (I) po = q.front ();
+	  q.pop ();
+	  mln_invariant (ima(po) == 0);
+
+	  mln_niter(N) ne(nbh, po);
+	  for_all (ne)
+	    {
+	      if (ima.has(ne))
+		{
+		  if (out(ne) != 0)
+		    out(po) = out (ne);
+		  else
+		    if (!q.has (ne))
+		      q.push (ne);
+		}
+	    }
+	}
+    }
+    return out;
+  }
+}
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-01  Guillaume Duhamel  <guillaume.duhamel(a)lrde.epita.fr>
	Fix bug in mesh_image.
	* mesh_image.hh: Update.
---
 mesh_image.hh |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
Index: trunk/milena/mln/core/mesh_image.hh
===================================================================
--- trunk/milena/mln/core/mesh_image.hh	(revision 1212)
+++ trunk/milena/mln/core/mesh_image.hh	(revision 1213)
@@ -100,6 +100,12 @@
     const std::vector<V>& data_values () const;
 
     const mesh_p<P>& domain() const;
+
+    /// Return the first node of the link at i from loc
+    const P& access_location_link_node1 (const unsigned& i) const;
+
+    /// Return the second node of the link at i from loc
+    const P& access_location_link_node2 (const unsigned& i) const;
 };
 
 
@@ -169,6 +175,20 @@
     return this->data_->mesh_;
   }
 
+  template <typename P, typename V>
+  const P&
+  mesh_image<P, V>::access_location_link_node1 (const unsigned& i) const
+  {
+    return this->domain().loc_[this->domain().gr_.links_[i]->node1];
+  }
+
+  template <typename P, typename V>
+  const P&
+  mesh_image<P, V>::access_location_link_node2 (const unsigned& i) const
+  {
+    return this->domain().loc_[this->domain().gr_.links_[i]->node2];
+  }
+
 # endif // ! MLN_INCLUDE_ONLY
 
 } // end of namespace mln
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-01  Guillaume Duhamel  <guillaume.duhamel(a)lrde.epita.fr>
	Add log file.
	* log.txt: New.
	* graph_labeling.hh: Update.
---
 graph_labeling.hh |    2 +-
 log.txt           |   15 +++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)
Index: trunk/milena/sandbox/duhamel/graph_labeling.hh
===================================================================
--- trunk/milena/sandbox/duhamel/graph_labeling.hh	(revision 1211)
+++ trunk/milena/sandbox/duhamel/graph_labeling.hh	(revision 1212)
@@ -14,7 +14,7 @@
 
 namespace mln
 {
-  template <typename I, typename N>
+  template <typename I, typename N, typename T>
   mesh_p<point2d>*
   make_graph (Image<I>& ima_,
 	      const Neighborhood<N>& nbh)
Index: trunk/milena/sandbox/duhamel/log.txt
===================================================================
--- trunk/milena/sandbox/duhamel/log.txt	(revision 0)
+++ trunk/milena/sandbox/duhamel/log.txt	(revision 1212)
@@ -0,0 +1,15 @@
+- level/memset_
+- level/memcpy_
+- level/fill
+- level/paste
+
+- border/fill
+- border/mirror
+- border/duplicate
+
+- mln::canvas::impl::labeling_fast
+
+- util/graph
+- mesh_p / mesh_image
+- draw mesh
+- graph_labeling
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-01  Guillaume Duhamel  <guillaume.duhamel(a)lrde.epita.fr>
	Add image toto.pbm in img.
	* toto.pbm: New.
---
 0 files changed
Index: trunk/milena/img/toto.pbm
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/milena/img/toto.pbm
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    01 Oct '07
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-01  Guillaume Duhamel  <guillaume.duhamel(a)lrde.epita.fr>
	Move border_fill and border_duplicate into mln/border.
	* duplicate.hh: Update.
	* fill.hh: Update.
---
 duplicate.hh |  147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 fill.hh      |   62 ++++++++++++++++++++++++
 2 files changed, 205 insertions(+), 4 deletions(-)
Index: trunk/milena/mln/border/fill.hh
===================================================================
--- trunk/milena/mln/border/fill.hh	(revision 1209)
+++ trunk/milena/mln/border/fill.hh	(revision 1210)
@@ -56,15 +56,73 @@
     template <typename I>
     void fill(const Fast_Image<I>& ima, const mln_value(I)& v);
 
-
 # ifndef MLN_INCLUDE_ONLY
 
+    namespace impl
+    {
+
+      template <typename I>
+      void fill_size_1_(const Fast_Image<I>& ima_, const mln_value(I)& v)
+      {
+	typedef mln_point(I) P;
+	const I& ima = exact(ima_);
+	typedef mln_point(I) P;
+	typename I::line_piter pl(ima.domain());
+	std::size_t len_r = exact(ima).bbox().len(P::dim - 1);
+	std::size_t st = 0;
+	
+	for_all (pl)
+	  {
+	    std::size_t end = ima.offset_at (pl);
+	    std::memset((void*)&ima[st],
+			*(const int*)(&v),
+			end - st);
+	    st = end + len_r;
+	  }
+	std::memset((void*)&ima[st],
+		    *(const int*)(&v),
+		    ima.ncells () - st);
+      }
+    
+      template <typename I>
+      void fill_size_n_(const Fast_Image<I>& ima_, const mln_value(I)& v)
+      {
+	typedef mln_point(I) P;
+	const I& ima = exact(ima_);
+	typedef mln_point(I) P;
+	typename I::line_piter pl(ima.domain());
+	std::size_t len_r = exact(ima).bbox().len(P::dim - 1);
+	std::size_t st = 0;
+	
+	for_all (pl)
+	  {
+	    std::size_t end = ima.offset_at (pl);
+	    for (std::size_t i = st; i < end; ++i)
+	      const_cast<I&>(ima)[i] = v;
+	    st = end + len_r;
+	  }
+	for (std::size_t i = st; i < ima.ncells (); ++i)
+	  const_cast<I&>(ima)[i] = v;
+      }
+
+    }
+    // Facade.
+
     template <typename I>
     void fill(const Fast_Image<I>& ima_, const mln_value(I)& v)
     {
+      trace::entering("border::fill");
+      typedef mln_point(I) P;
       const I& ima = exact(ima_);
       mln_precondition(ima.has_data());
-      internal::fixme();
+
+      if (!ima.border ())
+	return;
+      if (sizeof(mln_value(I)) == 1)
+	impl::fill_size_1_(ima_, v);
+      else
+	impl::fill_size_n_(ima_, v);
+      trace::exiting("border::fill");
     }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: trunk/milena/mln/border/duplicate.hh
===================================================================
--- trunk/milena/mln/border/duplicate.hh	(revision 1209)
+++ trunk/milena/mln/border/duplicate.hh	(revision 1210)
@@ -34,7 +34,9 @@
  */
 
 # include <mln/core/concept/image.hh>
-# include <mln/core/internal/fixme.hh>
+# include <mln/level/memset_.hh>
+# include <mln/core/line_piter.hh>
+#include <mln/core/pixel.hh>
 
 
 namespace mln
@@ -58,14 +60,155 @@
 
 # ifndef MLN_INCLUDE_ONLY
 
+    namespace impl
+    {
+
+      template <typename I>
+      void duplicate_1d_(const Fast_Image<I>& ima_)
+      {
+	const I& ima = exact(ima_);
+	mln_precondition(ima.has_data());
+
+	typedef mln_point(I) P;
+	typename I::line_piter pl(ima.domain());
+ 	std::size_t len_c = exact(ima).bbox().len(P::dim - 1);
+ 	std::size_t border = ima.border ();
+
+	for (std::size_t i = 0; i < border; ++i)
+	  const_cast<I&>(ima)[i] = ima[border];
+
+	std::size_t st = border + len_c - 1;
+	for (std::size_t i = st + 1; i < ima.ncells (); ++i)
+	  const_cast<I&>(ima)[i] = ima[st];
+      }
+
+      template <typename I>
+      void duplicate_2d_(const Fast_Image<I>& ima_)
+      {
+	const I& ima = exact(ima_);
+	mln_precondition(ima.has_data());
+
+	typedef mln_point(I) P;
+	typename I::line_piter pl(ima.domain());
+ 	std::size_t border = ima.border ();
+ 	std::size_t border_2x = 2 * ima.border ();
+ 	std::size_t len_c = exact(ima).bbox().len(1);
+ 	std::size_t len_r = exact(ima).bbox().len(0);
+ 	std::size_t real_len_c = len_c + border_2x;
+ 	std::size_t st;
+
+	// Duplicate
+	for_all (pl)
+	  {
+ 	    st = ima.offset_at (pl);
+	    for (std::size_t i = 1; i <= border; ++i)
+	      const_cast<I&>(ima)[st - i] = ima[st];
+	    st = st + len_c - 1;
+	    for (std::size_t i = 1; i <= border; ++i)
+	      const_cast<I&>(ima)[st + i] = ima[st];
+ 	  }
+
+	// Duplicate n first * border line
+	st = real_len_c * border;
+	for (std::size_t k = 0; k < border; ++k)
+	  for (std::size_t i = 0; i < real_len_c; ++i)
+	    const_cast<I&>(ima)[k * real_len_c + i] = ima[st + i];
+
+	// Duplicate n last * border line
+	st = real_len_c * (border + len_r - 1);
+	for (std::size_t k = 1; k <= border; ++k)
+	  for (std::size_t i = st; i < st + real_len_c; ++i)
+	    const_cast<I&>(ima)[k * real_len_c + i] = ima[i];
+      }
+
+      template <typename I>
+      void duplicate_3d_(const Fast_Image<I>& ima_)
+      {
+	const I& ima = exact(ima_);
+	mln_precondition(ima.has_data());
+
+	typedef mln_point(I) P;
+	typename I::line_piter pl(ima.domain());
+ 	std::size_t border = ima.border ();
+ 	std::size_t border_2x = 2 * ima.border ();
+ 	std::size_t len_c = exact(ima).bbox().len(P::dim - 1);
+ 	std::size_t len_r = exact(ima).bbox().len(1);
+ 	std::size_t len_s = exact(ima).bbox().len(0);
+ 	std::size_t real_len_c = len_c + border_2x;
+ 	std::size_t real_len_r = len_r + border_2x;
+	std::size_t face = real_len_c * real_len_r;
+	std::size_t st;
+
+	pl.start ();
+
+	for (std::size_t k = 0; k < len_s; ++k)
+	  {
+
+ 	    // Duplicate
+	    for (std::size_t j = 0; j < len_r; ++j)
+	      {
+		st = ima.offset_at (pl);
+		for (std::size_t i = 1; i <= border; ++i)
+		  const_cast<I&>(ima)[st - i] = ima[st];
+		st = st + len_c - 1;
+		for (std::size_t i = 1; i <= border; ++i)
+		  const_cast<I&>(ima)[st + i] = ima[st];
+		pl.next ();
+	      }
+
+	    // Duplicate n last * border line
+	    st = border * face + k * face + border * real_len_c ;
+	    for (std::size_t j = 1; j <= border; ++j)
+	      for (std::size_t i = 0; i < real_len_c; ++i)
+		const_cast<I&>(ima)[st - j * real_len_c + i] = ima[st + i];
+
+	    // Duplicate n last * border line
+	    st = border * face + k * face + (len_r + border - 1) * real_len_c ;
+	    for (std::size_t j = 1; j <= border; ++j)
+	      for (std::size_t i = 0; i < real_len_c; ++i)
+		const_cast<I&>(ima)[st + j * real_len_c + i] = ima[st + i];
+	  }
+
+	// Duplicate n first * border face
+	st = border * face;
+	for (std::size_t k = 0; k < border; ++k)
+	  for (std::size_t i = 0; i < face; ++i)
+	    const_cast<I&>(ima)[k * face + i] = ima[st + i];
+
+	// Duplicate n last * border face
+	st = (len_s + border - 1) * face;
+	for (std::size_t k = 1; k <= border; ++k)
+	  for (std::size_t i = 0; i < face; ++i)
+	    const_cast<I&>(ima)[st + k * face + i] = ima[st + i];
+      }
+
+
+
+    } // end of namespace mln::border::impl
+
+
+    // Facade.
+    
     template <typename I>
     void duplicate(const Fast_Image<I>& ima_)
     {
+      trace::entering("border::duplicate");
+      typedef mln_point(I) P;
       const I& ima = exact(ima_);
       mln_precondition(ima.has_data());
-      internal::fixme();
+
+      if (!ima.border ())
+	return;
+      if (P::dim == 1)
+	impl::duplicate_1d_(ima_);
+      if (P::dim == 2)
+	impl::duplicate_2d_(ima_);
+      if (P::dim == 3)
+	impl::duplicate_3d_(ima_);
+      trace::exiting("border::duplicate");
     }
 
+
 # endif // ! MLN_INCLUDE_ONLY
 
   } // end of namespace mln::border
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0