Build smarter operators for POD types

This commit is contained in:
Jason Turner
2009-06-09 03:12:59 +00:00
parent 3483b14c2b
commit 88708aaf7b
3 changed files with 306 additions and 31 deletions

View File

@@ -10,18 +10,35 @@ Ret add(P1 p1, P2 p2)
return p1 + p2; return p1 + p2;
} }
Boxed_Value pod_add(Boxed_POD_Value l, Boxed_POD_Value r)
{
return l + r;
}
template<typename Ret, typename P1, typename P2> template<typename Ret, typename P1, typename P2>
Ret subtract(P1 p1, P2 p2) Ret subtract(P1 p1, P2 p2)
{ {
return p1 - p2; return p1 - p2;
} }
Boxed_Value pod_subtract(Boxed_POD_Value l, Boxed_POD_Value r)
{
return l - r;
}
template<typename Ret, typename P1, typename P2> template<typename Ret, typename P1, typename P2>
Ret divide(P1 p1, P2 p2) Ret divide(P1 p1, P2 p2)
{ {
return p1 / p2; return p1 / p2;
} }
Boxed_Value pod_divide(Boxed_POD_Value l, Boxed_POD_Value r)
{
return l / r;
}
template<typename Ret, typename P1, typename P2> template<typename Ret, typename P1, typename P2>
Ret multiply(P1 p1, P2 p2) Ret multiply(P1 p1, P2 p2)
@@ -29,6 +46,12 @@ Ret multiply(P1 p1, P2 p2)
return p1 * p2; return p1 * p2;
} }
Boxed_Value pod_multiply(Boxed_POD_Value l, Boxed_POD_Value r)
{
return l * r;
}
template<typename P1, typename P2> template<typename P1, typename P2>
bool bool_and(P1 p1, P2 p2) bool bool_and(P1 p1, P2 p2)
{ {
@@ -47,66 +70,155 @@ P1 &assign(P1 &p1, const P2 &p2)
return (p1 = p2); return (p1 = p2);
} }
template<typename P1>
P1 &assign_pod(P1 &p1, Boxed_POD_Value v)
{
if (v.m_isfloat)
{
return (p1 = v.d);
} else {
return (p1 = v.i);
}
}
template<typename P1, typename P2> template<typename P1, typename P2>
bool equals(P1 p1, P2 p2) bool equals(P1 p1, P2 p2)
{ {
return p1 == p2; return p1 == p2;
} }
bool pod_equals(Boxed_POD_Value l, Boxed_POD_Value r)
{
return l == r;
}
template<typename P1, typename P2> template<typename P1, typename P2>
bool not_equals(P1 p1, P2 p2) bool not_equals(P1 p1, P2 p2)
{ {
return p1 != p2; return p1 != p2;
} }
bool pod_not_equals(Boxed_POD_Value l, Boxed_POD_Value r)
{
return l != r;
}
template<typename P1, typename P2> template<typename P1, typename P2>
bool less_than(P1 p1, P2 p2) bool less_than(P1 p1, P2 p2)
{ {
return p1 < p2; return p1 < p2;
} }
bool pod_less_than(Boxed_POD_Value l, Boxed_POD_Value r)
{
return l < r;
}
template<typename P1, typename P2> template<typename P1, typename P2>
bool greater_than(P1 p1, P2 p2) bool greater_than(P1 p1, P2 p2)
{ {
return p1 > p2; return p1 > p2;
} }
bool pod_greater_than(Boxed_POD_Value l, Boxed_POD_Value r)
{
return l > r;
}
template<typename P1, typename P2> template<typename P1, typename P2>
bool less_than_equals(P1 p1, P2 p2) bool less_than_equals(P1 p1, P2 p2)
{ {
return p1 <= p2; return p1 <= p2;
} }
bool pod_less_than_equals(Boxed_POD_Value l, Boxed_POD_Value r)
{
return l <= r;
}
template<typename P1, typename P2> template<typename P1, typename P2>
bool greater_than_equals(P1 p1, P2 p2) bool greater_than_equals(P1 p1, P2 p2)
{ {
return p1 >= p2; return p1 >= p2;
} }
bool pod_greater_than_equals(Boxed_POD_Value l, Boxed_POD_Value r)
{
return l >= r;
}
template<typename P1, typename P2> template<typename P1, typename P2>
P1 &timesequal(P1 &p1, const P2 &p2) P1 &timesequal(P1 &p1, const P2 &p2)
{ {
return (p1 *= p2); return (p1 *= p2);
} }
template<typename P1>
P1 &timesequal_pod(P1 &p1, Boxed_POD_Value r)
{
if (r.m_isfloat)
{
return (p1 *= r.d);
} else {
return (p1 *= r.i);
}
}
template<typename P1, typename P2> template<typename P1, typename P2>
P1 &dividesequal(P1 &p1, const P2 &p2) P1 &dividesequal(P1 &p1, const P2 &p2)
{ {
return (p1 /= p2); return (p1 /= p2);
} }
template<typename P1>
P1 &dividesequal_pod(P1 &p1, Boxed_POD_Value r)
{
if (r.m_isfloat)
{
return (p1 /= r.d);
} else {
return (p1 /= r.i);
}
}
template<typename P1, typename P2> template<typename P1, typename P2>
P1 &addsequal(P1 &p1, const P2 &p2) P1 &addsequal(P1 &p1, const P2 &p2)
{ {
return (p1 += p2); return (p1 += p2);
} }
template<typename P1>
P1 &addsequal_pod(P1 &p1, Boxed_POD_Value r)
{
if (r.m_isfloat)
{
return (p1 += r.d);
} else {
return (p1 += r.i);
}
}
template<typename P1, typename P2> template<typename P1, typename P2>
P1 &subtractsequal(P1 &p1, const P2 &p2) P1 &subtractsequal(P1 &p1, const P2 &p2)
{ {
return (p1 -= p2); return (p1 -= p2);
} }
template<typename P1>
P1 &subtractsequal_pod(P1 &p1, Boxed_POD_Value r)
{
if (r.m_isfloat)
{
return (p1 -= r.d);
} else {
return (p1 -= r.i);
}
}
template<typename P1> template<typename P1>
P1 &prefixincrement(P1 &p1) P1 &prefixincrement(P1 &p1)
{ {
@@ -169,6 +281,14 @@ void add_oper_assign(BoxedCPP_System &s)
register_function(s, &assign<T,T>, "="); register_function(s, &assign<T,T>, "=");
} }
template<typename T>
void add_oper_assign_pod(BoxedCPP_System &s)
{
register_function(s, &assign_pod<T>, "=");
}
template<typename T> template<typename T>
void add_oper_less_than(BoxedCPP_System &s) void add_oper_less_than(BoxedCPP_System &s)
{ {
@@ -205,6 +325,24 @@ void add_opers_comparison_overload(BoxedCPP_System &s)
register_function(s, &greater_than_equals<const T&, const R&>, ">="); register_function(s, &greater_than_equals<const T&, const R&>, ">=");
} }
void add_opers_comparison_pod(BoxedCPP_System &s)
{
register_function(s, &pod_equals, "==");
register_function(s, &pod_not_equals, "!=");
register_function(s, &pod_less_than, "<");
register_function(s, &pod_greater_than, ">");
register_function(s, &pod_less_than_equals, "<=");
register_function(s, &pod_greater_than_equals, ">=");
}
void add_opers_arithmetic_pod(BoxedCPP_System &s)
{
register_function(s, &pod_add, "+");
register_function(s, &pod_subtract, "-");
register_function(s, &pod_divide, "/");
register_function(s, &pod_multiply, "*");
}
template<typename T> template<typename T>
void add_opers_comparison(BoxedCPP_System &s) void add_opers_comparison(BoxedCPP_System &s)
{ {
@@ -226,11 +364,21 @@ void add_opers_arithmetic_overload(BoxedCPP_System &s)
register_function(s, &prefixdecrement<T>, "--"); register_function(s, &prefixdecrement<T>, "--");
} }
template<typename T>
void add_opers_arithmetic_modify_pod(BoxedCPP_System &s)
{
register_function(s, &timesequal_pod<T>, "*=");
register_function(s, &dividesequal_pod<T>, "/=");
register_function(s, &subtractsequal_pod<T>, "-=");
register_function(s, &addsequal_pod<T>, "+=");
}
template<typename T> template<typename T>
void add_basic_constructors(BoxedCPP_System &s, const std::string &type) void add_basic_constructors(BoxedCPP_System &s, const std::string &type)
{ {
s.register_function(build_constructor<T>(), type); s.register_function(build_constructor<T>(), type);
s.register_function(build_constructor<T, const T &>(), type); s.register_function(build_constructor<T, const T &>(), type);
s.register_function(build_constructor<T, const T &>(), "clone");
} }
template<typename T, typename U> template<typename T, typename U>
@@ -243,6 +391,7 @@ template<typename T>
void add_opers_arithmetic(BoxedCPP_System &s) void add_opers_arithmetic(BoxedCPP_System &s)
{ {
add_opers_arithmetic_overload<T, T, T>(s); add_opers_arithmetic_overload<T, T, T>(s);
} }
//Built in to_string operator //Built in to_string operator
@@ -262,25 +411,16 @@ std::string to_string(bool b)
} }
} }
template<typename T, typename P1, typename P2, typename P3> template<typename T>
void bootstrap_pod_type(BoxedCPP_System &s, const std::string &name) void bootstrap_pod_type(BoxedCPP_System &s, const std::string &name)
{ {
s.register_type<T>(name); s.register_type<T>(name);
add_basic_constructors<T>(s, name); add_basic_constructors<T>(s, name);
add_oper_assign<T>(s); add_oper_assign<T>(s);
add_oper_assign_pod<T>(s);
add_opers_arithmetic<T>(s); add_opers_arithmetic<T>(s);
add_opers_comparison<T>(s); add_opers_arithmetic_modify_pod<T>(s);
register_function(s, &to_string<T>, "to_string"); register_function(s, &to_string<T>, "to_string");
add_constructor_overload<T, P1>(s, name);
add_constructor_overload<T, P2>(s, name);
add_constructor_overload<T, P3>(s, name);
/*
add_opers_comparison_overload<T, P1>(s);
add_opers_comparison_overload<T, P2>(s);
add_opers_comparison_overload<T, P3>(s);
*/
} }
void bootstrap(BoxedCPP_System &s) void bootstrap(BoxedCPP_System &s)
@@ -289,30 +429,23 @@ void bootstrap(BoxedCPP_System &s)
s.register_type<std::string>("string"); s.register_type<std::string>("string");
add_basic_constructors<double>(s, "double");
add_basic_constructors<int>(s, "int");
add_basic_constructors<char>(s, "char");
add_basic_constructors<bool>(s, "bool"); add_basic_constructors<bool>(s, "bool");
add_basic_constructors<std::string>(s, "string"); add_basic_constructors<std::string>(s, "string");
add_oper_assign<std::string>(s); add_oper_assign<std::string>(s);
register_function(s, &to_string<const std::string &>, "to_string"); register_function(s, &to_string<const std::string &>, "to_string");
register_function(s, &to_string<bool>, "to_string");
bootstrap_pod_type<double>(s, "double");
bootstrap_pod_type<int>(s, "int");
bootstrap_pod_type<size_t>(s, "size_t");
bootstrap_pod_type<char>(s, "char");
bootstrap_pod_type<int64_t>(s, "int64_t");
bootstrap_pod_type<double, int, size_t, char>(s, "double");
bootstrap_pod_type<int, double, size_t, char>(s, "int");
bootstrap_pod_type<size_t, int, double, char>(s, "size_t");
bootstrap_pod_type<char, int, double, size_t>(s, "char");
add_opers_arithmetic_overload<double, int, double>(s);
add_opers_arithmetic_overload<double, double, int>(s);
add_opers_arithmetic_overload<double, size_t, double>(s);
add_opers_arithmetic_overload<double, double, size_t>(s);
add_opers_comparison_overload<int, double>(s);
add_opers_comparison_overload<double, int>(s);
add_opers_comparison_pod(s);
add_opers_arithmetic_pod(s);
add_oper_add<std::string>(s); add_oper_add<std::string>(s);

View File

@@ -38,7 +38,7 @@ class Boxed_Value
{ {
} }
const Type_Info &get_type_info() const Type_Info &get_type_info() const
{ {
return m_type_info; return m_type_info;
} }
@@ -59,6 +59,7 @@ class Boxed_Value
bool m_is_ref; bool m_is_ref;
}; };
//cast_help specializations //cast_help specializations
template<typename Result> template<typename Result>
struct Cast_Helper struct Cast_Helper
@@ -139,6 +140,147 @@ struct Cast_Helper<Boxed_Value>
} }
}; };
struct Boxed_POD_Value
{
Boxed_POD_Value(const Boxed_Value &v)
: d(0), i(0), m_isfloat(false)
{
const int inp_ = int(v.get_type_info().m_type_info);
const int char_ = int(&typeid(char));
const int bool_ = int(&typeid(bool));
const int double_ = int(&typeid(double));
const int float_ = int(&typeid(float));
const int uint8_t_ = int(&typeid(uint8_t));
const int uint16_t_ = int(&typeid(uint16_t));
const int uint32_t_ = int(&typeid(uint32_t));
// const int uint64_t_ = int(&typeid(uint64_t));
const int int8_t_ = int(&typeid(int8_t));
const int int16_t_ = int(&typeid(int16_t));
const int int32_t_ = int(&typeid(int32_t));
const int int64_t_ = int(&typeid(int64_t));
if (inp_ == double_)
{
d = Cast_Helper<double>()(v);
m_isfloat = true;
} else if (inp_ == float_) {
d = Cast_Helper<float>()(v);
m_isfloat = true;
} else if (inp_ == bool_ ) {
i = Cast_Helper<bool>()(v);
} else if (inp_ == char_) {
i = Cast_Helper<char>()(v);
} else if (inp_ == int8_t_) {
i = Cast_Helper<int8_t>()(v);
} else if (inp_ == int16_t_) {
i = Cast_Helper<int16_t>()(v);
} else if (inp_ == int32_t_) {
i = Cast_Helper<int32_t>()(v);
} else if (inp_ == int64_t_) {
i = Cast_Helper<int64_t>()(v);
} else if (inp_ == uint8_t_) {
i = Cast_Helper<uint8_t>()(v);
} else if (inp_ == uint16_t_) {
i = Cast_Helper<uint16_t>()(v);
} else if (inp_ == uint32_t_) {
i = Cast_Helper<uint32_t>()(v);
} else {
throw boost::bad_any_cast();
}
}
bool operator==(const Boxed_POD_Value &r) const
{
return ((m_isfloat)?d:i) == ((r.m_isfloat)?r.d:r.i);
}
bool operator<(const Boxed_POD_Value &r) const
{
return ((m_isfloat)?d:i) < ((r.m_isfloat)?r.d:r.i);
}
bool operator>(const Boxed_POD_Value &r) const
{
return ((m_isfloat)?d:i) > ((r.m_isfloat)?r.d:r.i);
}
bool operator>=(const Boxed_POD_Value &r) const
{
return ((m_isfloat)?d:i) >= ((r.m_isfloat)?r.d:r.i);
}
bool operator<=(const Boxed_POD_Value &r) const
{
return ((m_isfloat)?d:i) <= ((r.m_isfloat)?r.d:r.i);
}
bool operator!=(const Boxed_POD_Value &r) const
{
return ((m_isfloat)?d:i) != ((r.m_isfloat)?r.d:r.i);
}
Boxed_Value operator+(const Boxed_POD_Value &r) const
{
if (!m_isfloat && !r.m_isfloat)
{
return Boxed_Value(i + r.i);
}
return Boxed_Value(((m_isfloat)?d:i) + ((r.m_isfloat)?r.d:r.i));
}
Boxed_Value operator*(const Boxed_POD_Value &r) const
{
if (!m_isfloat && !r.m_isfloat)
{
return Boxed_Value(i * r.i);
}
return Boxed_Value(((m_isfloat)?d:i) * ((r.m_isfloat)?r.d:r.i));
}
Boxed_Value operator/(const Boxed_POD_Value &r) const
{
if (!m_isfloat && !r.m_isfloat)
{
return Boxed_Value(i / r.i);
}
return Boxed_Value(((m_isfloat)?d:i) / ((r.m_isfloat)?r.d:r.i));
}
Boxed_Value operator-(const Boxed_POD_Value &r) const
{
if (!m_isfloat && !r.m_isfloat)
{
return Boxed_Value(i - r.i);
}
return Boxed_Value(((m_isfloat)?d:i) - ((r.m_isfloat)?r.d:r.i));
}
double d;
int64_t i;
bool m_isfloat;
};
template<>
struct Cast_Helper<Boxed_POD_Value>
{
Boxed_POD_Value operator()(Boxed_Value ob)
{
return Boxed_POD_Value(ob);
}
};
#endif #endif

View File

@@ -6,7 +6,7 @@ vec.push_back(25.3)
var i = 0 var i = 0
var size = int(vec.size()) var size = vec.size()
print("Vector Size: " + size.to_string()); print("Vector Size: " + size.to_string());