https://svn.lrde.epita.fr/svn/oln/trunk/extended
Index: ChangeLog
from Thierry Geraud <theo(a)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));
+}