
https://svn.lrde.epita.fr/svn/oln/trunk/extended Index: ChangeLog from Thierry Geraud <theo@lrde.epita.fr> Separate xtd function expressions from meta functions. . The design has changed: now an nary_fun_expr is not a subclass of meta_nary_fun. Both fun_nary_expr and meta_nary_fun inherit from open_nary_fun, which contains the shared part of nary_fun_expr and meta_nary_fun. Precisely, it provides the operator() that accepts different input: values or function expressions. * xtd/res.hh: Update. * xtd/cast.hh: Update. * xtd/math/trigo.hh: Update. * xtd/math/arith.hh: Update. * xtd/math/id.hh: Update. * xtd/mexpr.hh: Update. * xtd/args.hh: Update. * xtd/literal.hh: Update. * xtd/ops_expr.hh: Update. * xtd/abstract/open_nary_fun.hh: New. * xtd/abstract/plain_nary_fun.hh: New. * xtd/abstract/fun_expr.hh: Update. * xtd/abstract/meta_nary_fun.hh: New. * xtd/abstract/fun.hh: Update. * xtd/abstract/open_fun.hh: New. * xtd/abstract/plain_fun.hh: Update. * xtd/abstract/meta_fun.hh: Update. * xtd/abstract/fun_nary_expr.hh: New. * xtd/mfun.hh: Update. * xtd/TODO: New. * xtd/arg.hh: Update. * xtd/case.hh: Remove. * xtd/bind.hh: New. * xtd/internal: New. * xtd/internal/mlc.hh: New. * tests/id.cc: Update. * tests/bind.cc: Update. * tests/lit.cc: Update. tests/bind.cc | 4 tests/id.cc | 1 tests/lit.cc | 1 xtd/TODO | 5 xtd/abstract/fun.hh | 25 +-- xtd/abstract/fun_expr.hh | 247 ----------------------------- xtd/abstract/fun_nary_expr.hh | 234 ++++++++++++++++++++++++++++ xtd/abstract/meta_fun.hh | 292 ----------------------------------- xtd/abstract/meta_nary_fun.hh | 143 +++++++++++++++++ xtd/abstract/open_fun.hh | 71 ++++++++ xtd/abstract/open_nary_fun.hh | 340 +++++++++++++++++++++++++++++++++++++++++ xtd/abstract/plain_fun.hh | 196 ----------------------- xtd/abstract/plain_nary_fun.hh | 266 ++++++++++++++++++++++++++++++++ xtd/arg.hh | 9 - xtd/args.hh | 57 ++++++ xtd/bind.hh | 105 ++++++++++++ xtd/cast.hh | 14 - xtd/internal/mlc.hh | 54 ++++++ xtd/literal.hh | 81 --------- xtd/math/arith.hh | 2 xtd/math/id.hh | 2 xtd/math/trigo.hh | 6 xtd/mexpr.hh | 115 ++++++------- xtd/mfun.hh | 6 xtd/ops_expr.hh | 2 xtd/res.hh | 48 ++--- 26 files changed, 1381 insertions(+), 945 deletions(-) Index: xtd/res.hh --- xtd/res.hh (revision 441) +++ xtd/res.hh (working copy) @@ -28,19 +28,12 @@ #ifndef EXTENDED_RES_HH # define EXTENDED_RES_HH -# include <mlc/flags.hh> -# include <mlc/bool.hh> // FIXME: should be assert.hh -# include <mlc/if.hh> -# include <mlc/is_a.hh> -# include <mlc/comma.hh> -# include <mlc/cmp.hh> -# include <mlc/ret.hh> +# include <xtd/internal/mlc.hh> -# include <xtd/abstract/nary_fun.hh> - -// forward declarations ............................... +/// Forward declarations. +/// \{ namespace xtd { @@ -49,32 +42,27 @@ { template <typename E> - class meta_fun_; + class open_fun_; - template <unsigned n, typename E> - class meta_nary_fun_; + template <typename E> + class meta_fun_; template <typename E> class fun_expr_; - } // end of namespace xtd::abstract + template <unsigned n> + class nary_fun_; - template <typename F, - typename Expr> - struct m1expr; + class args; - template <typename F, - typename Expr1, typename Expr2> - struct m2expr; + } // end of namespace xtd::abstract - template <typename F, - typename Expr1, typename Expr2, typename Expr3> - struct m3expr; + template <typename A1, typename A2, typename A3> + struct args_; } // end of namespace xtd - -// end of forward declarations ........................ +/// \} @@ -160,7 +148,7 @@ // FIXME: doc... - // for meta_fun that are *not* fun_expr + // for meta_fun // ------------------------------------ @@ -264,7 +252,7 @@ - // for meta_fun that *are* fun_expr + // for fun_expr // ------------------------------------ template <typename F, @@ -295,7 +283,11 @@ typename A1 = mlc::none, typename A2 = mlc::none, typename A3 = mlc::none> - struct get_res_ : public mlc::if_< mlc_is_a(F, xtd::abstract::fun_expr_), + struct get_res_ + + // FIXME: add assertion "F is an xtd::abstract::open_fun_" + + : public mlc::if_< mlc_is_a(F, xtd::abstract::fun_expr_), get_expr_res_<F, xtd::args_<A1, A2, A3> >, do_get_res_<F, A1, A2, A3> >::ret {}; Index: xtd/cast.hh --- xtd/cast.hh (revision 441) +++ xtd/cast.hh (working copy) @@ -28,10 +28,8 @@ #ifndef EXTENDED_CAST_HH # define EXTENDED_CAST_HH -# include <mlc/pair.hh> - -# include <xtd/abstract/plain_fun.hh> -# include <xtd/abstract/meta_fun.hh> +# include <xtd/abstract/plain_nary_fun.hh> +# include <xtd/abstract/meta_nary_fun.hh> # include <xtd/mexpr.hh> @@ -105,16 +103,16 @@ */ template <typename Dest, typename A> - typename xtd::case_< xtd::tag::meta_1ary_fun_operator, + typename xtd::case_< xtd::tag::fun_operator_1, mlc::pair_< meta_cast_<Dest>, A > >::ret::res cast_(const A& a) { - typedef typename xtd::case_< xtd::tag::meta_1ary_fun_operator, + typedef typename xtd::case_< xtd::tag::fun_operator_1, mlc::pair_< meta_cast_<Dest>, A> >::ret case_t; - static const meta_cast_<Dest> the_; - return case_t::impl(&the_, a); + static const meta_cast_<Dest> target; + return case_t::impl(target, a); } Index: xtd/math/trigo.hh --- xtd/math/trigo.hh (revision 441) +++ xtd/math/trigo.hh (working copy) @@ -30,11 +30,7 @@ # include <cmath> -# include <mlc/assert.hh> -# include <mlc/logic.hh> -# include <mlc/cmp.hh> - -# include <xtd/abstract/plain_fun.hh> +# include <xtd/abstract/plain_nary_fun.hh> # include <xtd/mfun.hh> Index: xtd/math/arith.hh --- xtd/math/arith.hh (revision 441) +++ xtd/math/arith.hh (working copy) @@ -29,7 +29,7 @@ # define EXTENDED_MATH_ARITH_HH # include <xtd/builtin/traits.hh> -# include <xtd/abstract/plain_fun.hh> +# include <xtd/abstract/plain_nary_fun.hh> # include <xtd/mfun.hh> Index: xtd/math/id.hh --- xtd/math/id.hh (revision 441) +++ xtd/math/id.hh (working copy) @@ -28,7 +28,7 @@ #ifndef EXTENDED_MATH_ID_HH # define EXTENDED_MATH_ID_HH -# include <xtd/abstract/plain_fun.hh> +# include <xtd/abstract/plain_nary_fun.hh> # include <xtd/mfun.hh> Index: xtd/mexpr.hh --- xtd/mexpr.hh (revision 441) +++ xtd/mexpr.hh (working copy) @@ -28,16 +28,8 @@ #ifndef EXTENDED_MEXPR_HH # define EXTENDED_MEXPR_HH -# include <mlc/case.hh> -# include <mlc/assert.hh> -# include <mlc/logic.hh> -# include <mlc/is_a.hh> - -# include <xtd/abstract/nary_fun.hh> -# include <xtd/abstract/fun_expr.hh> -# include <xtd/args.hh> -# include <xtd/res.hh> -# include <xtd/literal.hh> +# include <xtd/abstract/meta_nary_fun.hh> +# include <xtd/abstract/fun_nary_expr.hh> @@ -57,6 +49,9 @@ struct MIXED_ARGUMENTS_IN_CALLING_A_TERNARY_META_FUNCTION__EXPR3; struct FIXME; + struct FIXME1; + struct FIXME2; + struct FIXME3; } // end of namespace xtd::ERROR @@ -98,10 +93,10 @@ : private mlc::assert_< mlc_is_a(F, abstract::nary_fun_<0>), ERROR::FIXME >, - private mlc::assert_< mlc_is_a(F, abstract::meta_fun_), - ERROR::FIXME >, + private mlc::assert_< mlc_is_a(F, abstract::open_fun_), + ERROR::FIXME2 >, - public abstract::nary_fun_expr_< 0, m0expr_<F> > + public abstract::fun_nary_expr_< 0, m0expr_<F> > { const F f; @@ -109,11 +104,9 @@ f() {} - m0expr_(const F& f) : - f(f) + m0expr_(const abstract::open_nary_fun_<0, F>& f) : + f(f.exact_()) { - mlc::assert_< mlc_is_a(F, abstract::nary_fun_<0>), - ERROR::FIXME >::check(); } template <typename Args> @@ -162,13 +155,13 @@ : private mlc::assert_< mlc_is_a(F, abstract::nary_fun_<1>), ERROR::FIXME >, - private mlc::assert_< mlc_is_a(F, abstract::meta_fun_), - ERROR::FIXME >, + private mlc::assert_< mlc_is_a(F, abstract::open_fun_), + ERROR::FIXME2 >, private mlc::assert_< mlc_is_a(Expr, abstract::fun_expr_), xtd::ERROR::FIXME >, - public abstract::nary_fun_expr_< xtd_nargs(Expr), + public abstract::fun_nary_expr_< xtd_nargs(Expr), m1expr_<F, Expr> > { typedef m1expr_<F, Expr> self; @@ -183,16 +176,14 @@ m1expr_(const abstract::fun_expr_<Expr>& expr) : f(), - expr(exact_of(expr)) + expr(expr.exact()) {} - m1expr_(const F& f, // FIXME: constraint? + m1expr_(const abstract::open_nary_fun_<1, F>& f, const abstract::fun_expr_<Expr>& expr) : - f(f), - expr(exact_of(expr)) + f(f.exact_()), + expr(expr.exact()) { - mlc::assert_< mlc_is_a(F, abstract::nary_fun_<1>), - ERROR::FIXME >::check(); } template <typename Args> @@ -244,16 +235,16 @@ struct m2expr_ : private mlc::assert_< mlc_is_a(F, abstract::nary_fun_<2>), - ERROR::FIXME >, + ERROR::FIXME1 >, - private mlc::assert_< mlc_is_a(F, abstract::meta_fun_), - ERROR::FIXME >, + private mlc::assert_< mlc_is_a(F, abstract::open_fun_), + ERROR::FIXME2 >, private mlc::assert_< mlc::and_< mlc_is_a(Expr1, abstract::fun_expr_), mlc_is_a(Expr2, abstract::fun_expr_) >, - xtd::ERROR::FIXME >, + xtd::ERROR::FIXME3 >, - public abstract::nary_fun_expr_< xtd_nargs(mlc_comma_2(m2expr_<F, Expr1, Expr2>)), + public abstract::fun_nary_expr_< xtd_nargs(mlc_comma_2(m2expr_<F, Expr1, Expr2>)), m2expr_<F, Expr1, Expr2> > { typedef m2expr_<F, Expr1, Expr2> self; @@ -271,19 +262,17 @@ m2expr_(const abstract::fun_expr_<Expr1>& expr1, const abstract::fun_expr_<Expr2>& expr2) : f(), - expr1(exact_of(expr1)), - expr2(exact_of(expr2)) + expr1(expr1.exact()), + expr2(expr2.exact()) {} - m2expr_(const F& f, + m2expr_(const abstract::open_nary_fun_<2, F>& f, const abstract::fun_expr_<Expr1>& expr1, const abstract::fun_expr_<Expr2>& expr2) : - f(f), - expr1(exact_of(expr1)), - expr2(exact_of(expr2)) + f(f.exact_()), + expr1(expr1.exact()), + expr2(expr2.exact()) { - mlc::assert_< mlc_is_a(F, abstract::nary_fun_<2>), - ERROR::FIXME >::check(); } template <typename Args> @@ -338,15 +327,15 @@ : private mlc::assert_< mlc_is_a(F, abstract::nary_fun_<3>), ERROR::FIXME >, - private mlc::assert_< mlc_is_a(F, abstract::meta_fun_), - ERROR::FIXME >, + private mlc::assert_< mlc_is_a(F, abstract::open_fun_), + ERROR::FIXME2 >, private mlc::assert_< mlc::and_list_< mlc_is_a(Expr1, abstract::fun_expr_), mlc_is_a(Expr2, abstract::fun_expr_), mlc_is_a(Expr3, abstract::fun_expr_) >, xtd::ERROR::FIXME >, - public abstract::nary_fun_expr_< xtd_nargs(mlc_comma_3(m3expr_<F, Expr1, Expr2, Expr3>)), + public abstract::fun_nary_expr_< xtd_nargs(mlc_comma_3(m3expr_<F, Expr1, Expr2, Expr3>)), m3expr_<F, Expr1, Expr2, Expr3> > { typedef m3expr_<F, Expr1, Expr2, Expr3> self; @@ -367,22 +356,20 @@ const abstract::fun_expr_<Expr2>& expr2, const abstract::fun_expr_<Expr3>& expr3) : f(), - expr1(exact_of(expr1)), - expr2(exact_of(expr2)), - expr3(exact_of(expr3)) + expr1(expr1.exact()), + expr2(expr2.exact()), + expr3(expr3.exact()) {} - m3expr_(const F& f, + m3expr_(const abstract::open_nary_fun_<3, F>& f, const abstract::fun_expr_<Expr1>& expr1, const abstract::fun_expr_<Expr2>& expr2, const abstract::fun_expr_<Expr3>& expr3) : - f(f), - expr1(exact_of(expr1)), - expr2(exact_of(expr2)), - expr3(exact_of(expr3)) + f(f.exact_()), + expr1(expr1.exact()), + expr2(expr2.exact()), + expr3(expr3.exact()) { - mlc::assert_< mlc_is_a(F, abstract::nary_fun_<3>), - ERROR::FIXME >::check(); } template <typename Args> @@ -396,32 +383,32 @@ - // meta_nary_fun_<1, F>::operator()(abstract::fun_expr_<Expr>& expr) const + // open_nary_fun_<1, F>::operator()(abstract::fun_expr_<Expr>& expr) const template <typename F, typename Expr> - struct case_< tag::meta_1ary_fun_operator, + struct case_< tag::fun_operator_1, mlc::pair_<F, Expr>, 1 > : public mlc::where_< mlc_is_a(Expr, abstract::fun_expr_) > { typedef m1expr_<F, Expr> res; - static res impl(const abstract::meta_nary_fun_<1, F>* this_, + static res impl(const abstract::open_nary_fun_<1, F>& target, const abstract::fun_expr_<Expr>& expr) { - res tmp(exact_of(*this_), expr); + res tmp(target, expr); return tmp; } }; - // meta_nary_fun_<2, F>::operator()(const fun_expr_<Expr1>& expr1, + // open_nary_fun_<2, F>::operator()(const fun_expr_<Expr1>& expr1, // const fun_expr_<Expr2>& expr2) const template <typename F, typename Expr1, typename Expr2> - struct case_< tag::meta_2ary_fun_operator, + struct case_< tag::fun_operator_2, mlc::valist_<F, Expr1, Expr2>, 1 > : public mlc::where_< mlc::or_< mlc_is_a(Expr1, abstract::fun_expr_), @@ -437,11 +424,11 @@ { typedef m2expr_<F, Expr1, Expr2> res; - static res impl(const abstract::meta_nary_fun_<2, F>* this_, + static res impl(const abstract::open_nary_fun_<2, F>& target, const abstract::fun_expr_<Expr1>& expr1, const abstract::fun_expr_<Expr2>& expr2) { - res tmp(exact_of(*this_), expr1, expr2); + res tmp(target, expr1, expr2); return tmp; } @@ -449,12 +436,12 @@ - // meta_nary_fun_<3, F>::operator()(const fun_expr_<Expr1>& expr1, + // open_nary_fun_<3, F>::operator()(const fun_expr_<Expr1>& expr1, // const fun_expr_<Expr2>& expr2, // const fun_expr_<Expr3>& expr3) const template <typename F, typename Expr1, typename Expr2, typename Expr3> - struct case_< tag::meta_3ary_fun_operator, + struct case_< tag::fun_operator_3, mlc::valist_<F, Expr1, Expr2, Expr3>, 1 > : public mlc::where_< mlc::or_list_< mlc_is_a(Expr1, abstract::fun_expr_), @@ -481,12 +468,12 @@ { typedef m3expr_<F, Expr1, Expr2, Expr3> res; - static res impl(const abstract::meta_nary_fun_<3, F>* this_, + static res impl(const abstract::open_nary_fun_<3, F>& target, const abstract::fun_expr_<Expr1>& expr1, const abstract::fun_expr_<Expr2>& expr2, const abstract::fun_expr_<Expr3>& expr3) { - res tmp(exact_of(*this_), expr1, expr2, expr3); + res tmp(target, expr1, expr2, expr3); return tmp; } }; Index: xtd/args.hh --- xtd/args.hh (revision 441) +++ xtd/args.hh (working copy) @@ -28,9 +28,13 @@ #ifndef EXTENDED_ARGS_HH # define EXTENDED_ARGS_HH -# include <mlc/flags.hh> -# include <mlc/assert.hh> -# include <mlc/is_a.hh> +# include <xtd/internal/mlc.hh> + + + +// FIXME: doc + +# define xtd_nargs(F) xtd::internal::get_nargs_<F>::ret @@ -60,6 +64,7 @@ + /*! \class xtd::args_<A1, ..> ** ** FIXME: to pack arguments @@ -158,6 +163,52 @@ } + + + + + namespace ERROR + { + + struct SPECIALIZATION_OF_xtd_nargs_IS_FOR_xtd_fun_expr_ONLY; + struct SPECIALIZATION_OF_xtd_nargs_NOT_FOUND_FOR_AN_xtd_fun_expr; + + } // end of namespace xtd::ERROR + + + + /*! \class xtd::nargs_<F> + ** + ** FIXME: doc + */ + + template <typename F> + struct nargs_ : public mlc::undefined + { + }; + + + namespace internal + { + + template <typename F> + struct get_nargs_ + + : // private mlc::assert_< mlc_is_a(F, xtd::abstract::fun_expr_), + // xtd::ERROR::SPECIALIZATION_OF_xtd_nargs_IS_FOR_xtd_fun_expr_ONLY >, + // FIXME: the static assertion above does *not* compile... + + private mlc::assert_< mlc_is_not_a(xtd::nargs_<F>, mlc::undefined), + xtd::ERROR::SPECIALIZATION_OF_xtd_nargs_NOT_FOUND_FOR_AN_xtd_fun_expr > + { + static const unsigned ret = xtd::nargs_<F>::ret; + }; + + } // end of xtd::internal + + + + } // end of namespace xtd Index: xtd/literal.hh --- xtd/literal.hh (revision 441) +++ xtd/literal.hh (working copy) @@ -28,12 +28,9 @@ #ifndef EXTENDED_LITERAL_HH # define EXTENDED_LITERAL_HH -# include <mlc/assert.hh> -# include <mlc/is_a.hh> - -# include <xtd/abstract/plain_fun.hh> -# include <xtd/abstract/meta_fun.hh> -# include <xtd/abstract/fun_expr.hh> +# include <xtd/abstract/plain_nary_fun.hh> +# include <xtd/abstract/meta_nary_fun.hh> +# include <xtd/abstract/fun_nary_expr.hh> @@ -139,7 +136,7 @@ : private mlc::assert_< mlc_is_not_a(T, abstract::fun_), xtd::ERROR::FIXME >, - public abstract::nary_fun_expr_< 0, literal_expr_<T> > + public abstract::fun_nary_expr_< 0, literal_expr_<T> > { const T value; @@ -168,75 +165,5 @@ } // end of namespace xtd -# include <xtd/mexpr.hh> -# include <xtd/arg.hh> - - -namespace xtd -{ - - namespace abstract - { - - // nary_fun_expr_< 2, E >::bind_i - - template <typename E> - template <typename T> - m2expr_< E, literal_expr_<T>, arg_<2> > - nary_fun_expr_< 2, E >::bind_1(const T& value) const - { - typedef m2expr_< E, literal_expr_<T>, arg_<2> > ret; - ret tmp(exact_of(this), lit(value), arg_<2>()); - return tmp; - } - - template <typename E> - template <typename T> - m2expr_< E, arg_<1>, literal_expr_<T> > - nary_fun_expr_< 2, E >::bind_2(const T& value) const - { - typedef m2expr_< E, arg_<1>, literal_expr_<T> > ret; - ret tmp(exact_of(this), arg_<1>(), lit(value)); - return tmp; - } - - - // nary_fun_expr_< 3, E >::bind_i - - template <typename E> - template <typename T> - m3expr_< E, literal_expr_<T>, arg_<2>, arg_<3> > - nary_fun_expr_< 3, E >::bind_1(const T& value) const - { - typedef m3expr_< E, literal_expr_<T>, arg_<2>, arg_<3> > ret; - ret tmp(exact_of(this), lit(value), arg_<2>(), arg_<3>()); - return tmp; - } - - template <typename E> - template <typename T> - m3expr_< E, arg_<1>, literal_expr_<T>, arg_<3> > - nary_fun_expr_< 3, E >::bind_2(const T& value) const - { - typedef m3expr_< E, arg_<1>, literal_expr_<T>, arg_<3> > ret; - ret tmp(exact_of(this), arg_<1>(), lit(value), arg_<3>()); - return tmp; - } - - template <typename E> - template <typename T> - m3expr_< E, arg_<1>, arg_<2>, literal_expr_<T> > - nary_fun_expr_< 3, E >::bind_3(const T& value) const - { - typedef m3expr_< E, arg_<1>, arg_<2>, literal_expr_<T> > ret; - ret tmp(exact_of(this), arg_<1>(), arg_<2>(), lit(value)); - return tmp; - } - - } // end of namespace xtd::abstract - -} // end of namespace xtd - - #endif // ! EXTENDED_LITERAL_HH Index: xtd/ops_expr.hh --- xtd/ops_expr.hh (revision 441) +++ xtd/ops_expr.hh (working copy) @@ -28,8 +28,6 @@ #ifndef EXTENDED_OPS_EXPR_HH # define EXTENDED_OPS_EXPR_HH -# include <mlc/case.hh> - # include <xtd/abstract/fun_expr.hh> # include <xtd/mexpr.hh> # include <xtd/math/arith.hh> Index: xtd/abstract/open_nary_fun.hh --- xtd/abstract/open_nary_fun.hh (revision 0) +++ xtd/abstract/open_nary_fun.hh (revision 0) @@ -0,0 +1,340 @@ +// Copyright (C) 2002, 2005, 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, 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 EXTENDED_ABSTRACT_OPEN_NARY_FUN_HH +# define EXTENDED_ABSTRACT_OPEN_NARY_FUN_HH + +# include <xtd/abstract/open_fun.hh> +# include <xtd/abstract/nary_fun.hh> +# include <xtd/res.hh> + + + + +// macros + +namespace xtd +{ + + + namespace ERROR + { + struct ARG_SHOULD_NOT_BE_A_PLAIN_FUN; + struct ARG1_SHOULD_NOT_BE_A_PLAIN_FUN; + struct ARG2_SHOULD_NOT_BE_A_PLAIN_FUN; + struct ARG3_SHOULD_NOT_BE_A_PLAIN_FUN; + + struct ARG_SHOULD_NOT_BE_A_META_FUN; + struct ARG1_SHOULD_NOT_BE_A_META_FUN; + struct ARG2_SHOULD_NOT_BE_A_META_FUN; + struct ARG3_SHOULD_NOT_BE_A_META_FUN; + + }// end of namespace xtd + + + + // FIXME: document case stuff... + + namespace tag + { + + struct fun_operator_1; + struct fun_operator_2; + struct fun_operator_3; + + } // end of namespace xtd::tag + + + // open_nary_fun_<1, E>::operator()(const A& a) const + + template <typename E, typename A> + struct default_case_ < tag::fun_operator_1, + mlc::pair_<E, A> > + { + typedef xtd_res_1(E, A) res; + + static res impl(const E& target, + const A& a) + { + return target.impl_calc(a); + } + }; + + + // open_nary_fun_<2, E>::operator()(const A1& a1, const A2& a2) const + + template <typename E, typename A1, typename A2> + struct default_case_ < tag::fun_operator_2, + mlc::valist_<E, A1, A2> > + { + typedef xtd_res_2(E, A1, A2) res; + + static res impl(const E& target, + const A1& a1, const A2& a2) + { + return target.impl_calc(a1, a2); + } + }; + + + // open_nary_fun_<3, E>::operator()(const A1& a1, const A2& a2, const A3& a3) const + + template <typename E, typename A1, typename A2, typename A3> + struct default_case_ < tag::fun_operator_3, + mlc::valist_<E, A1, A2, A3> > + { + typedef xtd_res_3(E, A1, A2, A3) res; + + static res impl(const E& target, + const A1& a1, const A2& a2, const A3& a3) + { + return target.impl_calc(a1, a2, a3); + } + }; + + +} // end of namespace xtd + + + + +namespace xtd +{ + + namespace abstract + { + + /// Forward declarations. + /// \{ + + template <typename E> class plain_fun_; + + template <typename E> class meta_fun_; + + /// \} + + + + /*! \class xtd::abstract::open_nary_fun_<n, E> + ** + ** FIXME: doc + ** + ** Parameter n is the number of arguments with n being 1, 2, or 3. + ** Parameter E is the exact type of the function. + */ + + template <unsigned n, typename E> + class open_nary_fun_; + + + + /*! \class xtd::abstract::open_nary_fun_<0, E> + ** + ** FIXME: doc + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class open_nary_fun_< 0, E > + + : public open_fun_<E>, + public nary_fun_<0> + { + public: + + /* + ** This member is not templated so its behavior at compile-time + ** is different than open_nary_fun_<n,E>::operator() where n > + ** 0. Here the return type should be known before the hierarchy + ** classes are fully compiled thus static assertions in the + ** macro xtd_res_0 do *not* work. An alternate macro is thus + ** in use. + */ + + xtd_internal_res_0(E) + operator()() const + { + return this->exact_().impl_calc(); + } + + protected: + open_nary_fun_() {} + }; + + + + /*! \class xtd::abstract::open_nary_fun_<1, E> + ** + ** FIXME: doc + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class open_nary_fun_< 1, E > + + : public open_fun_<E>, + public nary_fun_<1> + { + public: + + template <typename A> + struct case_ + + : private mlc::assert_< mlc_is_not_a(A, xtd::abstract::plain_fun_), + xtd::ERROR::ARG_SHOULD_NOT_BE_A_PLAIN_FUN >, + + private mlc::assert_< mlc_is_not_a(A, xtd::abstract::meta_fun_), + xtd::ERROR::ARG_SHOULD_NOT_BE_A_META_FUN >, + + public xtd::case_< xtd::tag::fun_operator_1, + mlc::pair_<E, A> >::ret + {}; + + template <typename A> + typename case_<A>::res + operator()(const A& a) const + { + return case_<A>::impl(this->exact_(), a); + } + + protected: + open_nary_fun_() {} + }; + + + + /*! \class xtd::abstract::operator_<2, E> + ** + ** Abstract base class for meta functions taking two arguments. + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class open_nary_fun_< 2, E > + + : public open_fun_<E>, + public nary_fun_<2> + { + public: + + template <typename A1, typename A2> + struct case_ + + : private mlc::assert_< mlc_is_not_a(A1, xtd::abstract::plain_fun_), + xtd::ERROR::ARG1_SHOULD_NOT_BE_A_PLAIN_FUN >, + + private mlc::assert_< mlc_is_not_a(A1, xtd::abstract::meta_fun_), + xtd::ERROR::ARG1_SHOULD_NOT_BE_A_META_FUN >, + + private mlc::assert_< mlc_is_not_a(A2, xtd::abstract::plain_fun_), + xtd::ERROR::ARG2_SHOULD_NOT_BE_A_PLAIN_FUN >, + + private mlc::assert_< mlc_is_not_a(A2, xtd::abstract::meta_fun_), + xtd::ERROR::ARG2_SHOULD_NOT_BE_A_META_FUN >, + + public xtd::case_< xtd::tag::fun_operator_2, + mlc::valist_<E, A1, A2> >::ret + {}; + + template <typename A1, typename A2> + typename case_<A1, A2>::res + operator()(const A1& a1, const A2& a2) const + { + return case_<A1, A2>::impl(this->exact_(), a1, a2); + } + + protected: + open_nary_fun_() {} + }; + + + /*! \class xtd::abstract::open_nary_fun_<3, E> + ** + ** Abstract base class for meta functions taking three arguments. + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class open_nary_fun_< 3, E > + + : public open_fun_<E>, + public nary_fun_<3> + { + public: + + template <typename A1, typename A2, typename A3> + struct case_ + + : private mlc::assert_< mlc_is_not_a(A1, xtd::abstract::plain_fun_), + xtd::ERROR::ARG1_SHOULD_NOT_BE_A_PLAIN_FUN >, + + private mlc::assert_< mlc_is_not_a(A1, xtd::abstract::meta_fun_), + xtd::ERROR::ARG1_SHOULD_NOT_BE_A_META_FUN >, + + private mlc::assert_< mlc_is_not_a(A2, xtd::abstract::plain_fun_), + xtd::ERROR::ARG2_SHOULD_NOT_BE_A_PLAIN_FUN >, + + private mlc::assert_< mlc_is_not_a(A2, xtd::abstract::meta_fun_), + xtd::ERROR::ARG2_SHOULD_NOT_BE_A_META_FUN >, + + private mlc::assert_< mlc_is_not_a(A3, xtd::abstract::plain_fun_), + xtd::ERROR::ARG3_SHOULD_NOT_BE_A_PLAIN_FUN >, + + private mlc::assert_< mlc_is_not_a(A3, xtd::abstract::meta_fun_), + xtd::ERROR::ARG3_SHOULD_NOT_BE_A_META_FUN >, + + public xtd::case_< xtd::tag::fun_operator_3, + mlc::valist_<E, A1, A2, A3> >::ret + {}; + + template <typename A1, typename A2, typename A3> + typename case_<A1, A2, A3>::res + operator()(const A1& a1, const A2& a2, const A3& a3) const + { + return case_<A1, A2, A3>::impl(this->exact_(), a1, a2, a3); + } + + protected: + open_nary_fun_() {} + }; + + + } // end of namespace xtd::abstract + +} // end of namespace xtd + + + +#endif // ! EXTENDED_ABSTRACT_OPEN_NARY_FUN_HH Index: xtd/abstract/plain_nary_fun.hh --- xtd/abstract/plain_nary_fun.hh (revision 0) +++ xtd/abstract/plain_nary_fun.hh (revision 0) @@ -0,0 +1,266 @@ +// Copyright (C) 2002, 2005, 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, 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 EXTENDED_ABSTRACT_PLAIN_NARY_FUN_HH +# define EXTENDED_ABSTRACT_PLAIN_NARY_FUN_HH + +# include <xtd/abstract/plain_fun.hh> +# include <xtd/abstract/nary_fun.hh> + + +// macros + +# define xtd_arg(F) typename xtd::typedef_::arg_type::from_<xtd::fun_traits_<F> >::ret +# define xtd_arg1(F) typename xtd::typedef_::arg1_type::from_<xtd::fun_traits_<F> >::ret +# define xtd_arg2(F) typename xtd::typedef_::arg2_type::from_<xtd::fun_traits_<F> >::ret +# define xtd_arg3(F) typename xtd::typedef_::arg3_type::from_<xtd::fun_traits_<F> >::ret + + + + +namespace xtd +{ + + namespace ERROR + { + struct xtd_fun_traits_SHOULD_DEFINE_arg_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_1; + + struct xtd_fun_traits_SHOULD_DEFINE_arg1_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_2; + struct xtd_fun_traits_SHOULD_DEFINE_arg2_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_2; + + struct xtd_fun_traits_SHOULD_DEFINE_arg1_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3; + struct xtd_fun_traits_SHOULD_DEFINE_arg2_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3; + struct xtd_fun_traits_SHOULD_DEFINE_arg3_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3; + + struct AN_xtd_plain_function_DOES_NOT_ACCEPT_AN_xtd_function_AS_ARGUMENT; + + // FIXME: add error messages corresponding to definitions without sense + // FIXME: such as having arg2 when the plain function is unary + + } // end of namespace xtd::ERROR + + + + mlc_decl_typedef(arg_type); + mlc_decl_typedef(arg1_type); + mlc_decl_typedef(arg2_type); + mlc_decl_typedef(arg3_type); + + + namespace abstract + { + + /*! \class xtd::abstract::plain_nary_fun_<n, E> + ** + ** Abstract base class for plain functions with an explicit number + ** of arguments. + ** + ** Parameter n is the number of arguments with n being 0, 1, 2, or + ** 3. + ** + ** Parameter E is the exact type of the function. + */ + + template <unsigned n, typename E> + class plain_nary_fun_; + + + + /*! \class xtd::abstract::plain_nary_fun_<0, E> + ** + ** Abstract base class for plain functions taking no argument. + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class plain_nary_fun_< 0, E > + + : public plain_fun_<E>, + public nary_fun_<0> + + // FIXME: add many assertions in this class and the following ones + // FIXME: for instance, eq_< xtd_arg(E), mlc::not_found >, etc. + { + public: + + xtd_res(E) operator()() const + { + return this->exact().impl_op(); + } + + protected: + plain_nary_fun_() {} + }; + + + + /*! \class xtd::abstract::plain_nary_fun_<1, E> + ** + ** Abstract base class for plain functions taking one argument. + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class plain_nary_fun_< 1, E > + + : public plain_fun_<E>, + public nary_fun_<1>, + + private mlc::assert_< mlc::neq_<xtd_arg(E), mlc::not_found>, + xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_1 > + { + public: + + xtd_res(E) operator()(const xtd_arg(E)& arg) const + { + return this->exact().impl_op(arg); + } + + template <typename A> + xtd_res(E) operator()(const A& arg) const + { + mlc::assert_< mlc_is_not_a(A, abstract::fun_), + xtd::ERROR::AN_xtd_plain_function_DOES_NOT_ACCEPT_AN_xtd_function_AS_ARGUMENT >::check(); + // FIXME: check that conversion is ok + return this->exact().impl_op(arg); + } + + protected: + plain_nary_fun_() {} + }; + + + + /*! \class xtd::abstract::plain_nary_fun_<2, E> + ** + ** Abstract base class for plain functions taking two arguments. + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class plain_nary_fun_< 2, E > + + : public plain_fun_<E>, + public nary_fun_<2>, + + private mlc::assert_< mlc::neq_<xtd_arg1(E), mlc::not_found>, + xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg1_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_2 >, + + private mlc::assert_< mlc::neq_<xtd_arg2(E), mlc::not_found>, + xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg2_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_2 > + { + public: + + xtd_res(E) operator()(const xtd_arg1(E)& arg1, + const xtd_arg2(E)& arg2) const + { + return this->exact().impl_op(arg1, arg2); + } + + template <typename A1, typename A2> + xtd_res(E) operator()(const A1& arg1, const A2& arg2) const + { + // FIXME: be more specific in the assertions below (and also in the other classes) + mlc::assert_< mlc_is_not_a(A1, abstract::fun_), + xtd::ERROR::AN_xtd_plain_function_DOES_NOT_ACCEPT_AN_xtd_function_AS_ARGUMENT >::check(); + mlc::assert_< mlc_is_not_a(A2, abstract::fun_), + xtd::ERROR::AN_xtd_plain_function_DOES_NOT_ACCEPT_AN_xtd_function_AS_ARGUMENT >::check(); + // FIXME: check that conversions below are ok + return this->exact().impl_op(arg1, arg2); + } + + protected: + plain_nary_fun_() {} + }; + + + + /*! \class xtd::abstract::plain_nary_fun_<3, E> + ** + ** Abstract base class for plain functions taking three arguments. + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class plain_nary_fun_< 3, E > + + : public plain_fun_<E>, + public nary_fun_<3>, + + private mlc::assert_< mlc::neq_<xtd_arg1(E), mlc::not_found>, + xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg1_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3 >, + + private mlc::assert_< mlc::neq_<xtd_arg2(E), mlc::not_found>, + xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg2_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3 >, + + private mlc::assert_< mlc::neq_<xtd_arg3(E), mlc::not_found>, + xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg3_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3 > + { + public: + + xtd_res(E) operator()(const xtd_arg1(E)& arg1, + const xtd_arg2(E)& arg2, + const xtd_arg3(E)& arg3) const + { + return this->exact().impl_op(arg1, arg2, arg3); + } + + template <typename A1, typename A2, typename A3> + xtd_res(E) operator()(const A1& arg1, + const A2& arg2, + const A3& arg3) const + { + mlc::assert_< mlc_is_not_a(A1, abstract::fun_), + xtd::ERROR::AN_xtd_plain_function_DOES_NOT_ACCEPT_AN_xtd_function_AS_ARGUMENT >::check(); + mlc::assert_< mlc_is_not_a(A2, abstract::fun_), + xtd::ERROR::AN_xtd_plain_function_DOES_NOT_ACCEPT_AN_xtd_function_AS_ARGUMENT >::check(); + mlc::assert_< mlc_is_not_a(A3, abstract::fun_), + xtd::ERROR::AN_xtd_plain_function_DOES_NOT_ACCEPT_AN_xtd_function_AS_ARGUMENT >::check(); + // FIXME: check that conversions below are ok + return this->exact().impl_op(arg1, arg2, arg3); + } + + protected: + plain_nary_fun_() {} + }; + + + } // end of namespace xtd::abstract + +} // end of namespace xtd + + + +#endif // ! EXTENDED_ABSTRACT_PLAIN_NARY_FUN_HH Index: xtd/abstract/fun_expr.hh --- xtd/abstract/fun_expr.hh (revision 441) +++ xtd/abstract/fun_expr.hh (working copy) @@ -28,20 +28,9 @@ #ifndef EXTENDED_ABSTRACT_FUN_EXPR_HH # define EXTENDED_ABSTRACT_FUN_EXPR_HH -# include <mlc/flags.hh> -# include <mlc/bool.hh> -# include <mlc/is_a.hh> -# include <mlc/comma.hh> - -# include <xtd/args.hh> +# include <xtd/abstract/fun.hh> # include <xtd/res.hh> -# include <xtd/abstract/meta_fun.hh> - - - -// FIXME: doc - -# define xtd_nargs(F) xtd::internal::get_nargs_<F>::ret +# include <xtd/args.hh> @@ -53,267 +42,45 @@ { struct INTERNAL_ILL_FORMED_CALL_TO_xtd_fun_expr_eval; - struct SPECIALIZATION_OF_xtd_nargs_IS_FOR_xtd_fun_expr_ONLY; - struct SPECIALIZATION_OF_xtd_nargs_NOT_FOUND_FOR_AN_xtd_fun_expr; } // end of namespace xtd::ERROR - - /// Forward declarations. - /// \{ - namespace abstract { - template <typename E> class fun_expr_; - } - - template <typename F, typename Expr1, typename Expr2> - struct m2expr_; - - template <typename F, typename Expr1, typename Expr2, typename Expr3> - struct m3expr_; - - template <typename T> - struct literal_expr_; - - template <unsigned i> - struct arg_; - - /// \} - - - - /*! \class xtd::nargs_<F> - ** - ** FIXME: doc - ** FIXME: and add a mechanism so that the type of F is checked - ** FIXME: Cf. get_res0_ in xtd/abstract/meta_fun.hh - */ - - template <typename F> - struct nargs_ : public mlc::undefined - { - }; - - - namespace internal - { - - template <typename F> - struct get_nargs_ - - : // private mlc::assert_< mlc_is_a(F, xtd::abstract::fun_expr_), - // xtd::ERROR::SPECIALIZATION_OF_xtd_nargs_IS_FOR_xtd_fun_expr_ONLY >, - // FIXME: the static assertion above does *not* compile... - - private mlc::assert_< mlc_is_not_a(xtd::nargs_<F>, mlc::undefined), - xtd::ERROR::SPECIALIZATION_OF_xtd_nargs_NOT_FOUND_FOR_AN_xtd_fun_expr > - { - static const unsigned ret = xtd::nargs_<F>::ret; - }; - } // end of xtd::internal - - - - namespace abstract - { /*! \class xtd::abstract::fun_expr_<E> ** ** Abstract base class for function expressions. Parameter E is ** the exact type of the function expression. - ** - ** Design note: this class does not derive from xtd::abstract::any - ** to avoid diamond inheritance since fun_expr classes are also - ** meta_fun classes. */ template <typename E> class fun_expr_ - // FIXME: at that point, we should verify that nargs_<E> is user-defined... - : public fun_<E> { public: template <typename Args> xtd_expr_res(E, Args) - eval(const Args& as) const + eval(const Args& arglist) const { mlc::assert_< mlc_is_a(Args, xtd::abstract::args), xtd::ERROR::INTERNAL_ILL_FORMED_CALL_TO_xtd_fun_expr_eval >::check(); - return exact_of(this)->impl_eval(as); + return this->exact().impl_eval(arglist); } - protected: - fun_expr_() {} - }; - - - - - - - /*! \class xtd::abstract::nary_fun_expr_<n, E> - ** - ** Abstract base class for function expressions with an explicit - ** number of arguments. - ** - ** Parameter n is the number of arguments with n being 0, 1, 2, or - ** 3. - ** - ** Parameter E is the exact type of the function. - */ - - template <unsigned n, typename E> - class nary_fun_expr_; - - - - /*! \class xtd::abstract::nary_fun_expr_<0, E> - ** - ** Abstract base class for function expressions taking no - ** argument. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class nary_fun_expr_< 0, E > - - : public fun_expr_<E>, - public meta_nary_fun_<0, E> + unsigned nargs() const { - public: - - // the return type here is not xtd_res_0(E) - // the explanations are given with meta_nary_fun_<0, E>::operator()() - // in file xtd/abstract/meta_fun.hh - - xtd_internal_res_0(E) - impl_calc() const - { - return this->eval(mk_args()); - } - - // no bind_i method here - - protected: - nary_fun_expr_() {} - }; - - - - /*! \class xtd::abstract::nary_fun_expr_<1, E> - ** - ** Abstract base class for function expressions taking one - ** argument. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class nary_fun_expr_< 1, E > - - : public fun_expr_<E>, - public meta_nary_fun_<1, E> - { - public: - - template <typename A> - xtd_res_1(E, A) - impl_calc(const A& a) const - { - return this->eval(mk_args(a)); - } - - // no bind_i method here - - protected: - nary_fun_expr_() {} - }; - - - - /*! \class xtd::abstract::nary_fun_expr_<2, E> - ** - ** Abstract base class for function expressions taking two - ** arguments. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class nary_fun_expr_< 2, E > - - : public fun_expr_<E>, - public meta_nary_fun_<2, E> - { - public: - - template <typename A1, typename A2> - xtd_res_2(E, A1, A2) - impl_calc(const A1& a1, const A2& a2) const - { - return this->eval(mk_args(a1, a2)); - } - - template <typename T> - m2expr_< E, literal_expr_<T>, arg_<2> > - bind_1(const T& value) const; - - template <typename T> - m2expr_< E, arg_<1>, literal_expr_<T> > - bind_2(const T& value) const; - - protected: - nary_fun_expr_() {} - }; - - - - /*! \class xtd::abstract::nary_fun_expr_<3, E> - ** - ** Abstract base class for function expressions taking three - ** arguments. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class nary_fun_expr_< 3, E > - - : public fun_expr_<E>, - public meta_nary_fun_<3, E> - { - public: - - template <typename A1, typename A2, typename A3> - xtd_res_3(E, A1, A2, A3) - impl_calc(const A1& a1, const A2& a2, const A3& a3) const - { - return this->eval(mk_args(a1, a2, a3)); + return xtd_nargs(E); } - template <typename T> - m3expr_< E, literal_expr_<T>, arg_<2>, arg_<3> > - bind_1(const T& value) const; - - template <typename T> - m3expr_< E, arg_<1>, literal_expr_<T>, arg_<3> > - bind_2(const T& value) const; - - template <typename T> - m3expr_< E, arg_<1>, arg_<2>, literal_expr_<T> > - bind_3(const T& value) const; - protected: - nary_fun_expr_() {} + fun_expr_() {} }; Index: xtd/abstract/meta_nary_fun.hh --- xtd/abstract/meta_nary_fun.hh (revision 0) +++ xtd/abstract/meta_nary_fun.hh (revision 0) @@ -0,0 +1,143 @@ +// Copyright (C) 2002, 2005, 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, 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 EXTENDED_ABSTRACT_META_NARY_FUN_HH +# define EXTENDED_ABSTRACT_META_NARY_FUN_HH + +# include <xtd/abstract/meta_fun.hh> +# include <xtd/abstract/open_nary_fun.hh> + + + +namespace xtd +{ + + namespace abstract + { + + + /*! \class xtd::abstract::meta_nary_fun_<n, E> + ** + ** Abstract base class for meta functions with an explicit number + ** of arguments. + ** + ** Parameter n is the number of arguments with n being 1, 2, or 3. + ** + ** Parameter E is the exact type of the function. + */ + + template <unsigned n, typename E> + class meta_nary_fun_; + + + + /*! \class xtd::abstract::meta_nary_fun_<0, E> + ** + ** Abstract base class for meta functions taking no argument. + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class meta_nary_fun_< 0, E > + + : public meta_fun_<E>, + public open_nary_fun_<0, E> + { + protected: + meta_nary_fun_() {} + }; + + + + /*! \class xtd::abstract::meta_nary_fun_<1, E> + ** + ** Abstract base class for meta functions taking one argument. + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class meta_nary_fun_< 1, E > + + : public meta_fun_<E>, + public open_nary_fun_<1, E> + { + protected: + meta_nary_fun_() {} + }; + + + + /*! \class xtd::abstract::meta_nary_fun_<2, E> + ** + ** Abstract base class for meta functions taking two arguments. + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class meta_nary_fun_< 2, E > + + : public meta_fun_<E>, + public open_nary_fun_<2, E> + { + protected: + meta_nary_fun_() {} + }; + + + + /*! \class xtd::abstract::meta_nary_fun_<3, E> + ** + ** Abstract base class for meta functions taking three arguments. + ** This class is defined as a specialization. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class meta_nary_fun_< 3, E > + + : public meta_fun_<E>, + public open_nary_fun_<3, E> + { + protected: + meta_nary_fun_() {} + }; + + + } // end of namespace xtd::abstract + +} // end of namespace xtd + + + +#endif // ! EXTENDED_ABSTRACT_META_NARY_FUN_HH Index: xtd/abstract/fun.hh --- xtd/abstract/fun.hh (revision 441) +++ xtd/abstract/fun.hh (working copy) @@ -28,6 +28,8 @@ #ifndef EXTENDED_ABSTRACT_FUN_HH # define EXTENDED_ABSTRACT_FUN_HH +# include <xtd/internal/mlc.hh> + namespace xtd { @@ -44,6 +46,13 @@ template <typename E> class fun_ { + public: + + const E& exact() const + { + return *(const E*)(const void*)(this); + } + protected: fun_() {} }; @@ -52,22 +61,6 @@ } // end of namespace xtd::abstract - - // FIXME: doc - - template <typename E> - const E* exact_of(const abstract::fun_<E>* f) - { - return (const E*)(const void*)(f); - } - - template <typename E> - const E& exact_of(const abstract::fun_<E>& f) - { - return *(const E*)(const void*)(&f); - } - - } // end of namespace xtd Index: xtd/abstract/open_fun.hh --- xtd/abstract/open_fun.hh (revision 0) +++ xtd/abstract/open_fun.hh (revision 0) @@ -0,0 +1,71 @@ +// Copyright (C) 2002, 2005, 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, 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 EXTENDED_ABSTRACT_OPEN_FUN_HH +# define EXTENDED_ABSTRACT_OPEN_FUN_HH + +# include <xtd/internal/mlc.hh> + + +namespace xtd +{ + + namespace abstract + { + + /*! \class xtd::abstract::open_fun_<E> + ** + ** FIXME: doc + ** + ** Parameter n is the number of arguments with n being 1, 2, or 3. + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class open_fun_ + { + protected: + + open_fun_() + {} + + public: + + const E& exact_() const + { + return *(const E*)(const void*)(this); + } + }; + + + } // end of namespace xtd::abstract + +} // end of namespace xtd + + + +#endif // ! EXTENDED_ABSTRACT_OPEN_FUN_HH Index: xtd/abstract/plain_fun.hh --- xtd/abstract/plain_fun.hh (revision 441) +++ xtd/abstract/plain_fun.hh (working copy) @@ -28,24 +28,10 @@ #ifndef EXTENDED_ABSTRACT_PLAIN_FUN_HH # define EXTENDED_ABSTRACT_PLAIN_FUN_HH -# include <mlc/flags.hh> -# include <mlc/assert.hh> -# include <mlc/is_a.hh> -# include <mlc/typedef.hh> -# include <mlc/assert.hh> -# include <mlc/abort.hh> - # include <xtd/abstract/fun.hh> -# include <xtd/abstract/nary_fun.hh> - - -// macros -# define xtd_arg(F) typename xtd::typedef_::arg_type::from_<xtd::fun_traits_<F> >::ret -# define xtd_arg1(F) typename xtd::typedef_::arg1_type::from_<xtd::fun_traits_<F> >::ret -# define xtd_arg2(F) typename xtd::typedef_::arg2_type::from_<xtd::fun_traits_<F> >::ret -# define xtd_arg3(F) typename xtd::typedef_::arg3_type::from_<xtd::fun_traits_<F> >::ret +// macro # define xtd_res(F) typename xtd::typedef_::res_type::from_<xtd::fun_traits_<F> >::ret @@ -59,25 +45,8 @@ { struct SPECIALIZATION_OF_xtd_fun_traits_NOT_FOUND_FOR_AN_xtd_plain_fun; struct xtd_fun_traits_SHOULD_DEFINE_res_type_FOR_AN_xtd_plain_fun; - - struct xtd_fun_traits_SHOULD_DEFINE_arg_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_1; - - struct xtd_fun_traits_SHOULD_DEFINE_arg1_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_2; - struct xtd_fun_traits_SHOULD_DEFINE_arg2_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_2; - - struct xtd_fun_traits_SHOULD_DEFINE_arg1_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3; - struct xtd_fun_traits_SHOULD_DEFINE_arg2_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3; - struct xtd_fun_traits_SHOULD_DEFINE_arg3_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3; - struct YOU_SHOULD_NOT_DERIVE_FROM_xtd_plain_fun_BUT_FROM_xtd_plain_nary_fun; - struct FIXME; - - struct AN_xtd_plain_function_DOES_NOT_ACCEPT_AN_xtd_function_AS_ARGUMENT; - - // FIXME: add error messages corresponding to definitions without sense - // FIXME: such as having arg2 when the plain function is unary - } // end of namespace xtd::ERROR @@ -85,31 +54,15 @@ template <typename F> struct fun_traits_ : public mlc::undefined { - // nothing }; - mlc_decl_typedef(arg_type); - - mlc_decl_typedef(arg1_type); - mlc_decl_typedef(arg2_type); - mlc_decl_typedef(arg3_type); - mlc_decl_typedef(res_type); namespace abstract { - /// Forward declarations. - /// \{ - template <unsigned n, typename E> class plain_nary_fun_; - template <typename E> class meta_fun_; - template <typename E> class fun_expr_; - /// \} - - - /*! \class xtd::abstract::plain_fun_ ** ** Abstract base class for plain functions. Parameter E is the @@ -137,153 +90,6 @@ }; - /*! \class xtd::abstract::plain_nary_fun_<n, E> - ** - ** Abstract base class for plain functions with an explicit number - ** of arguments. - ** - ** Parameter n is the number of arguments with n being 0, 1, 2, or - ** 3. - ** - ** Parameter E is the exact type of the function. - */ - - template <unsigned n, typename E> - class plain_nary_fun_; - - - - /*! \class xtd::abstract::plain_nary_fun_<0, E> - ** - ** Abstract base class for plain functions taking no argument. - ** This class is defined as a specialization. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class plain_nary_fun_< 0, E > - - : public plain_fun_<E>, - public nary_fun_<0> - { - public: - - xtd_res(E) operator()() const - { - return exact_of(this)->impl_op(); - } - - protected: - plain_nary_fun_() {} - }; - - - - /*! \class xtd::abstract::plain_nary_fun_<1, E> - ** - ** Abstract base class for plain functions taking one argument. - ** This class is defined as a specialization. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class plain_nary_fun_< 1, E > - - : public plain_fun_<E>, - public nary_fun_<1>, - - private mlc::assert_< mlc::neq_<xtd_arg(E), mlc::not_found>, - xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_1 > - { - public: - - template <typename F> - void operator()(const abstract::fun_<F>&) const - { - mlc::abort_< F, - xtd::ERROR::AN_xtd_plain_function_DOES_NOT_ACCEPT_AN_xtd_function_AS_ARGUMENT >::check(); - } - - xtd_res(E) operator()(const xtd_arg(E)& arg) const - { - return exact_of(this)->impl_op(arg); - } - - protected: - plain_nary_fun_() {} - }; - - - - /*! \class xtd::abstract::plain_nary_fun_<2, E> - ** - ** Abstract base class for plain functions taking two arguments. - ** This class is defined as a specialization. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class plain_nary_fun_< 2, E > - - : public plain_fun_<E>, - public nary_fun_<2>, - - private mlc::assert_< mlc::neq_<xtd_arg1(E), mlc::not_found>, - xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg1_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_2 >, - - private mlc::assert_< mlc::neq_<xtd_arg2(E), mlc::not_found>, - xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg2_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_2 > - { - public: - xtd_res(E) operator()(const xtd_arg1(E)& arg1, - const xtd_arg2(E)& arg2) const - { - return exact_of(this)->impl_op(arg1, arg2); - } - protected: - plain_nary_fun_() {} - }; - - - - /*! \class xtd::abstract::plain_nary_fun_<3, E> - ** - ** Abstract base class for plain functions taking three arguments. - ** This class is defined as a specialization. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class plain_nary_fun_< 3, E > - - : public plain_fun_<E>, - public nary_fun_<3>, - - private mlc::assert_< mlc::neq_<xtd_arg1(E), mlc::not_found>, - xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg1_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3 >, - - private mlc::assert_< mlc::neq_<xtd_arg2(E), mlc::not_found>, - xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg2_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3 >, - - private mlc::assert_< mlc::neq_<xtd_arg3(E), mlc::not_found>, - xtd::ERROR::xtd_fun_traits_SHOULD_DEFINE_arg3_type_FOR_AN_xtd_plain_nary_fun_WITH_n_BEING_3 > - { - public: - xtd_res(E) operator()(const xtd_arg1(E)& arg1, - const xtd_arg2(E)& arg2, - const xtd_arg3(E)& arg3) const - { - return exact_of(this)->impl_op(arg1, arg2, arg3); - } - protected: - plain_nary_fun_() {} - }; - - } // end of namespace xtd::abstract } // end of namespace xtd Index: xtd/abstract/meta_fun.hh --- xtd/abstract/meta_fun.hh (revision 441) +++ xtd/abstract/meta_fun.hh (working copy) @@ -28,108 +28,20 @@ #ifndef EXTENDED_ABSTRACT_META_FUN_HH # define EXTENDED_ABSTRACT_META_FUN_HH -# include <mlc/flags.hh> -# include <mlc/pair.hh> -# include <mlc/valist.hh> - # include <xtd/abstract/fun.hh> -# include <xtd/abstract/nary_fun.hh> -# include <xtd/args.hh> -# include <xtd/res.hh> -# include <xtd/case.hh> - - -// macros - namespace xtd { namespace ERROR { - struct ARG_SHOULD_NOT_BE_A_PLAIN_FUN; - struct ARG1_SHOULD_NOT_BE_A_PLAIN_FUN; - struct ARG2_SHOULD_NOT_BE_A_PLAIN_FUN; - struct ARG3_SHOULD_NOT_BE_A_PLAIN_FUN; - - struct ARG_SHOULD_NOT_BE_A_META_NON_EXPR_FUN; - struct ARG1_SHOULD_NOT_BE_A_META_NON_EXPR_FUN; - struct ARG2_SHOULD_NOT_BE_A_META_NON_EXPR_FUN; - struct ARG3_SHOULD_NOT_BE_A_META_NON_EXPR_FUN; - - }// end of namespace xtd - - - - // FIXME: document case stuff... - - namespace tag - { - - struct meta_1ary_fun_operator; - struct meta_2ary_fun_operator; - struct meta_3ary_fun_operator; - - } // end of namespace xtd::tag - - - // meta_nary_fun_<1, E>::operator()(const A& a) const - - template <typename E, typename A> - struct default_case_ < tag::meta_1ary_fun_operator, - mlc::pair_<E, A> > - { - typedef xtd_res_1(E, A) res; + struct YOU_SHOULD_NOT_DERIVE_DIRECTLY_FROM_xtd_meta_fun_BUT_FROM_xtd_meta_nary_fun_; - static res impl(const abstract::meta_nary_fun_<1, E>* this_, - const A& a) - { - return exact_of(this_)->impl_calc(a); - } - }; + } // end of namespace xtd::ERROR - // meta_nary_fun_<2, E>::operator()(const A1& a1, const A2& a2) const - - template <typename E, typename A1, typename A2> - struct default_case_ < tag::meta_2ary_fun_operator, - mlc::valist_<E, A1, A2> > - { - typedef xtd_res_2(E, A1, A2) res; - - static res impl(const abstract::meta_nary_fun_<2, E>* this_, - const A1& a1, const A2& a2) - { - return exact_of(this_)->impl_calc(a1, a2); - } - }; - - - // meta_nary_fun_<3, E>::operator()(const A1& a1, const A2& a2, const A3& a3) const - - template <typename E, typename A1, typename A2, typename A3> - struct default_case_ < tag::meta_3ary_fun_operator, - mlc::valist_<E, A1, A2, A3> > - { - typedef xtd_res_3(E, A1, A2, A3) res; - - static res impl(const abstract::meta_nary_fun_<3, E>* this_, - const A1& a1, const A2& a2, const A3& a3) - { - return exact_of(this_)->impl_calc(a1, a2, a3); - } - }; - - -} // end of namespace xtd - - - - -namespace xtd -{ namespace abstract { @@ -157,206 +69,6 @@ }; - /*! \class xtd::abstract::meta_nary_fun_<n, E> - ** - ** Abstract base class for meta functions with an explicit number - ** of arguments. - ** - ** Parameter n is the number of arguments with n being 1, 2, or 3. - ** - ** Parameter E is the exact type of the function. - */ - - template <unsigned n, typename E> - class meta_nary_fun_; - - - - /*! \class xtd::abstract::meta_nary_fun_<0, E> - ** - ** Abstract base class for meta functions taking no argument. - ** This class is defined as a specialization. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class meta_nary_fun_< 0, E > - - : public meta_fun_<E>, - public nary_fun_<0> - { - public: - - /* - ** This member is not templated so its behavior at compile-time - ** is different than meta_nary_fun_<n,E>::operator() where n > - ** 0. Here the return type should be known before the hierarchy - ** classes are fully compiled thus static assertions in the - ** macro xtd_res_0 do *not* work. An alternate macro is thus - ** in use. - */ - - xtd_internal_res_0(E) - operator()() const - { - return exact_of(this)->impl_calc(); - } - - protected: - meta_nary_fun_() {} - }; - - - - /*! \class xtd::abstract::meta_nary_fun_<1, E> - ** - ** Abstract base class for meta functions taking one argument. - ** This class is defined as a specialization. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class meta_nary_fun_< 1, E > - - : public meta_fun_<E>, - public nary_fun_<1> - { - public: - - template <typename A> - struct case_ - - : private mlc::assert_< mlc_is_not_a(A, xtd::abstract::plain_fun_), - xtd::ERROR::ARG_SHOULD_NOT_BE_A_PLAIN_FUN >, - - private mlc::assert_< mlc::implies_< mlc_is_a(A, xtd::abstract::meta_fun_), - mlc_is_a(A, xtd::abstract::fun_expr_) >, - xtd::ERROR::ARG_SHOULD_NOT_BE_A_META_NON_EXPR_FUN >, - - public xtd::case_< xtd::tag::meta_1ary_fun_operator, - mlc::pair_<E, A> >::ret - {}; - - template <typename A> - typename case_<A>::res - operator()(const A& a) const - { - return case_<A>::impl(this, a); - } - - protected: - meta_nary_fun_() {} - }; - - - - /*! \class xtd::abstract::meta_nary_fun_<2, E> - ** - ** Abstract base class for meta functions taking two arguments. - ** This class is defined as a specialization. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class meta_nary_fun_< 2, E > - - : public meta_fun_<E>, - public nary_fun_<2> - { - public: - - template <typename A1, typename A2> - struct case_ - - : private mlc::assert_< mlc_is_not_a(A1, xtd::abstract::plain_fun_), - xtd::ERROR::ARG1_SHOULD_NOT_BE_A_PLAIN_FUN >, - - private mlc::assert_< mlc::implies_< mlc_is_a(A1, xtd::abstract::meta_fun_), - mlc_is_a(A1, xtd::abstract::fun_expr_) >, - xtd::ERROR::ARG1_SHOULD_NOT_BE_A_META_NON_EXPR_FUN >, - - private mlc::assert_< mlc_is_not_a(A2, xtd::abstract::plain_fun_), - xtd::ERROR::ARG2_SHOULD_NOT_BE_A_PLAIN_FUN >, - - private mlc::assert_< mlc::implies_< mlc_is_a(A2, xtd::abstract::meta_fun_), - mlc_is_a(A2, xtd::abstract::fun_expr_) >, - xtd::ERROR::ARG2_SHOULD_NOT_BE_A_META_NON_EXPR_FUN >, - - public xtd::case_< xtd::tag::meta_2ary_fun_operator, - mlc::valist_<E, A1, A2> >::ret - {}; - - template <typename A1, typename A2> - typename case_<A1, A2>::res - operator()(const A1& a1, const A2& a2) const - { - return case_<A1, A2>::impl(this, a1, a2); - } - - protected: - meta_nary_fun_() {} - }; - - - /*! \class xtd::abstract::meta_nary_fun_<3, E> - ** - ** Abstract base class for meta functions taking three arguments. - ** This class is defined as a specialization. - ** - ** Parameter E is the exact type of the function. - */ - - template <typename E> - class meta_nary_fun_< 3, E > - - : public meta_fun_<E>, - public nary_fun_<3> - { - public: - - template <typename A1, typename A2, typename A3> - struct case_ - - : private mlc::assert_< mlc_is_not_a(A1, xtd::abstract::plain_fun_), - xtd::ERROR::ARG1_SHOULD_NOT_BE_A_PLAIN_FUN >, - - private mlc::assert_< mlc::implies_< mlc_is_a(A1, xtd::abstract::meta_fun_), - mlc_is_a(A1, xtd::abstract::fun_expr_) >, - xtd::ERROR::ARG1_SHOULD_NOT_BE_A_META_NON_EXPR_FUN >, - - private mlc::assert_< mlc_is_not_a(A2, xtd::abstract::plain_fun_), - xtd::ERROR::ARG2_SHOULD_NOT_BE_A_PLAIN_FUN >, - - private mlc::assert_< mlc::implies_< mlc_is_a(A2, xtd::abstract::meta_fun_), - mlc_is_a(A2, xtd::abstract::fun_expr_) >, - xtd::ERROR::ARG2_SHOULD_NOT_BE_A_META_NON_EXPR_FUN >, - - private mlc::assert_< mlc_is_not_a(A3, xtd::abstract::plain_fun_), - xtd::ERROR::ARG3_SHOULD_NOT_BE_A_PLAIN_FUN >, - - private mlc::assert_< mlc::implies_< mlc_is_a(A3, xtd::abstract::meta_fun_), - mlc_is_a(A3, xtd::abstract::fun_expr_) >, - xtd::ERROR::ARG3_SHOULD_NOT_BE_A_META_NON_EXPR_FUN >, - - public xtd::case_< xtd::tag::meta_3ary_fun_operator, - mlc::valist_<E, A1, A2, A3> >::ret - {}; - - template <typename A1, typename A2, typename A3> - typename case_<A1, A2, A3>::res - operator()(const A1& a1, const A2& a2, const A3& a3) const - { - return case_<A1, A2, A3>::impl(this, a1, a2, a3); - } - - protected: - meta_nary_fun_() {} - }; - - } // end of namespace xtd::abstract } // end of namespace xtd Index: xtd/abstract/fun_nary_expr.hh --- xtd/abstract/fun_nary_expr.hh (revision 0) +++ xtd/abstract/fun_nary_expr.hh (revision 0) @@ -0,0 +1,234 @@ +// Copyright (C) 2002, 2005, 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, 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 EXTENDED_ABSTRACT_FUN_NARY_EXPR_HH +# define EXTENDED_ABSTRACT_FUN_NARY_EXPR_HH + +# include <xtd/abstract/fun_expr.hh> +# include <xtd/abstract/open_nary_fun.hh> + + + +namespace xtd +{ + + + /// Forward declarations. + /// \{ + + template <typename F, typename Expr1, typename Expr2> + struct m2expr_; + + template <typename F, typename Expr1, typename Expr2, typename Expr3> + struct m3expr_; + + template <typename T> + struct literal_expr_; + + template <unsigned i> + struct arg_; + + /// \} + + + + + namespace abstract + { + + /*! \class xtd::abstract::fun_nary_expr_<n, E> + ** + ** Abstract base class for function expressions with an explicit + ** number of arguments. + ** + ** For "open_nary_fun_<n, E>::operator()(arg1,...)" we provide + ** "::impl_calc(arg1,...)". This method first packs the argument list: + ** precisely "(arg1,...)" becomes "(arglist)" where the type of + ** "arglist" is "args_<Arg1,...>". Then the computation is delegated + ** to "fun_expr_<E>::eval(arglist)". + ** + ** Parameter n is the number of arguments with n being 0, 1, 2, or + ** 3. Parameter E is the exact type of the function. + */ + + template <unsigned n, typename E> + class fun_nary_expr_; + + + + /*! \class xtd::abstract::fun_nary_expr_<0, E> + ** + ** Abstract base class for function expressions taking no + ** argument. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class fun_nary_expr_< 0, E > + + : public fun_expr_<E>, + public open_nary_fun_<0, E> + { + public: + + // the return type here is not xtd_res_0(E) + // the explanations are given with meta_nary_fun_<0, E>::operator()() + // in file xtd/abstract/meta_fun.hh + + xtd_internal_res_0(E) + impl_calc() const + { + return this->eval(mk_args()); + } + + // no bind_i method here + + protected: + fun_nary_expr_() {} + }; + + + + /*! \class xtd::abstract::fun_nary_expr_<1, E> + ** + ** Abstract base class for function expressions taking one + ** argument. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class fun_nary_expr_< 1, E > + + : public fun_expr_<E>, + public open_nary_fun_<1, E> + { + public: + + template <typename A> + xtd_res_1(E, A) + impl_calc(const A& a) const + { + return this->eval(mk_args(a)); + } + + // no bind_i method here + + protected: + fun_nary_expr_() {} + }; + + + + /*! \class xtd::abstract::fun_nary_expr_<2, E> + ** + ** Abstract base class for function expressions taking two + ** arguments. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class fun_nary_expr_< 2, E > + + : public fun_expr_<E>, + public open_nary_fun_<2, E> + { + public: + + template <typename A1, typename A2> + xtd_res_2(E, A1, A2) + impl_calc(const A1& a1, const A2& a2) const + { + return this->eval(mk_args(a1, a2)); + } + + template <typename T> + m2expr_< E, literal_expr_<T>, arg_<2> > + bind_1(const T& value) const; + + template <typename T> + m2expr_< E, arg_<1>, literal_expr_<T> > + bind_2(const T& value) const; + + protected: + fun_nary_expr_() {} + }; + + + + /*! \class xtd::abstract::fun_nary_expr_<3, E> + ** + ** Abstract base class for function expressions taking three + ** arguments. + ** + ** Parameter E is the exact type of the function. + */ + + template <typename E> + class fun_nary_expr_< 3, E > + + : public fun_expr_<E>, + public open_nary_fun_<3, E> + { + public: + + template <typename A1, typename A2, typename A3> + xtd_res_3(E, A1, A2, A3) + impl_calc(const A1& a1, const A2& a2, const A3& a3) const + { + return this->eval(mk_args(a1, a2, a3)); + } + + template <typename T> + m3expr_< E, literal_expr_<T>, arg_<2>, arg_<3> > + bind_1(const T& value) const; + + template <typename T> + m3expr_< E, arg_<1>, literal_expr_<T>, arg_<3> > + bind_2(const T& value) const; + + template <typename T> + m3expr_< E, arg_<1>, arg_<2>, literal_expr_<T> > + bind_3(const T& value) const; + + protected: + fun_nary_expr_() {} + }; + + + } // end of namespace xtd::abstract + + +} // end of namespace xtd + + +# include <xtd/bind.hh> + + +#endif // ! EXTENDED_ABSTRACT_FUN_NARY_EXPR_HH Index: xtd/mfun.hh --- xtd/mfun.hh (revision 441) +++ xtd/mfun.hh (working copy) @@ -28,12 +28,8 @@ #ifndef EXTENDED_MFUN_HH # define EXTENDED_MFUN_HH -# include <mlc/assert.hh> -# include <mlc/logic.hh> -# include <mlc/is_a.hh> - # include <xtd/abstract/plain_fun.hh> -# include <xtd/abstract/meta_fun.hh> +# include <xtd/abstract/meta_nary_fun.hh> Index: xtd/TODO --- xtd/TODO (revision 0) +++ xtd/TODO (revision 0) @@ -0,0 +1,5 @@ + -*- outline -*- + +* files + +xtd/res.hh -> xtd/internal/res.hh ? Index: xtd/arg.hh --- xtd/arg.hh (revision 441) +++ xtd/arg.hh (working copy) @@ -28,12 +28,7 @@ #ifndef EXTENDED_ARG_HH # define EXTENDED_ARG_HH -# include <mlc/assert.hh> -# include <mlc/is_a.hh> - -# include <xtd/args.hh> -# include <xtd/mexpr.hh> - +# include <xtd/abstract/fun_nary_expr.hh> namespace xtd @@ -122,7 +117,7 @@ template <unsigned i> struct arg_ - : public abstract::nary_fun_expr_< i, arg_<i> >, + : public abstract::fun_nary_expr_< i, arg_<i> >, public internal::impl_arg_<i> Index: xtd/bind.hh --- xtd/bind.hh (revision 0) +++ xtd/bind.hh (revision 0) @@ -0,0 +1,105 @@ +// Copyright (C) 2002, 2005, 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, 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 EXTENDED_BIND_HH +# define EXTENDED_BIND_HH + +# include <xtd/abstract/fun_nary_expr.hh> +# include <xtd/literal.hh> +# include <xtd/mexpr.hh> +# include <xtd/arg.hh> + + +namespace xtd +{ + + + namespace abstract + { + + // fun_nary_expr_< 2, E >::bind_i + + template <typename E> + template <typename T> + m2expr_< E, literal_expr_<T>, arg_<2> > + fun_nary_expr_< 2, E >::bind_1(const T& value) const + { + typedef m2expr_< E, literal_expr_<T>, arg_<2> > ret; + ret tmp(this->exact(), lit(value), arg_<2>()); + return tmp; + } + + template <typename E> + template <typename T> + m2expr_< E, arg_<1>, literal_expr_<T> > + fun_nary_expr_< 2, E >::bind_2(const T& value) const + { + typedef m2expr_< E, arg_<1>, literal_expr_<T> > ret; + ret tmp(this->exact(), arg_<1>(), lit(value)); + return tmp; + } + + + // fun_nary_expr_< 3, E >::bind_i + + template <typename E> + template <typename T> + m3expr_< E, literal_expr_<T>, arg_<2>, arg_<3> > + fun_nary_expr_< 3, E >::bind_1(const T& value) const + { + typedef m3expr_< E, literal_expr_<T>, arg_<2>, arg_<3> > ret; + ret tmp(this->exact(), lit(value), arg_<2>(), arg_<3>()); + return tmp; + } + + template <typename E> + template <typename T> + m3expr_< E, arg_<1>, literal_expr_<T>, arg_<3> > + fun_nary_expr_< 3, E >::bind_2(const T& value) const + { + typedef m3expr_< E, arg_<1>, literal_expr_<T>, arg_<3> > ret; + ret tmp(this->exact(), arg_<1>(), lit(value), arg_<3>()); + return tmp; + } + + template <typename E> + template <typename T> + m3expr_< E, arg_<1>, arg_<2>, literal_expr_<T> > + fun_nary_expr_< 3, E >::bind_3(const T& value) const + { + typedef m3expr_< E, arg_<1>, arg_<2>, literal_expr_<T> > ret; + ret tmp(this->exact(), arg_<1>(), arg_<2>(), lit(value)); + return tmp; + } + + } // end of namespace xtd::abstract + +} // end of namespace xtd + + + +#endif // ! EXTENDED_BIND_HH Index: xtd/internal/mlc.hh --- xtd/internal/mlc.hh (revision 0) +++ xtd/internal/mlc.hh (revision 0) @@ -0,0 +1,54 @@ +// Copyright (C) 2002, 2005, 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, 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 EXTENDED_INTERNAL_MLC_HH +# define EXTENDED_INTERNAL_MLC_HH + +# include <mlc/flags.hh> +# include <mlc/comma.hh> + +# include <mlc/typedef.hh> +# include <mlc/ret.hh> + +# include <mlc/assert.hh> +# include <mlc/is_a.hh> +# include <mlc/logic.hh> +# include <mlc/cmp.hh> +# include <mlc/if.hh> + +# include <mlc/pair.hh> +# include <mlc/valist.hh> + + + + +# include <mlc/case.hh> + +mlc_case_equipment_for_namespace(xtd); + + +#endif // ! EXTENDED_INTERNAL_MLC_HH Index: tests/id.cc --- tests/id.cc (revision 441) +++ tests/id.cc (working copy) @@ -1,6 +1,5 @@ #include <iostream> - #include <xtd/math/id.hh> Index: tests/bind.cc --- tests/bind.cc (revision 441) +++ tests/bind.cc (working copy) @@ -13,9 +13,9 @@ (_1 + _2)(_1, lit(1.f)); - (_1 + _2).bind_2(1.f); + ; - std::cout << (_1 + _2)(5., 1.) << std::endl; + std::cout << (_1 + _2) .bind_2(2.6f) (2.5f) << std::endl; // std::cout << (_1 + _2)(_1, 1.)(5.) << std::endl; Index: tests/lit.cc --- tests/lit.cc (revision 441) +++ tests/lit.cc (working copy) @@ -1,4 +1,5 @@ #include <iostream> + #include <xtd/literal.hh>