Index: mlc/fcmp.hh
===================================================================
--- mlc/fcmp.hh	(revision 0)
+++ mlc/fcmp.hh	(revision 0)
@@ -0,0 +1,85 @@
+// Copyright (C) 2005  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, 59 Temple Place - Suite 330, 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 METALIC_FCMP_HH
+# define METALIC_FCMP_HH
+
+# include <mlc/afun.hh>
+
+
+
+# define mlc_decl_mfun_cmp(OperatorName, OperatorSymbol)				\
+											\
+  template <typename T1, typename T2> struct OperatorName##_;				\
+											\
+  template <typename T1, typename T2>							\
+  struct set_super_type < OperatorName##_<T1,T2> >					\
+  {											\
+    typedef abstract::binary_function< OperatorName##_<T1,T2> > ret;			\
+  };											\
+											\
+  template <typename T1, typename T2>							\
+  struct set_props < category::fun, OperatorName##_<T1,T2> >				\
+  {											\
+    typedef bool res_type;								\
+    typedef T1 arg1_type;								\
+    typedef T2 arg2_type;								\
+  };											\
+											\
+  template <typename T1, typename T2>							\
+  struct OperatorName##_ : public abstract::binary_function< OperatorName##_<T1,T2> >	\
+  {											\
+    bool impl_binop(const T1& arg1, const T2& arg2) const				\
+    {											\
+      return arg1 OperatorSymbol arg2;							\
+    }											\
+  };											\
+  											\
+  typedef mfun2<OperatorName##_> f_OperatorName##_type;					\
+  static f_OperatorName##_type f_OperatorName##;					\
+											\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+namespace mlc
+{
+
+  mlc_decl_mfun_cmp( eq,      == );
+  mlc_decl_mfun_cmp( neq,     != );
+
+  mlc_decl_mfun_cmp( less,    <  );
+  mlc_decl_mfun_cmp( leq,     <= );
+
+  mlc_decl_mfun_cmp( greater, >  );
+  mlc_decl_mfun_cmp( geq,     >= );
+
+} // end of namespace mlc
+
+
+
+#endif // ! METALIC_FCMP_HH
Index: mlc/afun.hh
===================================================================
--- mlc/afun.hh	(revision 0)
+++ mlc/afun.hh	(revision 0)
@@ -0,0 +1,387 @@
+// Copyright (C) 2005  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, 59 Temple Place - Suite 330, 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 METALIC_AFUN_HH
+# define METALIC_AFUN_HH
+
+# include <mlc/any.hh>
+# include <mlc/contract.hh>
+# include <mlc/overload.hh>
+# include <mlc/properties.hh>
+# include <mlc/to_string.hh>
+
+
+
+
+// FIXME: break cycling dependance due to...
+// FIXME: ...the recursive classes oln::pw::unary_op and oln::f_::abstract::munary
+
+
+
+
+// Macro.
+
+# define mlc_fun_type_of(FunType, Alias) \
+mlc_type_of(mlc, mlc::category::fun, FunType, Alias)
+
+
+
+namespace mlc
+{
+
+  mlc_equip_namespace_with_properties();
+
+  mlc_decl_typedef(res_type);
+  mlc_decl_typedef(arg_type);
+  mlc_decl_typedef(arg1_type);
+  mlc_decl_typedef(arg2_type);
+  mlc_decl_typedef(arg3_type);
+
+
+  // *the* category of functions.
+
+  namespace category
+  {
+    struct fun;
+  }
+
+
+  // fwd decls of function abstractions.
+
+  namespace abstract {
+
+    template <typename F> struct unary_function;
+    template <typename F> struct meta_unary_function;
+
+    template <typename F> struct binary_function;
+    template <typename F> struct meta_binary_function;
+
+    template <typename F> struct ternary_function;
+    template <typename F> struct meta_ternary_function;
+
+  } // end of mlc::abstract
+
+
+
+  template <>
+  struct set_default_props < category::fun >
+  {
+    typedef mlc::undefined_type res_type;
+    // for unary functions
+    typedef mlc::undefined_type arg_type;
+    // for binary functions
+    typedef mlc::undefined_type arg1_type;
+    typedef mlc::undefined_type arg2_type;
+    // for ternary functions
+    typedef mlc::undefined_type arg3_type;
+  };
+
+
+  template <typename F>
+  struct get_props < category::fun, F >
+  {
+    typedef mlc_fun_type_of(F, res)  res_type;
+    typedef mlc_fun_type_of(F, arg)  arg_type;
+    typedef mlc_fun_type_of(F, arg1) arg1_type;
+    typedef mlc_fun_type_of(F, arg2) arg2_type;
+    typedef mlc_fun_type_of(F, arg3) arg3_type;
+
+    static void echo(std::ostream& ostr)
+    {
+      ostr << "props_of( mlc::category::fun, " << mlc_to_string(F) << " ) =" << std::endl
+	   << "{" << std::endl
+	   << "\t res_type  = " << mlc_to_string(res_type)  << std::endl
+	   << "\t arg_type  = " << mlc_to_string(arg_type)  << std::endl
+	   << "\t arg1_type = " << mlc_to_string(arg1_type) << std::endl
+	   << "\t arg2_type = " << mlc_to_string(arg2_type) << std::endl
+	   << "\t arg3_type = " << mlc_to_string(arg3_type) << std::endl
+	   << "}" << std::endl;
+    }
+
+    static void ensure()
+    {
+      mlc::is_ok< res_type  >::ensure();
+      mlc::is_ok< arg_type  >::ensure();
+      mlc::is_ok< arg1_type >::ensure();
+      mlc::is_ok< arg2_type >::ensure();
+      mlc::is_ok< arg3_type >::ensure();
+    }
+  };
+
+
+
+
+  // traits for result type of meta functions.
+
+  template <typename F,
+	    typename A1,
+	    typename A2 = mlc::undefined_type,
+	    typename A3 = mlc::undefined_type>
+  struct mfun_res_traits
+  {
+    typedef mlc::undefined_type ret;
+  };
+
+
+
+
+  // tags used for overloading abstract::*_function::operator().
+
+
+  namespace tag
+  {
+    // for meta functions
+    struct mufun; // unary
+    struct mbfun; // binary
+    struct mtfun; // ternary
+
+  } // end of mlc::tag
+
+
+
+
+
+  /// default impl of mlc::abstract::meta_unary_function<F>::operator()(const A&)
+
+  template <typename F, typename A>
+  struct decl_overload <tag::mufun, 0,
+			F, A>
+  {
+    typedef typename mfun_res_traits<F, A>::ret ret;
+
+    static ret exec(const F& fun, const A& arg)
+    {
+      // safety check:
+      mlc_is_a(F, mlc::abstract::meta_unary_function)::ensure();
+
+      ret tmp = fun.impl_unop(arg);
+      return tmp;
+    }
+  };
+
+
+
+  /// default impl of mlc::abstract::meta_binary_function<F>::operator()(const A1&, const A2&)
+
+  template <typename F, typename A1, typename A2>
+  struct decl_overload <tag::mbfun, 0,
+			F, A1, A2>
+  {
+    typedef typename mfun_res_traits<F, A1, A2>::ret ret;
+
+    static ret exec(const F& fun, const A1& arg1, const A2& arg2)
+    {
+      // safety check:
+      mlc_is_a(F, mlc::abstract::meta_binary_function)::ensure();
+
+      ret tmp = fun.impl_binop(arg1, arg2);
+      return tmp;
+    }
+  };
+
+
+
+
+  // Properties of abstractions.
+
+  template <typename F>
+  struct set_props < category::fun, abstract::unary_function<F> >
+  {
+    typedef mlc::no_type arg1_type;
+    typedef mlc::no_type arg2_type;
+    typedef mlc::no_type arg3_type;
+  };
+
+  template <typename F>
+  struct set_props < category::fun, abstract::binary_function<F> >
+  {
+    typedef mlc::no_type arg_type;
+    typedef mlc::no_type arg3_type;
+  };
+
+  template <typename F>
+  struct set_props < category::fun, abstract::ternary_function<F> >
+  {
+    typedef mlc::no_type arg_type;
+  };
+
+
+
+  namespace abstract {
+
+
+    /// Class mlc::abstract::unary_function<F>.
+
+    template <typename F> // F is the exact type
+    struct unary_function : public mlc::any<F>
+    {
+      typedef mlc_fun_type_of(F, res) res_type;
+      typedef mlc_fun_type_of(F, arg) arg_type;
+
+      res_type operator()(const arg_type& arg) const
+      {
+	return this->exact().impl_unop(arg);
+      }
+
+    protected:
+      unary_function() {}
+      ~unary_function()
+      {
+	get_props<category::fun, F>::ensure();
+	mlc_check_method_impl(F, res_type, unop, const arg_type&, const);
+      }
+    };
+
+
+    /// Class mlc::abstract::meta_unary_function<F>.
+
+    template <typename F>
+    struct meta_unary_function : public mlc::any<F>
+    {
+      template <typename A>
+      typename overload<tag::mufun, F, A>::ret
+      operator()(const A& arg) const
+      {
+	return overload<tag::mufun, F, A>::exec(this->exact(), arg);
+      }
+    protected:
+      meta_unary_function() {}
+    };
+
+
+
+
+    /// Class mlc::abstract::binary_function<F>.
+
+    template <typename F> // F is the exact type
+    struct binary_function : public mlc::any<F>
+    {
+      typedef mlc_fun_type_of(F, res) res_type;
+      typedef mlc_fun_type_of(F, arg1) arg1_type;
+      typedef mlc_fun_type_of(F, arg2) arg2_type;
+
+      res_type operator()(const arg1_type& arg1, const arg2_type& arg2) const
+      {
+	return this->exact().impl_binop(arg1, arg2);
+      }
+
+    protected:
+      binary_function() {}
+      ~binary_function()
+      {
+	get_props<category::fun, F>::ensure();
+	mlc_check_method_impl_2(F, res_type, binop, const arg1_type&, const arg2_type&, const);
+      }
+    };
+
+
+    /// Class mlc::abstract::meta_binary_function<F>.
+
+    template <typename F>
+    struct meta_binary_function : public mlc::any<F>
+    {
+      template <typename A1, typename A2>
+      typename overload<tag::mbfun, F, A1, A2>::ret
+      operator()(const A1& arg1, const A2& arg2) const
+      {
+	return overload<tag::mbfun, F, A1, A2>::exec(this->exact(), arg1, arg2);
+      }
+    protected:
+      meta_binary_function() {}
+    };
+
+
+  } // end of namespace mlc::abstract
+
+
+
+  /// Meta unary function that relies on a unary function.
+
+  template <template <typename> class F>
+  struct mfun1;
+
+  template <template <typename> class F,
+	    typename A>
+  struct mfun_res_traits < mfun1<F>, A >
+  {
+    typedef mlc_fun_type_of(F<A>, res) ret;
+  };
+
+  template <template <typename> class F>
+  struct mfun1 : public abstract::meta_unary_function< mfun1<F> >
+  {
+    template <typename A>
+    mlc_fun_type_of(F<A>, res)
+    impl_unop(const A& arg) const
+    {
+      mlc_is_a(F<A>, mlc::abstract::unary_function)::ensure();
+      static const F<A> fun;
+      return fun(arg);
+    }
+  };
+
+
+
+  /// Meta binary function that relies on a binary function.
+
+  template <template <typename, typename> class F>
+  struct mfun2;
+
+  template <template <typename, typename> class F,
+	    typename A1, typename A2>
+  struct mfun_res_traits < mfun2<F>, A1, A2 >
+  {
+    typedef F<A1, A2> Fun;
+    typedef mlc_fun_type_of(Fun, res) ret;
+  };
+
+  template <template <typename, typename> class F>
+  struct mfun2 : public abstract::meta_binary_function< mfun2<F> >
+  {
+    template <typename A1, typename A2>
+    struct res {
+      typedef F<A1, A2> Fun;
+      typedef mlc_fun_type_of(Fun, res) ret;
+    };
+
+    template <typename A1, typename A2>
+    typename res<A1,A2>::ret
+    impl_binop(const A1& arg1, const A2& arg2) const
+    {
+      typedef F<A1, A2> Fun;
+      mlc_is_a(Fun, mlc::abstract::binary_function)::ensure();
+      static const F<A1,A2> fun;
+      return fun(arg1, arg2);
+    }
+  };
+
+
+} // end of namespace mlc
+
+
+
+#endif // ! METALIC_AFUN_HH
Index: mlc/traits.hh
===================================================================
--- mlc/traits.hh	(revision 256)
+++ mlc/traits.hh	(working copy)
@@ -29,20 +29,9 @@
 # define METALIC_TRAITS_HH
 
 
+// FIXME: this file contents seemed useless so it has been removed!
+// FIXME: remove also this file?
 
-namespace mlc {
 
-  template <typename T>
-  struct traits
-  {
-  };
 
-} // end of namespace mlc
-
-
-# define mlc_encoding_type(T) typename mlc::traits<T>::encoding_type
-# define mlc_encoding_type_(T) mlc::traits<T>::encoding_type
-
-
-
 #endif // ! METALIC_TRAITS_HH
Index: mlc/overload.hh
===================================================================
--- mlc/overload.hh	(revision 0)
+++ mlc/overload.hh	(revision 0)
@@ -0,0 +1,285 @@
+// Copyright (C) 2005 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, 59 Temple Place - Suite 330, 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 METALIC_OVERLOAD_HH
+# define METALIC_OVERLOAD_HH
+
+# include <mlc/types.hh>
+# include <mlc/bool.hh>
+# include <mlc/is_a.hh>
+# include <mlc/if.hh>
+# include <mlc/cmp.hh>
+
+
+namespace mlc
+{
+
+  /// where (for use as where clause).
+
+  template <typename B>
+  struct where : public B
+  {
+    static const bool check_that_B_is_a_Boolean = mlc_bool(B);
+  };
+
+
+
+  /// decl_overload (structure to be specialized by the client).
+
+  template <typename what_is_overloaded,
+ 	    unsigned i,
+	    typename T1,
+	    typename T2 = mlc::undefined_type,
+	    typename T3 = mlc::undefined_type>
+  struct decl_overload : public mlc::undefined_type
+  {};
+
+  // we know that the structure above is specialized by a client when
+  // it does not derive from mlc::undefined_type
+
+
+
+  // Internal stuff.
+
+  namespace internal
+  {
+
+    template <typename what, unsigned i,
+	      typename T1, typename T2, typename T3>
+    struct f_overload;
+
+    // f_overload(i)  ---here, other params are omitted
+    // {
+    //   for i = 1...
+    //     if (decl_overload(i) derives from undefined_type)
+    //       ---default case
+    //       return decl_overload(0)
+    //     else if (decl_overload(i) derives from true_type)
+    //       ---the proper overload version is found
+    //       return decl_overload(i)
+    //     else
+    //       ---a proper overload version is not found yet
+    //       ---so searching continues with i+1
+    //       return f_overload(i+1)
+    // }
+
+    template <typename base,
+	      typename what, unsigned i,
+	      typename T1, typename T2, typename T3>
+    struct helper_f_overload;
+
+    // default case
+
+    template <typename what, unsigned i,
+	      typename T1, typename T2, typename T3>
+    struct helper_f_overload <mlc::undefined_type,
+			      what, i, T1,T2,T3>
+    {
+      typedef decl_overload<what, 0, T1,T2,T3> ret;
+    };
+
+    // case 'found'
+
+    template <typename what, unsigned i,
+	      typename T1, typename T2, typename T3>
+    struct helper_f_overload <mlc::true_type,
+			      what, i, T1,T2,T3>
+    {
+      typedef decl_overload<what, i, T1,T2,T3> ret;
+    };
+
+    // case 'search again'
+
+    template <typename what, unsigned i,
+	      typename T1, typename T2, typename T3>
+    struct helper_f_overload <mlc::false_type,
+			      what, i, T1,T2,T3>
+    {
+      typedef typename f_overload<what, i+1, T1,T2,T3>::ret ret;
+    };
+
+    // f_overload
+
+    template <typename what, unsigned i,
+	      typename T1, typename T2, typename T3>
+    struct f_overload
+    {
+      typedef decl_overload<what, i, T1,T2,T3> decl;
+      typedef typename
+      mlc::if_< mlc_is_a(decl, mlc::undefined_type),
+		mlc::undefined_type, typename
+		mlc::if_< mlc_is_a(decl, mlc::true_type),
+			  mlc::true_type,
+			  mlc::false_type >::ret
+      >::ret base;
+      typedef typename helper_f_overload<base, what, i, T1,T2,T3>::ret ret;
+    };
+
+  } // end of namespace mlc::internal
+
+
+  /// overload (ternary version).
+
+  template <typename what,
+	    typename T1,
+	    typename T2 = mlc::undefined_type,
+	    typename T3 = mlc::undefined_type>
+  struct overload
+  {
+    static const unsigned start = 1;
+    typedef typename internal::f_overload<what, start, T1,T2,T3>::ret overload_type;
+
+    // ret
+    typedef typename overload_type::ret ret;
+
+    // exec
+    static ret exec(const T1& arg1, const T2& arg2, const T3& arg3)
+    {
+      return overload_type::exec(arg1, arg2, arg3);
+    }
+  };
+
+
+  /// overload (binary version).
+
+  template <typename what,
+	    typename T1, typename T2>
+  struct overload <what,
+		   T1, T2,
+		   mlc::undefined_type>
+  {
+    typedef mlc::undefined_type T3;
+
+    static const unsigned start = 1;
+    typedef typename internal::f_overload<what, start, T1,T2,T3>::ret overload_type;
+
+    // ret
+    typedef typename overload_type::ret ret;
+
+    // exec
+    static ret exec(const T1& arg1, const T2& arg2)
+    {
+      return overload_type::exec(arg1, arg2);
+    }
+  };
+
+
+  /// overload (unary version).
+
+  template <typename what,
+	    typename T1>
+  struct overload <what,
+		   T1,
+		   mlc::undefined_type, mlc::undefined_type>
+  {
+    typedef mlc::undefined_type T2;
+    typedef mlc::undefined_type T3;
+
+    static const unsigned start = 1;
+    typedef typename internal::f_overload<what, start, T1,T2,T3>::ret overload_type;
+
+    // ret
+    typedef typename overload_type::ret ret;
+
+    // exec
+    static ret exec(const T1& arg1)
+    {
+      return overload_type::exec(arg1);
+    }
+  };
+
+
+} // end of namespace mlc
+
+
+
+// sample use
+
+/*
+
+namespace tag
+{
+  struct foo;
+}
+
+template <class T>
+struct decl_overload <tag::foo, 1, T> : public where< mlc::eq<T, int> >
+{
+  typedef int ret;
+  static ret exec(const int& lhs)
+  {
+    std::cout << "foo(int)" << std::endl;
+    return 1;
+  }
+};
+
+template <typename I>
+struct decl_overload <tag::foo, 2, I> : public where< mlc_is_a(I, oln::abstract::image) >
+{
+  typedef int ret;
+  static ret exec(const I& lhs)
+    {
+      std::cout << "foo(image)" << std::endl;
+      lhs.m();
+      return 2;
+    }
+};
+
+template <typename T>
+struct decl_overload <tag::foo, 0, T>
+{
+  typedef int ret;
+  static ret exec(const T& lhs)
+  {
+    std::cout << "foo(T)" << std::endl;
+    return 0;
+  }
+};
+
+template <typename T>
+typename overload<tag::foo, T>::ret
+foo(const T& arg)
+{
+  return overload<tag::foo, T>::exec(arg);
+}
+
+int main()
+{
+  int i;
+  float f;
+  oln::image2d<int> ima;
+
+  test::foo(i);
+  test::foo(f);
+  test::foo(ima);
+}
+
+*/
+
+
+#endif // ! METALIC_OVERLOAD_HH
+
