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
|
struct sub
|
||||||
{
|
{
|
||||||
using value_type = V;
|
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;
|
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>
|
template <typename T>
|
||||||
value_type operator() (T lhs, T rhs) const
|
value_type operator() (T lhs, T rhs) const
|
||||||
{
|
{
|
||||||
|
@ -495,15 +529,12 @@ struct sub
|
||||||
return value_type();
|
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
|
value_type operator() (value_bool lhs, value_bool rhs) const
|
||||||
{
|
{
|
||||||
|
@ -515,11 +546,47 @@ template <typename V>
|
||||||
struct mult
|
struct mult
|
||||||
{
|
{
|
||||||
using value_type = V;
|
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;
|
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>
|
template <typename T>
|
||||||
value_type operator() (T lhs, T rhs) const
|
value_type operator() (T lhs, T rhs) const
|
||||||
{
|
{
|
||||||
|
@ -532,19 +599,15 @@ struct mult
|
||||||
return value_type();
|
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;
|
return value_integer(lhs * rhs);
|
||||||
}
|
|
||||||
|
|
||||||
value_type operator() (value_bool, value_bool) const
|
|
||||||
{
|
|
||||||
return value_integer(0);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -552,12 +615,35 @@ template <typename V>
|
||||||
struct div
|
struct div
|
||||||
{
|
{
|
||||||
using value_type = V;
|
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;
|
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>
|
template <typename T>
|
||||||
value_type operator() (T lhs, T rhs) const
|
value_type operator() (T lhs, T rhs) const
|
||||||
{
|
{
|
||||||
|
@ -576,16 +662,23 @@ struct div
|
||||||
return value_type();
|
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;
|
||||||
return lhs / rhs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
if (rhs == 0) return value_type();
|
||||||
return lhs / rhs;
|
return typename std::common_type<T1,T2>::type{ lhs / rhs };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -593,6 +686,7 @@ template <typename V>
|
||||||
struct mod
|
struct mod
|
||||||
{
|
{
|
||||||
using value_type = V;
|
using value_type = V;
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
value_type operator() (T1 const& lhs, T2 const&) const
|
value_type operator() (T1 const& lhs, T2 const&) const
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue