improve type promotion across arithmetic ops
This commit is contained in:
parent
a707d5cd65
commit
85c3f5dbc1
1 changed files with 121 additions and 27 deletions
|
@ -477,12 +477,46 @@ template <typename V>
|
|||
struct sub
|
||||
{
|
||||
using value_type = V;
|
||||
template <typename T1, typename T2>
|
||||
value_type operator() (T1 const& lhs, T2 const&) const
|
||||
|
||||
value_type operator() (value_null const& lhs ,
|
||||
value_null const& rhs) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
value_type operator() (value_null, value_unicode_string const& rhs) const
|
||||
{
|
||||
return rhs;
|
||||
}
|
||||
value_type operator() (value_unicode_string const& lhs, value_null) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename R>
|
||||
value_type operator() (value_unicode_string const& lhs, R const&) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename L>
|
||||
value_type operator() (L const&, value_unicode_string const& rhs) const
|
||||
{
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template <typename L>
|
||||
value_type operator() (L const& lhs, value_null const&) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename R>
|
||||
value_type operator() (value_null const&, R const& rhs) const
|
||||
{
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
value_type operator() (T lhs, T rhs) const
|
||||
{
|
||||
|
@ -495,15 +529,12 @@ struct sub
|
|||
return value_type();
|
||||
}
|
||||
|
||||
value_type operator() (value_double lhs, value_integer rhs) const
|
||||
template <typename T1, typename T2>
|
||||
value_type operator() (T1 const& lhs, T2 const& rhs) const
|
||||
{
|
||||
return lhs - rhs;
|
||||
return typename std::common_type<T1,T2>::type{ lhs - rhs };
|
||||
}
|
||||
|
||||
value_type operator() (value_integer lhs, value_double rhs) const
|
||||
{
|
||||
return lhs - rhs;
|
||||
}
|
||||
|
||||
value_type operator() (value_bool lhs, value_bool rhs) const
|
||||
{
|
||||
|
@ -515,11 +546,47 @@ template <typename V>
|
|||
struct mult
|
||||
{
|
||||
using value_type = V;
|
||||
template <typename T1, typename T2>
|
||||
value_type operator() (T1 const& lhs , T2 const& ) const
|
||||
|
||||
value_type operator() (value_null const& lhs ,
|
||||
value_null const& rhs) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
value_type operator() (value_unicode_string const& lhs, value_null) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
value_type operator() (value_null, value_unicode_string const& rhs) const
|
||||
{
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template <typename L>
|
||||
value_type operator() (L const& lhs, value_null const&) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename R>
|
||||
value_type operator() (value_null const&, R const& rhs) const
|
||||
{
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template <typename R>
|
||||
value_type operator() (value_unicode_string const& lhs, R const&) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename L>
|
||||
value_type operator() (L const&, value_unicode_string const& rhs) const
|
||||
{
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
value_type operator() (T lhs, T rhs) const
|
||||
{
|
||||
|
@ -532,19 +599,15 @@ struct mult
|
|||
return value_type();
|
||||
}
|
||||
|
||||
value_type operator() (value_double lhs, value_integer rhs) const
|
||||
template <typename T1, typename T2>
|
||||
value_type operator() (T1 const& lhs, T2 const& rhs) const
|
||||
{
|
||||
return lhs * rhs;
|
||||
return typename std::common_type<T1,T2>::type{ lhs * rhs };
|
||||
}
|
||||
|
||||
value_type operator() (value_integer lhs, value_double rhs) const
|
||||
value_type operator() (value_bool lhs, value_bool rhs) const
|
||||
{
|
||||
return lhs * rhs;
|
||||
}
|
||||
|
||||
value_type operator() (value_bool, value_bool) const
|
||||
{
|
||||
return value_integer(0);
|
||||
return value_integer(lhs * rhs);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -552,12 +615,35 @@ template <typename V>
|
|||
struct div
|
||||
{
|
||||
using value_type = V;
|
||||
template <typename T1, typename T2>
|
||||
value_type operator() (T1 const& lhs, T2 const&) const
|
||||
|
||||
value_type operator() (value_null const& lhs ,
|
||||
value_null const& rhs) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
value_type operator() (value_unicode_string const& lhs, value_null) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
value_type operator() (value_null, value_unicode_string const& rhs) const
|
||||
{
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template <typename L>
|
||||
value_type operator() (L const& lhs, value_null const&) const
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename R>
|
||||
value_type operator() (value_null const&, R const& rhs) const
|
||||
{
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
value_type operator() (T lhs, T rhs) const
|
||||
{
|
||||
|
@ -576,16 +662,23 @@ struct div
|
|||
return value_type();
|
||||
}
|
||||
|
||||
value_type operator() (value_double lhs, value_integer rhs) const
|
||||
template <typename R>
|
||||
value_type operator() (value_unicode_string const& lhs, R const&) const
|
||||
{
|
||||
if (rhs == 0) return value_type();
|
||||
return lhs / rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
value_type operator() (value_integer lhs, value_double rhs) const
|
||||
template <typename L>
|
||||
value_type operator() (L const&, value_unicode_string const& rhs) const
|
||||
{
|
||||
return rhs;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
value_type operator() (T1 const& lhs, T2 const& rhs) const
|
||||
{
|
||||
if (rhs == 0) return value_type();
|
||||
return lhs / rhs;
|
||||
return typename std::common_type<T1,T2>::type{ lhs / rhs };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -593,10 +686,11 @@ template <typename V>
|
|||
struct mod
|
||||
{
|
||||
using value_type = V;
|
||||
|
||||
template <typename T1, typename T2>
|
||||
value_type operator() (T1 const& lhs, T2 const&) const
|
||||
{
|
||||
return lhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
Loading…
Reference in a new issue