
https://svn.lrde.epita.fr/svn/oln/trunk/extended Index: ChangeLog from Thierry Geraud <theo@lrde.epita.fr> Fix some icpc remarks and update operator traits. * xtd/res.hh (macros): Add spaces to fix pb with icpc preproc. * xtd/args.hh (xtd_nargs): Likewise. * xtd/math/abs.hh (internal::int_): Handwrite code. * xtd/math/pow.hh: Cosmetics. * xtd/math/arith.hh: Add comments. * xtd/literal.hh (argument): Remove reference so that temporaries are copied. * xtd/abstract/fun_nary_expr.hh: Likewise. * xtd/bind.hh: Likewise. * xtd/abstract/any.hh: Remove cause obsolete. * xtd/abstract/fun.hh: Add doc. (abstract::fun_): Disable imperative operators. * xtd/abstract/plain_fun.hh: Add doc. * xtd/optraits.hh: Rewrite. * xtd/traits.hh: New. * xtd/builtin/traits.hh: Replace dummy code by effective one. * xtd/internal/opmacros.hh: Rewrite. * xtd/internal/mlc.hh: Add include. * tests: Add ignore rule for '.deps'. * tests/cfun.cc: Fix icpc remark. * tests/abs.cc: New. * tests/optraits.cc: New. * tests/Makefile.am: Update. * tests/bi_traits: New directory to test builtin op traits. * tests/bi_traits/bool.cc: New. * tests/bi_traits/char.cc: New. * tests/bi_traits/sint.cc: New. * tests/bi_traits/uint.cc: New. * tests/bi_traits/schar.cc: New. * tests/bi_traits/slong.cc: New. * tests/bi_traits/uchar.cc: New. * tests/bi_traits/sshort.cc: New. * tests/bi_traits/ulong.cc: New. * tests/bi_traits/ushort.cc: New. * tests/bi_traits/float.cc: New. * tests/bi_traits/ldouble.cc: New. * tests/bi_traits/double.cc: New. tests/Makefile.am | 10 + tests/abs.cc | 13 ++ tests/bi_traits/bool.cc | 48 ++++++++ tests/bi_traits/char.cc | 48 ++++++++ tests/bi_traits/double.cc | 48 ++++++++ tests/bi_traits/float.cc | 48 ++++++++ tests/bi_traits/ldouble.cc | 48 ++++++++ tests/bi_traits/schar.cc | 48 ++++++++ tests/bi_traits/sint.cc | 48 ++++++++ tests/bi_traits/slong.cc | 48 ++++++++ tests/bi_traits/sshort.cc | 48 ++++++++ tests/bi_traits/uchar.cc | 48 ++++++++ tests/bi_traits/uint.cc | 48 ++++++++ tests/bi_traits/ulong.cc | 48 ++++++++ tests/bi_traits/ushort.cc | 48 ++++++++ tests/cfun.cc | 4 tests/optraits.cc | 33 ++++++ xtd/abstract/fun.hh | 42 +++++++ xtd/abstract/fun_nary_expr.hh | 10 - xtd/abstract/plain_fun.hh | 32 +++++ xtd/bind.hh | 10 - xtd/builtin/traits.hh | 194 ++++++++++++++++++++++------------- xtd/internal/mlc.hh | 1 xtd/internal/opmacros.hh | 87 ++++++++++++--- xtd/literal.hh | 8 - xtd/math/abs.hh | 10 - xtd/math/arith.hh | 1 xtd/math/pow.hh | 1 xtd/optraits.hh | 229 +++++++++++++++++++++++++++--------------- xtd/traits.hh | 74 +++++++++++++ 30 files changed, 1186 insertions(+), 197 deletions(-) Index: xtd/res.hh Index: xtd/math/abs.hh --- xtd/math/abs.hh (revision 456) +++ xtd/math/abs.hh (working copy) @@ -56,12 +56,12 @@ namespace internal { - int abs_(int i) { return std::abs(i); } - long int abs_(long int i) { return std::abs(i); } + int abs_(int x) { return x < 0 ? -x : x; } + long int abs_(long int x) { return x < 0 ? -x : x; } - float abs_(float i) { return std::fabs(i); } - double abs_(double i) { return std::fabs(i); } - long double abs_(long double i) { return std::fabs(i); } + float abs_(float x) { return std::abs(x); } + double abs_(double x) { return std::abs(x); } + long double abs_(long double x) { return std::abs(x); } } // end of namespace xtd::internal Index: xtd/math/pow.hh --- xtd/math/pow.hh (revision 456) +++ xtd/math/pow.hh (working copy) @@ -102,6 +102,7 @@ const pow_type pow; + } // end of namespace xtd Index: xtd/math/arith.hh --- xtd/math/arith.hh (revision 456) +++ xtd/math/arith.hh (working copy) @@ -39,6 +39,7 @@ xtd_internal_decl_binary_operator( mult, * ); xtd_internal_decl_binary_operator( div, / ); xtd_internal_decl_binary_operator( mod, % ); +// xtd_internal_decl_binary_operator( pow, ^ ); // Cf. xtd/math/pow.hh xtd_internal_decl_unary_operator( uminus, - ); Index: xtd/args.hh Index: xtd/literal.hh --- xtd/literal.hh (revision 456) +++ xtd/literal.hh (working copy) @@ -68,7 +68,7 @@ { const T value; - plain_literal_(const T& value) + plain_literal_(T value) : value(value) {} @@ -106,7 +106,7 @@ { const T value; - meta_literal_(const T& value) + meta_literal_(T value) : value(value) {} @@ -150,7 +150,7 @@ { const T value; - literal_expr_(const T& value) : + literal_expr_(T value) : value(value) {} @@ -165,7 +165,7 @@ // FIXME: doc template <typename T> - literal_expr_<T> lit(const T& value) + literal_expr_<T> lit(T value) { literal_expr_<T> tmp(value); return tmp; Index: xtd/optraits.hh --- xtd/optraits.hh (revision 456) +++ xtd/optraits.hh (working copy) @@ -28,141 +28,210 @@ #ifndef EXTENDED_OPTRAITS_HH # define EXTENDED_OPTRAITS_HH -# include <mlc/flags.hh> +# include <xtd/traits.hh> +# include <xtd/builtin/traits.hh> -// logic +namespace xtd +{ -# define xtd_land(L, R) typename xtd::land_trait_<L, R>::ret -# define xtd_lor(L, R) typename xtd::lor_trait_<L, R>::ret -# define xtd_lxor(L, R) typename xtd::lxor_trait_<L, R>::ret -# define xtd_lnot(T) typename xtd::lnot_trait_<T>::ret + /// \{ + /// Tags to designate operators. + namespace abstract + { + struct oper + {}; -// cmp + struct op_tag + {}; -# define xtd_eq(L, R) typename xtd::eq_trait_<L, R>::ret -# define xtd_neq(L, R) typename xtd::neq_trait_<L, R>::ret -# define xtd_less(L, R) typename xtd::less_trait_<L, R>::ret -# define xtd_leq(L, R) typename xtd::leq_trait_<L, R>::ret -# define xtd_greater(L, R) typename xtd::greater_trait_<L, R>::ret -# define xtd_geq(L, R) typename xtd::geq_trait_<L, R>::ret + } // end of namespace xtd::abstract -// arith -# define xtd_plus(L, R) typename xtd::plus_trait_<L, R>::ret -# define xtd_minus(L, R) typename xtd::minus_trait_<L, R>::ret -# define xtd_mult(L, R) typename xtd::mult_trait_<L, R>::ret -# define xtd_div(L, R) typename xtd::div_trait_<L, R>::ret -# define xtd_mod(L, R) typename xtd::mod_trait_<L, R>::ret + template <typename opname> + struct op_ -# define xtd_uminus(T) typename xtd::uminus_trait_<T>::ret + : public abstract::oper, + private mlc::assert_< mlc_is_a(opname, abstract::op_tag), + xtd::ERROR::FIXME > + { + }; -// FIXME: xtd_plus(L, R) should be xtd::INTERNAL::plus_trait_< L, R >::ret -// FIXME: which checks that the trait *is* defined + // logic + struct land : public abstract::op_tag {}; + struct lor : public abstract::op_tag {}; + struct lxor : public abstract::op_tag {}; + struct lnot : public abstract::op_tag {}; + + typedef op_<land> op_land; + typedef op_<lor > op_lor; + typedef op_<lxor> op_lxor; + typedef op_<lnot> op_lnot; -namespace xtd -{ + // cmp - // logic + struct eq : public abstract::op_tag {}; + struct neq : public abstract::op_tag {}; + struct less : public abstract::op_tag {}; + struct leq : public abstract::op_tag {}; + struct greater : public abstract::op_tag {}; + struct geq : public abstract::op_tag {}; + + typedef op_<eq > op_eq; + typedef op_<neq > op_neq; + typedef op_<less > op_less; + typedef op_<leq > op_leq; + typedef op_<greater> op_greater; + typedef op_<geq > op_geq; - template <typename L, typename R> - struct land_trait_ : public mlc::undefined - { - }; + // arith - template <typename L, typename R> - struct lor_trait_ : public mlc::undefined - { - }; + struct plus : public abstract::op_tag {}; + struct minus : public abstract::op_tag {}; + struct mult : public abstract::op_tag {}; + struct div : public abstract::op_tag {}; + struct mod : public abstract::op_tag {}; + struct uminus : public abstract::op_tag {}; - template <typename L, typename R> - struct lxor_trait_ : public mlc::undefined - { - }; + typedef op_<plus > op_plus; + typedef op_<minus > op_minus; + typedef op_<mult > op_mult; + typedef op_<div > op_div; + typedef op_<mod > op_mod; + typedef op_<uminus> op_uminus; - template <typename T> - struct lnot_trait_ : public mlc::undefined - { - }; + /// \} - // cmp - template <typename L, typename R> - struct eq_trait_ : public mlc::undefined - { - }; - template <typename L, typename R> - struct neq_trait_ : public mlc::undefined - { - }; - template <typename L, typename R> - struct less_trait_ : public mlc::undefined + template < typename name, + typename data > + struct default_case_ < op_<name>, data > { + typedef mlc::undefined ret; }; - template <typename L, typename R> - struct leq_trait_ : public mlc::undefined - { - }; - template <typename L, typename R> - struct greater_trait_ : public mlc::undefined + template <typename name, + typename T> + struct case_ < op_<name>, T, + 1 > : public mlc::where_< mlc_is_builtin(T) >, + + private mlc::assert_< mlc_is_not_a(T, mlc::pair_), + xtd::ERROR::FIXME > { + typedef T ret; // FIXME: fake!!! }; - template <typename L, typename R> - struct geq_trait_ : public mlc::undefined + + template <typename name, + typename L, typename R> + struct case_ < op_<name>, mlc::pair_<L, R>, + 1 > : public mlc::where_< mlc::and_<mlc_is_builtin(L), mlc_is_builtin(R)> > { + struct protected_ { + typedef typename xtd::switch_< internal::UAC, mlc::pair_<L, R> >::ret ret; + }; }; - // arith - template <typename L, typename R> - struct plus_trait_ : public mlc::undefined + namespace internal { - }; - template <typename L, typename R> - struct minus_trait_ : public mlc::undefined - { - }; - template <typename L, typename R> - struct mult_trait_ : public mlc::undefined // FIXME: or "times"? - { - }; + template < typename name, + typename L, typename R > + struct get_trait_ < op_<name>, L, R > - template <typename L, typename R> - struct div_trait_ : public mlc::undefined - { - }; + : private mlc::assert_< mlc::implies_< mlc::is_defined_< xtd::set_trait_<op_<name>, L, R> >, + mlc::ret_found_in_< xtd::set_trait_<op_<name>, L, R> > >, + xtd::ERROR::FIXME >, - template <typename L, typename R> - struct mod_trait_ : public mlc::undefined + private mlc::assert_< mlc::implies_< mlc::is_undefined_< xtd::set_trait_<op_<name>, L, R> >, + mlc::neq_< typename get_case_< op_<name>, mlc::pair_<L, R> >::ret, + mlc::none > >, + xtd::ERROR::FIXME > { + typedef xtd::set_trait_< op_<name>, L, R > user_trait; + typedef mlc_ret(user_trait) user_ret; + + typedef typename get_case_< op_<name>, mlc::pair_<L, R> >::ret case_t; + typedef mlc_ret(case_t) case_ret; + + typedef typename mlc::if_< mlc_is_found(user_ret), user_ret, case_ret >::ret ret; }; - template <typename T> - struct uminus_trait_ : public mlc::undefined + + template < typename name, + typename T > + struct get_trait_ < op_<name>, T > + + : private mlc::assert_< mlc::implies_< mlc::is_defined_< xtd::set_trait_<op_<name>, T> >, + mlc::ret_found_in_< xtd::set_trait_<op_<name>, T> > >, + xtd::ERROR::FIXME > { + typedef xtd::set_trait_< op_<name>, T > user_trait; + typedef mlc_ret(user_trait) user_ret; + + typedef typename get_case_< op_<name>, T >::ret case_t; + typedef mlc_ret(case_t) case_ret; + + typedef typename mlc::if_< mlc_is_found(user_ret), user_ret, case_ret >::ret ret; }; + } // end of namespace xtd::internal + } // end of namespace xtd +// logic + +# define xtd_op_land_trait(L, R) typename xtd::internal::get_trait_<xtd::op_land, L, R>::ret +# define xtd_op_lor_trait(L, R) typename xtd::internal::get_trait_<xtd::op_lor, L, R>::ret +# define xtd_op_lxor_trait(L, R) typename xtd::internal::get_trait_<xtd::op_lxor, L, R>::ret + +# define xtd_op_lnot_trait(T) typename xtd::internal::get_trait_<xtd::op_lnot, T>::ret + + +// cmp + +# define xtd_op_eq_trait(L, R) typename xtd::internal::get_trait_<xtd::op_eq, L, R>::ret +# define xtd_op_neq_trait(L, R) typename xtd::internal::get_trait_<xtd::op_neq, L, R>::ret +# define xtd_op_less_trait(L, R) typename xtd::internal::get_trait_<xtd::op_less, L, R>::ret +# define xtd_op_leq_trait(L, R) typename xtd::internal::get_trait_<xtd::op_leq, L, R>::ret +# define xtd_op_greater_trait(L, R) typename xtd::internal::get_trait_<xtd::op_greater, L, R>::ret +# define xtd_op_geq_trait(L, R) typename xtd::internal::get_trait_<xtd::op_geq, L, R>::ret + + +// arith + +# define xtd_op_plus_trait(L, R) typename xtd::internal::get_trait_<xtd::op_plus, L, R>::ret +# define xtd_op_plus_trait_(L, R) xtd::internal::get_trait_<xtd::op_plus, L, R>::ret +# define xtd_op_minus_trait(L, R) typename xtd::internal::get_trait_<xtd::op_minus, L, R>::ret +# define xtd_op_minus_trait_(L, R) xtd::internal::get_trait_<xtd::op_minus, L, R>::ret +# define xtd_op_mult_trait(L, R) typename xtd::internal::get_trait_<xtd::op_mult, L, R>::ret +# define xtd_op_mult_trait_(L, R) xtd::internal::get_trait_<xtd::op_mult, L, R>::ret +# define xtd_op_div_trait(L, R) typename xtd::internal::get_trait_<xtd::op_div, L, R>::ret +# define xtd_op_div_trait_(L, R) xtd::internal::get_trait_<xtd::op_div, L, R>::ret +# define xtd_op_mod_trait(L, R) typename xtd::internal::get_trait_<xtd::op_mod, L, R>::ret +# define xtd_op_mod_trait_(L, R) xtd::internal::get_trait_<xtd::op_mod, L, R>::ret + +# define xtd_op_uminus_trait(T) typename xtd::internal::get_trait_<xtd::op_uminus, T>::ret + + + #endif // ! EXTENDED_OPTRAITS_HH Index: xtd/abstract/fun.hh --- xtd/abstract/fun.hh (revision 456) +++ xtd/abstract/fun.hh (working copy) @@ -37,10 +37,18 @@ namespace abstract { - /*! \class xtd::abstract::fun_ + /*! \class xtd::abstract::fun_<E> ** - ** Abstract base class for xtd functions. Parameter E is the - ** exact type of the function. + ** Abstract base class for xtd functions. These functions are + ** pure (non imperative); they can be plain, meta, or expr. + ** Parameter E is the exact type of the function. + ** + ** \note 1) This base class is useful to check if a type is the + ** one of an xtd function. 2) As an xtd function is pure, all + ** imperative operators are disabled. + ** + ** \see xtd::abstract::plain_fun_<E>, xtd::abstract::meta_fun_<E>, + ** xtd::abstract::fun_expr_<E> */ template <typename E> @@ -48,12 +56,40 @@ { public: + /// Static dispatch of this towards its exact type. const E& exact() const { return *(const E*)(const void*)(this); } + /// \{ + /// Imperative operators are disabled. + template <typename T> void operator %= (const T&) const; + template <typename T> void operator &= (const T&) const; + template <typename T> void operator *= (const T&) const; + template <typename T> void operator += (const T&) const; + template <typename T> void operator -= (const T&) const; + template <typename T> void operator /= (const T&) const; + template <typename T> void operator ^= (const T&) const; + template <typename T> void operator |= (const T&) const; + template <typename T> void operator = (const T&); + void operator ++ () const; + void operator -- () const; + void operator ++ (int) const; + void operator -- (int) const; + /// \} + + /// \{ + /// Operators "*(x)" and "(x)->" are disabled. + void operator * () const; + void operator -> () const; + /// \} + + /// Conversion operator is disabled. + template <typename T> operator T () const; + protected: + /// Ctor is protected so that this class seems abstract. fun_() {} }; Index: xtd/abstract/plain_fun.hh --- xtd/abstract/plain_fun.hh (revision 456) +++ xtd/abstract/plain_fun.hh (working copy) @@ -31,8 +31,9 @@ # include <xtd/abstract/fun.hh> -// macro - +/** \def xtd_res(F) + ** \brief Macro to get the result type of a plain function of type F. + */ # define xtd_res(F) typename xtd::typedef_::res_type::from_<xtd::fun_traits_<F> >::ret @@ -50,6 +51,12 @@ } // end of namespace xtd::ERROR + /*! \class xtd::fun_traits_<F> + ** + ** Traits class for a plain function of type F. This class should + ** be specialized to provide (thru typedefs) the result type and + ** the argument types. + */ template <typename F> struct fun_traits_ : public mlc::undefined @@ -63,10 +70,27 @@ namespace abstract { - /*! \class xtd::abstract::plain_fun_ + /*! \class xtd::abstract::plain_fun_<E> ** ** Abstract base class for plain functions. Parameter E is the ** exact type of the function. + ** + ** A plain function is a function object knowing the types of its + ** input (and consequently of its output). For instance, + ** xtd::cos_f is an instance of xtd::cos_<float>. This function + ** explicitly takes a float (and thus returns a float); so it is a + ** plain function. + ** + ** A plain function of type F should define the type of its + ** result. For that the traits class associated with this + ** function type, fun_traits_<F>, should be specialized and + ** contain a typedef res_type. The result type is then accessible + ** thru the macro xtd_res(F) where F is the type of the plain + ** function. + ** + ** An xtd plain function is an xtd function. + ** + ** \see xtd::fun_traits_<F>, xtd_res(F) */ template <typename E> @@ -80,6 +104,8 @@ public fun_<E> { + public: + protected: plain_fun_(){ // FIXME: unsigned is parameter so mlc_is_a does not work Index: xtd/abstract/fun_nary_expr.hh --- xtd/abstract/fun_nary_expr.hh (revision 456) +++ xtd/abstract/fun_nary_expr.hh (working copy) @@ -170,11 +170,11 @@ template <typename T> m2expr_< E, literal_expr_<T>, arg_<2> > - bind_1(const T& value) const; + bind_1(T value) const; template <typename T> m2expr_< E, arg_<1>, literal_expr_<T> > - bind_2(const T& value) const; + bind_2(T value) const; protected: fun_nary_expr_() {} @@ -207,15 +207,15 @@ template <typename T> m3expr_< E, literal_expr_<T>, arg_<2>, arg_<3> > - bind_1(const T& value) const; + bind_1(T value) const; template <typename T> m3expr_< E, arg_<1>, literal_expr_<T>, arg_<3> > - bind_2(const T& value) const; + bind_2(T value) const; template <typename T> m3expr_< E, arg_<1>, arg_<2>, literal_expr_<T> > - bind_3(const T& value) const; + bind_3(T value) const; protected: fun_nary_expr_() {} Index: xtd/traits.hh --- xtd/traits.hh (revision 0) +++ xtd/traits.hh (revision 0) @@ -0,0 +1,74 @@ +// 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_TRAITS_HH +# define EXTENDED_TRAITS_HH + +# include <xtd/internal/mlc.hh> + + +namespace xtd +{ + + namespace ERROR + { + struct FIXME; + + } // end of namespace xtd::ERROR + + + + template < typename subject, + typename T1, + typename T2 = mlc::none > + struct set_trait_ : public mlc::undefined + { + }; + + + + namespace internal + { + + template < typename subject, + typename T1, + typename T2 = mlc::none > + struct get_trait_ + + : private mlc::assert_< mlc::is_defined_< xtd::set_trait_<subject, T1, T2> >, + xtd::ERROR::FIXME > + { + }; + + } // end of namespace xtd::internal + + +} // end of namespace xtd + + + +#endif // ! EXTENDED_TRAITS_HH Index: xtd/builtin/traits.hh --- xtd/builtin/traits.hh (revision 456) +++ xtd/builtin/traits.hh (working copy) @@ -28,95 +28,149 @@ #ifndef EXTENDED_BUILTIN_TRAITS_HH # define EXTENDED_BUILTIN_TRAITS_HH -# include <xtd/optraits.hh> +# include <xtd/traits.hh> -// FIXME: this is dummy and incomplete code! +# define xtd_intprom(Type) typename xtd::internal::intprom_<Type>::ret -# define xtd_internal_DUMMY_builtin_arith_traits(OperatorName) \ - \ - template <typename T> \ - struct OperatorName##_trait_ < T, T > \ - { \ - typedef T ret; \ - }; \ - \ - template <> struct OperatorName##_trait_ < float, int > { typedef float ret; }; \ - template <> struct OperatorName##_trait_ < int, float > { typedef float ret; }; \ - template <> struct OperatorName##_trait_ < double, int > { typedef double ret; }; \ - template <> struct OperatorName##_trait_ < int, double > { typedef double ret; }; \ - template <> struct OperatorName##_trait_ < double, float > { typedef double ret; }; \ - template <> struct OperatorName##_trait_ < float, double > { typedef double ret; }; \ - \ - template <> struct OperatorName##_trait_ < long double, int > { typedef long double ret; }; \ - template <> struct OperatorName##_trait_ < int, long double > { typedef long double ret; }; \ - template <> struct OperatorName##_trait_ < long double, float > { typedef long double ret; }; \ - template <> struct OperatorName##_trait_ < float, long double > { typedef long double ret; }; \ - template <> struct OperatorName##_trait_ < long double, double > { typedef long double ret; }; \ - template <> struct OperatorName##_trait_ < double, long double > { typedef long double ret; }; \ - \ - struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n - - -# define xtd_internal_DUMMY_builtin_logic_traits(OperatorName) \ - \ - template <> \ - struct OperatorName##_trait_ < bool, bool > \ - { \ - typedef bool ret; \ - }; \ - \ - struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n - - -# define xtd_internal_DUMMY_builtin_cmp_traits(OperatorName) \ - \ - template <typename T> \ - struct OperatorName##_trait_ < T, T > \ - { \ - typedef bool ret; \ - }; \ - \ - struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n +namespace xtd +{ + + // built-in traits and usual arithmetic conversions + namespace internal + { + // see page 90 of ISO-IEC_14882.2003.pdf -namespace xtd + + struct UAC; // for "usual arithmetic conversions" + + // Integral promotion such as defined in FIXME: std. + + template <class T> + struct intprom_ { + typedef T ret; + }; - // logic + // FIXME: approx? - xtd_internal_DUMMY_builtin_logic_traits( land ); - xtd_internal_DUMMY_builtin_logic_traits( lor ); - xtd_internal_DUMMY_builtin_logic_traits( lxor ); + template <> struct intprom_ <char> { typedef int ret; }; + template <> struct intprom_ <signed char> { typedef int ret; }; + template <> struct intprom_ <unsigned char> { typedef int ret; }; + template <> struct intprom_ <unsigned short int> { typedef int ret; }; - template <> struct lnot_trait_< bool > { typedef bool ret; }; + template <> struct intprom_ <bool> { typedef int ret; }; // FIXME: right? - // cmp + } // end of namespace mlc::internal - xtd_internal_DUMMY_builtin_cmp_traits( eq ); - xtd_internal_DUMMY_builtin_cmp_traits( neq ); - xtd_internal_DUMMY_builtin_cmp_traits( less ); - xtd_internal_DUMMY_builtin_cmp_traits( leq ); - xtd_internal_DUMMY_builtin_cmp_traits( greater ); - xtd_internal_DUMMY_builtin_cmp_traits( geq ); + // 1) Prevent bool to be involved in arithmetics. + template <typename L, typename R> + struct case_ < internal::UAC, mlc::pair_<L, R>, + 1 > + : public mlc::where_< mlc::or_< mlc::eq_<L, bool>, + mlc::eq_<R, bool> > > + { + typedef mlc::undefined ret; + }; - // arith + // 2) If either operand is of type long double, the other shall be + // 2) converted to long double. + template <typename L, typename R> + struct case_ < internal::UAC, mlc::pair_<L, R>, + 2 > + : public mlc::where_< mlc::or_< mlc::eq_<L, long double>, + mlc::eq_<R, long double> > > + { + typedef long double ret; + }; - xtd_internal_DUMMY_builtin_arith_traits( plus ); - xtd_internal_DUMMY_builtin_arith_traits( minus ); - xtd_internal_DUMMY_builtin_arith_traits( mult ); - xtd_internal_DUMMY_builtin_arith_traits( div ); - xtd_internal_DUMMY_builtin_arith_traits( mod ); + // 3) Otherwise, if either operand is double, the other shall be + // 3) converted to double. + template <typename L, typename R> + struct case_ < internal::UAC, mlc::pair_<L, R>, + 3 > + : public mlc::where_< mlc::or_< mlc::eq_<L, double>, + mlc::eq_<R, double> > > + { + typedef double ret; + }; - template <> struct uminus_trait_< int > { typedef int ret; }; - template <> struct uminus_trait_< float > { typedef float ret; }; - template <> struct uminus_trait_< double > { typedef double ret; }; - template <> struct uminus_trait_< long double > { typedef long double ret; }; + // 4) Otherwise, if either operand is float, the other shall be + // 4) converted to float. + template <typename L, typename R> + struct case_ < internal::UAC, mlc::pair_<L, R>, + 4 > + : public mlc::where_< mlc::or_< mlc::eq_<L, float>, + mlc::eq_<R, float> > > + { + typedef float ret; + }; + + // 5) If either operand is unsigned long the other shall be + // 5) converted to unsigned long. + template <typename L, typename R> + struct case_ < internal::UAC, mlc::pair_<L, R>, + 5 > + : public mlc::where_< mlc::or_< mlc::eq_<L, unsigned long>, + mlc::eq_<R, unsigned long> > > + { + typedef unsigned long ret; + }; + + // 6) Otherwise, if one operand is a long int and the other unsigned + // 6) int, then if a long int can represent all the values of an + // 6) unsigned int, the unsigned int shall be converted to a long + // 6) int; otherwise both operands shall be converted to unsigned + // 6) long int. + template <typename L, typename R> + struct case_ < internal::UAC, mlc::pair_<L, R>, + 6 > + : public mlc::where_< mlc::or_< mlc::and_< mlc::eq_<xtd_intprom(L), long int>, + mlc::eq_<xtd_intprom(R), unsigned int> >, + mlc::and_< mlc::eq_<xtd_intprom(R), long int>, + mlc::eq_<xtd_intprom(L), unsigned int> > > > + { + typedef long int ret; // FIXME: approx... + }; + + // 7) Otherwise, if either operand is long, the other shall be + // 7) converted to long. + template <typename L, typename R> + struct case_ < internal::UAC, mlc::pair_<L, R>, + 7 > + : public mlc::where_< mlc::or_< mlc::eq_<xtd_intprom(L), long>, + mlc::eq_<xtd_intprom(R), long> > > + { + typedef long ret; + }; + + // 8) Otherwise, if either operand is unsigned, the other shall be + // 8) converted to unsigned. + template <typename L, typename R> + struct case_ < internal::UAC, mlc::pair_<L, R>, + 8 > + : public mlc::where_< mlc::or_< mlc::eq_<xtd_intprom(L), unsigned>, + mlc::eq_<xtd_intprom(R), unsigned> > > + { + typedef unsigned ret; + }; + + + // 0) Note: otherwise, the only remaining case is that both operands + // 0) are int. + template <typename L, typename R> + struct default_case_ < internal::UAC, mlc::pair_<L, R> > + { + // FIXME: test that: + // mlc::or_<mlc::eq_<xtd_intprom(L), int>, mlc::eq_<xtd_intprom(R), int> > + typedef int ret; + }; } // end of namespace xtd Index: xtd/bind.hh --- xtd/bind.hh (revision 456) +++ xtd/bind.hh (working copy) @@ -46,7 +46,7 @@ template <typename E> template <typename T> m2expr_< E, literal_expr_<T>, arg_<2> > - fun_nary_expr_< 2, E >::bind_1(const T& value) const + fun_nary_expr_< 2, E >::bind_1(T value) const { typedef m2expr_< E, literal_expr_<T>, arg_<2> > ret; ret tmp(this->exact(), lit(value), arg_<2>()); @@ -56,7 +56,7 @@ template <typename E> template <typename T> m2expr_< E, arg_<1>, literal_expr_<T> > - fun_nary_expr_< 2, E >::bind_2(const T& value) const + fun_nary_expr_< 2, E >::bind_2(T value) const { typedef m2expr_< E, arg_<1>, literal_expr_<T> > ret; ret tmp(this->exact(), arg_<1>(), lit(value)); @@ -69,7 +69,7 @@ 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 + fun_nary_expr_< 3, E >::bind_1(T value) const { typedef m3expr_< E, literal_expr_<T>, arg_<2>, arg_<3> > ret; ret tmp(this->exact(), lit(value), arg_<2>(), arg_<3>()); @@ -79,7 +79,7 @@ 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 + fun_nary_expr_< 3, E >::bind_2(T value) const { typedef m3expr_< E, arg_<1>, literal_expr_<T>, arg_<3> > ret; ret tmp(this->exact(), arg_<1>(), lit(value), arg_<3>()); @@ -89,7 +89,7 @@ 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 + fun_nary_expr_< 3, E >::bind_3(T value) const { typedef m3expr_< E, arg_<1>, arg_<2>, literal_expr_<T> > ret; ret tmp(this->exact(), arg_<1>(), arg_<2>(), lit(value)); Index: xtd/internal/opmacros.hh --- xtd/internal/opmacros.hh (revision 456) +++ xtd/internal/opmacros.hh (working copy) @@ -28,6 +28,7 @@ #ifndef EXTENDED_INTERNAL_OPMACROS_HH # define EXTENDED_INTERNAL_OPMACROS_HH +# include <mlc/if.hh> # include <xtd/math/includes.hh> # include <xtd/abstract/fun_expr.hh> @@ -49,7 +50,7 @@ struct fun_traits_< plain_##OperatorName##_<T> > \ { \ typedef T arg_type; \ - typedef xtd_##OperatorName(T) res_type; \ + typedef xtd_op_##OperatorName##_trait(T) res_type; \ }; \ \ \ @@ -71,6 +72,16 @@ \ \ template <typename Expr> \ + struct case_ < op_##OperatorName, Expr, \ + 2 > : public mlc::where_< mlc_is_a(Expr, xtd::abstract::fun_expr_) > \ + { \ + struct protected_ { \ + typedef xtd::m1expr_<xtd::OperatorName##_type, Expr> ret; \ + }; \ + }; \ + \ + \ + template <typename Expr> \ xtd::m1expr_<xtd::OperatorName##_type, Expr> \ operator OperatorSymbol (const xtd::abstract::fun_expr_<Expr>& expr) \ { \ @@ -79,16 +90,41 @@ } \ \ \ - struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n \ + struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n -// FIXME: does not specialize any template arguments -// template <typename Expr> -// struct OperatorName##_trait_ < Expr > -// { -// typedef xtd::m1expr_<xtd::OperatorName##_type, Expr> ret; -// }; + + +# define xtd_internal_decl_binop_w_lit(OperatorName, OperatorSymbol, Builtin) \ + \ + \ + template <typename Rexpr> \ + xtd::m2expr_<xtd::OperatorName##_type, xtd::literal_expr_<Builtin>, Rexpr> \ + operator OperatorSymbol (Builtin value, \ + const xtd::abstract::fun_expr_<Rexpr>& rexpr) \ + { \ + typedef xtd::literal_expr_<Builtin> Lexpr; \ + Lexpr lexpr(value); \ + xtd::m2expr_<xtd::OperatorName##_type, Lexpr, Rexpr> tmp(lexpr, rexpr); \ + return tmp; \ + } \ + \ + \ + template <typename Lexpr> \ + xtd::m2expr_<xtd::OperatorName##_type, Lexpr, xtd::literal_expr_<Builtin> > \ + operator OperatorSymbol (const xtd::abstract::fun_expr_<Lexpr>& lexpr, \ + Builtin value) \ + { \ + typedef xtd::literal_expr_<Builtin> Rexpr; \ + Rexpr rexpr(value); \ + xtd::m2expr_<xtd::OperatorName##_type, Lexpr, Rexpr> tmp(lexpr, rexpr); \ + return tmp; \ + } \ + \ + \ + struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n + @@ -103,7 +139,7 @@ { \ typedef T1 arg1_type; \ typedef T2 arg2_type; \ - typedef xtd_##OperatorName(T1, T2) res_type; \ + typedef xtd_op_##OperatorName##_trait(T1, T2) res_type; \ }; \ \ \ @@ -124,6 +160,25 @@ const OperatorName##_type OperatorName; \ \ \ + template <typename L, typename R> \ + struct case_ < op_##OperatorName, mlc::pair_<L, R>, \ + 2 > : public mlc::where_< mlc::or_< mlc_is_a(L, xtd::abstract::fun_expr_), \ + mlc_is_a(R, xtd::abstract::fun_expr_) > > \ + { \ + struct protected_ { \ + typedef typename mlc::if_< mlc_is_a(L, xtd::abstract::fun_expr_), \ + L, \ + xtd::literal_expr_<L> >::ret Lexpr; \ + \ + typedef typename mlc::if_< mlc_is_a(R, xtd::abstract::fun_expr_), \ + R, \ + xtd::literal_expr_<R> >::ret Rexpr; \ + \ + typedef xtd::m2expr_<xtd::OperatorName##_type, Lexpr, Rexpr> ret; \ + }; \ + }; \ + \ + \ template <typename Lexpr, typename Rexpr> \ xtd::m2expr_<xtd::OperatorName##_type, Lexpr, Rexpr> \ operator OperatorSymbol (const xtd::abstract::fun_expr_<Lexpr>& lexpr, \ @@ -134,16 +189,14 @@ } \ \ \ - struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n \ - + xtd_internal_decl_binop_w_lit(OperatorName, OperatorSymbol, int); \ + xtd_internal_decl_binop_w_lit(OperatorName, OperatorSymbol, float); \ + xtd_internal_decl_binop_w_lit(OperatorName, OperatorSymbol, double); \ + \ + \ + struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n -// FIXME: does not specialize any template arguments -// template <typename Lexpr, typename Rexpr> -// struct OperatorName##_trait_ < Lexpr, Rexpr > -// { -// typedef xtd::m2expr_<xtd::OperatorName##_type, Lexpr, Rexpr> ret; -// }; #endif // ! EXTENDED_INTERNAL_OPMACROS_HH Index: xtd/internal/mlc.hh --- xtd/internal/mlc.hh (revision 456) +++ xtd/internal/mlc.hh (working copy) @@ -37,6 +37,7 @@ # include <mlc/assert.hh> # include <mlc/is_a.hh> # include <mlc/logic.hh> +# include <mlc/implies.hh> # include <mlc/cmp.hh> # include <mlc/if.hh> Index: tests/cfun.cc --- tests/cfun.cc (revision 456) +++ tests/cfun.cc (working copy) @@ -7,12 +7,12 @@ namespace my { - float foo() + static float foo() { return 5.1f; } - float bar(int i) + static float bar(int i) { return float(i) * 3.f; } Index: tests/bi_traits/bool.cc --- tests/bi_traits/bool.cc (revision 0) +++ tests/bi_traits/bool.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + +// check_trait(bool, bool); +// check_trait(bool, char); +// check_trait(bool, float); +// check_trait(bool, double); +// check_trait(bool, ldouble); + check_trait(bool, uchar); + check_trait(bool, schar); + check_trait(bool, ushort); + check_trait(bool, sshort); +// check_trait(bool, uint); + check_trait(bool, sint); +// check_trait(bool, ulong); +// check_trait(bool, slong); + +} Index: tests/bi_traits/char.cc --- tests/bi_traits/char.cc (revision 0) +++ tests/bi_traits/char.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + + check_trait(char, bool); + check_trait(char, char); + check_trait(char, float); + check_trait(char, double); + check_trait(char, ldouble); + check_trait(char, uchar); + check_trait(char, schar); + check_trait(char, ushort); + check_trait(char, sshort); + check_trait(char, uint); + check_trait(char, sint); + check_trait(char, ulong); + check_trait(char, slong); + +} Index: tests/bi_traits/sint.cc --- tests/bi_traits/sint.cc (revision 0) +++ tests/bi_traits/sint.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + + check_trait(sint, bool); + check_trait(sint, char); + check_trait(sint, float); + check_trait(sint, double); + check_trait(sint, ldouble); + check_trait(sint, uchar); + check_trait(sint, schar); + check_trait(sint, ushort); + check_trait(sint, sshort); + check_trait(sint, uint); + check_trait(sint, sint); + check_trait(sint, ulong); + check_trait(sint, slong); + +} Index: tests/bi_traits/uint.cc --- tests/bi_traits/uint.cc (revision 0) +++ tests/bi_traits/uint.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + + check_trait(uint, bool); + check_trait(uint, char); + check_trait(uint, float); + check_trait(uint, double); + check_trait(uint, ldouble); + check_trait(uint, uchar); + check_trait(uint, schar); + check_trait(uint, ushort); + check_trait(uint, sshort); + check_trait(uint, uint); + check_trait(uint, sint); + check_trait(uint, ulong); + check_trait(uint, slong); + +} Index: tests/bi_traits/schar.cc --- tests/bi_traits/schar.cc (revision 0) +++ tests/bi_traits/schar.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + + check_trait(schar, bool); + check_trait(schar, char); + check_trait(schar, float); + check_trait(schar, double); + check_trait(schar, ldouble); + check_trait(schar, uchar); + check_trait(schar, schar); + check_trait(schar, ushort); + check_trait(schar, sshort); + check_trait(schar, uint); + check_trait(schar, sint); + check_trait(schar, ulong); + check_trait(schar, slong); + +} Index: tests/bi_traits/slong.cc --- tests/bi_traits/slong.cc (revision 0) +++ tests/bi_traits/slong.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + + check_trait(slong, bool); + check_trait(slong, char); + check_trait(slong, float); + check_trait(slong, double); + check_trait(slong, ldouble); + check_trait(slong, uchar); + check_trait(slong, schar); + check_trait(slong, ushort); + check_trait(slong, sshort); + check_trait(slong, uint); + check_trait(slong, sint); + check_trait(slong, ulong); + check_trait(slong, slong); + +} Index: tests/bi_traits/uchar.cc --- tests/bi_traits/uchar.cc (revision 0) +++ tests/bi_traits/uchar.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + + check_trait(uchar, bool); + check_trait(uchar, char); + check_trait(uchar, float); + check_trait(uchar, double); + check_trait(uchar, ldouble); + check_trait(uchar, uchar); + check_trait(uchar, schar); + check_trait(uchar, ushort); + check_trait(uchar, sshort); + check_trait(uchar, uint); + check_trait(uchar, sint); + check_trait(uchar, ulong); + check_trait(uchar, slong); + +} Index: tests/bi_traits/sshort.cc --- tests/bi_traits/sshort.cc (revision 0) +++ tests/bi_traits/sshort.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + + check_trait(sshort, bool); + check_trait(sshort, char); + check_trait(sshort, float); + check_trait(sshort, double); + check_trait(sshort, ldouble); + check_trait(sshort, uchar); + check_trait(sshort, schar); + check_trait(sshort, ushort); + check_trait(sshort, sshort); + check_trait(sshort, uint); + check_trait(sshort, sint); + check_trait(sshort, ulong); + check_trait(sshort, slong); + +} Index: tests/bi_traits/ulong.cc --- tests/bi_traits/ulong.cc (revision 0) +++ tests/bi_traits/ulong.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + + check_trait(ulong, bool); + check_trait(ulong, char); + check_trait(ulong, float); + check_trait(ulong, double); + check_trait(ulong, ldouble); + check_trait(ulong, uchar); + check_trait(ulong, schar); + check_trait(ulong, ushort); + check_trait(ulong, sshort); + check_trait(ulong, uint); + check_trait(ulong, sint); + check_trait(ulong, ulong); + check_trait(ulong, slong); + +} Index: tests/bi_traits/ushort.cc --- tests/bi_traits/ushort.cc (revision 0) +++ tests/bi_traits/ushort.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + + check_trait(ushort, bool); + check_trait(ushort, char); + check_trait(ushort, float); + check_trait(ushort, double); + check_trait(ushort, ldouble); + check_trait(ushort, uchar); + check_trait(ushort, schar); + check_trait(ushort, ushort); + check_trait(ushort, sshort); + check_trait(ushort, uint); + check_trait(ushort, sint); + check_trait(ushort, ulong); + check_trait(ushort, slong); + +} Index: tests/bi_traits/float.cc --- tests/bi_traits/float.cc (revision 0) +++ tests/bi_traits/float.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + +// check_trait(float, bool); + check_trait(float, char); + check_trait(float, float); + check_trait(float, double); + check_trait(float, ldouble); + check_trait(float, uchar); + check_trait(float, schar); + check_trait(float, ushort); + check_trait(float, sshort); + check_trait(float, uint); + check_trait(float, sint); + check_trait(float, ulong); + check_trait(float, slong); + +} Index: tests/bi_traits/ldouble.cc --- tests/bi_traits/ldouble.cc (revision 0) +++ tests/bi_traits/ldouble.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + +// check_trait(ldouble, bool); + check_trait(ldouble, char); + check_trait(ldouble, float); + check_trait(ldouble, double); + check_trait(ldouble, ldouble); + check_trait(ldouble, uchar); + check_trait(ldouble, schar); + check_trait(ldouble, ushort); + check_trait(ldouble, sshort); + check_trait(ldouble, uint); + check_trait(ldouble, sint); + check_trait(ldouble, ulong); + check_trait(ldouble, slong); + +} Index: tests/bi_traits/double.cc --- tests/bi_traits/double.cc (revision 0) +++ tests/bi_traits/double.cc (revision 0) @@ -0,0 +1,48 @@ +#include <iostream> +#include <typeinfo> + +#include <mlc/assert.hh> +#include <mlc/cmp.hh> + +#include <xtd/optraits.hh> + + +# define check_op_trait(OpName, OpSymb, T1, T2) \ +mlc::assert_< mlc::eq_< typeof(T1() OpSymb T2()), xtd_op_##OpName##_trait_(T1, T2) > >::check() + +# define check_trait(T1, T2) \ +check_op_trait(plus, +, T1, T2); \ +check_op_trait(minus, -, T1, T2); \ +check_op_trait(mult, *, T1, T2) + +// check_op_trait(mod, %, T1, T2); + + + +int main() +{ + typedef long double ldouble; + typedef unsigned char uchar; + typedef signed char schar; + typedef unsigned short ushort; + typedef signed short sshort; + typedef unsigned int uint; + typedef signed int sint; + typedef unsigned long ulong; + typedef signed long slong; + +// check_trait(double, bool); + check_trait(double, char); + check_trait(double, float); + check_trait(double, double); + check_trait(double, ldouble); + check_trait(double, uchar); + check_trait(double, schar); + check_trait(double, ushort); + check_trait(double, sshort); + check_trait(double, uint); + check_trait(double, sint); + check_trait(double, ulong); + check_trait(double, slong); + +} Index: tests/Makefile.am --- tests/Makefile.am (revision 456) +++ tests/Makefile.am (working copy) @@ -8,20 +8,24 @@ # when oln.m4 is available in the distribution. check_PROGRAMS = \ - id \ + abs \ bind \ cast \ cfun \ cos \ + id \ lit \ - math + math \ + optraits -id_SOURCES = id.cc +abs_SOURCES = abs.cc bind_SOURCES = bind.cc cast_SOURCES = cast.cc cfun_SOURCES = cfun.cc cos_SOURCES = cos.cc +id_SOURCES = id.cc lit_SOURCES = lit.cc math_SOURCES = math.cc +optraits_SOURCES = optraits.cc TESTS = $(check_PROGRAMS) Index: tests/abs.cc --- tests/abs.cc (revision 0) +++ tests/abs.cc (revision 0) @@ -0,0 +1,13 @@ +#include <iostream> +#include <xtd/math/abs.hh> + +int main() +{ + long l = -3; + long ll = xtd::abs(l); + std::cout << ll << std::endl; + + long i = -3; + long ii = xtd::abs(i); + std::cout << ii << std::endl; +} Index: tests/optraits.cc --- tests/optraits.cc (revision 0) +++ tests/optraits.cc (revision 0) @@ -0,0 +1,33 @@ +#include <iostream> +#include <xtd/optraits.hh> +#include <xtd/math.hh> + + +template <typename T> +static void foo() +{ + xtd_op_plus_trait(int, char) tmp; +} + + +template <typename E1, typename E2> +static +void test_plus(const xtd::abstract::fun_expr_<E1>& expr1, + const xtd::abstract::fun_expr_<E2>& expr2) +{ + const xtd_op_plus_trait(E1, E2)& tmp = expr1 + expr2; + std::cout << tmp(1.) << std::endl; +} + + +int main() +{ + using xtd::cos; + using xtd::sin; + using xtd::_1; + + typeof(1+2u) tmp; +// 2 * cos(_1); + + test_plus(2 * cos(_1), sin(_1)); +}